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
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!