Git Jedi Knights already understand the importance of maintaining a clean commit history. Generally speaking this is done with git commit --amend
and git rebase
. Padawans should take a look at our archive of Evan Coury’s A simple explanation of git-rebase for more information.
If you have pushed your changes to a remote, and subsequently amended or rebased, you will need to replace the old commit(s) with your new one(s). To do this, you will need to use The Force:
git push --force
On the assumption that you are already a Jedi Master, undoubtedly you will have noticed a disturbance in The Force when using Git 2.0. Here’s a typical example, assuming you haven’t set a value in push.default
:
jsmall$ git push -f
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:
git config --global push.default matching
To squelch this message and adopt the new behavior now, use:
git config --global push.default simple
When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.
Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.
See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)
Counting objects: 70, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (70/70), done.
Writing objects: 100% (70/70), 2.09 MiB | 845.00 KiB/s, done.
Total 70 (delta 37), reused 0 (delta 0)
remote:
remote: View pull request for feature/schema-updates => develop:
remote: https://hostname/stash/projects/XXX/repos/my-project/pull-requests/92
remote:
To ssh://git@hostname/~jsmall/my-project.git
+ d1a08d2...379884e feature/schema-updates -> feature/schema-updates (forced update)
jsmall$
You are probably aware that the old default matching
behavior could be a very dangerous if you are in the habit of having many local tracking branches checked out. The new default simple
behavior is much more user-friendly, in my opinion.
In short, the difference is, matching
will push changes on all branches that have a remote tracking branch defined, and simple
will only push changes on the currently checked out branch. In the context of using a force push, if you use matching
, you can potentially get yourself into trouble, when you forget you have changes in other local branches, as they will all be force pushed.
If you take a moment to read what Git 2.0 prints out when you force push without an explicit value set for push.default
, it’s quite clear how you should set this. I highly recommend that you explicitly set it to simple
like this:
git config --global push.default simple
May The Force be with you!