When should I force push after rebasing?05 Jul 2017
tl;dr: assuming it’s your own branch, immediately.
On the last few projects I have been a part of, I have been the defacto Git problem solver.
On more than one occasion, I was presented with something like the following:
$ git l master * 232e985 (origin/master, origin/HEAD, master) Feature 4 * 94989d0 Feature 3 * 296d0b3 Feature 2 * 4b856cd Feature 1 $ git l feature-5 * 5c31f6d (HEAD -> feature-5) Feature 4 * 420f83b Feature 3 * 724236a (origin/feature-5) Feature 5 * 296d0b3 Feature 2 * 4b856cd Feature 1
In the above, the commits adding features 3 and 4 on each branch are logically
the same, but on the
feature-5 branch they’ve somehow ended up after the
commit adding feature 5.
The team was using feature branches, and the author of feature 5 above was trying to rebase their changes onto master, but somehow ended up inserting their commit between commits on master. At this stage, you’re in a pretty bad place, as you’ve diverged from master.
How did this happen? I’m guessing it was the following series of events:
- Developer branches from master to create feature-5
- Features 3 & 4 are pushed to master
- Feature 5 is committed to the feature-5 branch
- Developer runs
git pull --rebase origin masteror similar
- … some time passes …
- Developer runs
git pull --rebasewithout really thinking about it
After the first few steps above, we have something like the following:
So far, so good. We want to rebase our changes onto master, so that we can test
and push our code. After
git pull --rebase origin master:
Still looking good. At this stage, we could
git push --force origin feature-5
and all would be well in the world.
But what happens if we go for a tea and forget what we were doing (or we use an
overzealous git GUI tool), and we try to rebase onto
What we see above is the result of Git rebasing commits
44e1c44 on top of
origin/feature-5. As the commit ID is computed by
hashing of the contents of a commit and its parent, the same logical commits
from master now exist on our branch with different IDs.
This could have been avoided if we followed this rule of thumb:
If you’re working on your own branch, always push immediately after rebasing.
Some people on the team were seeing a message like the following:
Your branch and 'origin/feature-5' have diverged, and have 3 and 1 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
and assuming that they should
git pull --rebase, which in this case is exactly what you don’t want.