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 C
on main
) does not appear in the branch we are merging in (e.g. branch feat/d
).
(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 feat/d
.
In this case, it is commit B
2. Temporarily Remove Newer Commits
Git then temporarily removes any commits on feat/d
that occur after the common commit (B
).
(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
.
(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 D'
(main) (feat/d*)
D'
C C
B B
A A
Rewriting History
When our 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
Note: 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.
Leave a Reply