Let’s look at how to resolve two Git branches that have diverged by performing a Git rebase (your other option in this situation is to create a merge commit).
As discussed in Visualizing Git Branching with Blocks, we can’t do a fast-forward merge when the most recent commit on the receiving branch (e.g. commit
main) does not appear in the branch we are merging in (e.g. branch
(main) (feat/d*) C D B B A A
What Happens with Git Rebase
When we are on the
feat/d branch and type
git rebase main, the following steps occur.
1. Find a Common Ancestor
Git finds the most recent commit in
main that also appears in
In this case, it is commit
2. Temporarily Remove Newer Commits
Git then temporarily removes any commits on
feat/d that occur after the common commit (
(main) (feat/d*) D C B B A A
3. Update our Receiving Branch
Git then performs a fast-forward merge, bringing
feat/d up to date with
(main) (feat/d*) D C C B B A A
4. Re-apply Commits
Git then re-applies the temporarily removed commit(s). Because a Git commit is a unique snapshot in time, even though the changes introduced in
D are the same, it is a different commit so we will refer to this new commit as
(main) (feat/d*) D' C C B B A A
git rebase brought our
feat/d branch up to date with
main, it modified the history of our branch.
If someone else has a copy of the
feat/d branch, their copy and our copy have now diverged.
Theirs Mine (feat/d) (feat/d) D' C C B B A A
This is the biggest hazard of using
git rebase. In general, you should only rewrite Git history (e.g. with
git rebase) when the branch whose history you are rewriting is private to you.
Updating Your Remote
If you have a copy of your branch on a remote server (like GitHub), you’ll need to overwrite it.
git push will not overwrite a branch on your remote server (by default
git push will only update the branch, like a fast-forward merge). You can force an overwrite with
git push --force-with-lease
git push --force would also work but you should never use git push –force.
Merge Conflicts During Rebase
Often when you re-apply your temporarily removed commit(s), there is a merge conflict. A merge conflict occurs when you tell Git to apply a commit but Git doesn’t know how to apply your changes because of how the branch has changed.