I'm trying to figure out why rebase requires a three-way merge. For instance, if we have
A1 - A2
\
B1
And I've checked out B1, and I want to perform:
git rebase A2
why does git merge A2, B1 AND A1? Why wouldn't A2 and B1 suffice? I mean, don't A2 and B1 as commit contain the complete current snapshot of the tree?
The reason it is called a 3-way merge is because the Merge Commit is based on 3 different commits. The common ancestor of our branches, in this case commit number C3. This commit contains code before we diverge into different branches.
3-way merges use a dedicated commit to tie together the two histories. The nomenclature comes from the fact that Git uses three commits to generate the merge commit: the two branch tips and their common ancestor.
Merging is a safe option that preserves the entire history of your repository, while rebasing creates a linear history by moving your feature branch onto the tip of main .
To perform a merge, Git needs to find out, what exactly happened in the two branches since the common ancestor (A1
). As you have said correctly, Git stores snapshots of the commits/trees so to get an actual change set, it has to compare A2
to A1
and B1
to A1
and then merge those individual change sets.
The same thing happens in a rebase. To apply the change set of A2
on B1
, we first need to calculate that change set from the differences between A1
and A2
. And then we can apply that to B1
. You can think of a rebase as something similar to an automated generation of patch files. First it generates all those patch files from the old branch and applies them then to the current HEAD.
So, we need all those three commits to actually calculate the differences, as we cannot figure out what happened in a commit just by looking at that commit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With