Rebase v Merge in Git
February 3rd, 2009If you haven’t worked with a version control tool that allows for easy branching, you’re probably wondering what the difference is between rebase and merge and why you’d choose one over the other.
From the standpoint of the end result, a merge and a rebase in Git appear to do the same thing:
A + B + A’ (merge) = A + A’ + B (rebase)
Wouldn’t it be simpler to just choose one operation and stick with it?
The answer of course is no. Otherwise you wouldn’t have the option. (If you feel completely contrary, best of luck. And choose merge.)
It really only becomes apparent once your development effort becomes hierarchical, either in terms of application lifecycle (such as dev, test and release versions) or in a team structure. You’re now dealing with multiple branches, each with non-trivial changes that can and will occur independently.
Rebases are how changes should pass from the top of hierarchy downwards and merges are how they flow back upwards.
Let’s take a look in more detail at what is actually taking place in each operation for a parent branch A and a child branch B:
Merge
A + B + A’ + dA’B
where A’ are the changes being merged in and dA’B the resolution of merge conflicts from A’ and the set of commits B on the current branch
The changes introduced by A’ and dA’B are grouped together into one merge commit A” = A’ + dA’B that is added on top of the existing set of commits (A + B) and becomes the head of the current branch:
A + B + A”
Rebase
A + A’ + B + dA’B
The rebase resets the starting point the branch and reapplies the set of commits B. Merge conflicts dA’B are combined with these commits so they become grouped together B’ = B + dA’B:
A + A’ + B’
If you stare at it, you’ll realize that the rebase guarantees that the changes being brought it in from the other branch come in exactly as-is: A + A’. Any conflicts are resolved and contained with the associated commits B’ on the current branch.
Using merge to pull in changes from the higher-level branch mixes those changes with the resolved merge conflicts. This means that the current branch won’t necessarily have the same state as the one it was based on (from the hierarchical structure). And since the resolved conflicts are grouped all together in one merge commit, you’ve also made it harder to cleanly cherry-pick individual changes.
Having development lifecycle tracks and each local developer branch start from known consistent states is critical to reducing and resolving code issues. Where a change occurs (or suddenly becomes missing) and who is responsible become easier to determine. By using the rebase to pull in changes, you have that.
When you’re submitting changes back up the chain, you only want to add your changes on top of the existing commits of the higher-level branch. Merge is clearly the operation for that.
Even if you’re a single developer with only a few branches, it’s worth it to get in the habit of using rebase and merge properly. The basic work pattern will look like:
- Create new branch B from existing branch A
- Add/commit changes on branch B
- Rebase updates from branch A
- Merge changes from branch B onto branch A
February 3rd, 2009 at 10:29 pm
I really would like to understand this, but I don’t understand the notation.
February 4th, 2009 at 6:49 pm
I’ve taken some liberties with the notation.
A is the set of commits (a1, a2, a3…) on branch A.
B is the set of commits (b1, b2, b3…) on branch B that were added after this branch was created based on branch A.
A’ is the set of new commits (a’1, a’2…) on branch A that need to be added to branch B via a merge or rebase.
So before the merge or rebase, the current configuration of the branches are
Branch A: A + A’ (original set of commits and new set of commits) = a1 + a2 + a3 + … + a’1 + a’2 +….
Branch B: A + B (original set of commits from branch A and set of commits on branch B) = a1 + a2 + a3 + … + b1 + b2 + b3 + …
When I talk about the merge from branch A onto branch B, the addition of the sets of commits is
A + B + A’ = a1 + a2 + a3 + … + b1 + b2 + b3 + … + a’1 + a’2 + …
The order is important: You start with the original commits on branch A. The commits on branch B are added on top of those commits. And finally the new commits from branch A are added on top of those.
You can also view “A + B” as the code that you see in the directory that is the end result of the set of commits A and B. Which is why I have the first statement:
A + B + A’ = A + A’ + B
Whether you choose a rebase or a merge, the final code that you see should be the same. However, the order of individual commits that go into are different.
July 2nd, 2009 at 10:26 am
Does rebase make the comparison between the two branches faster?
August 20th, 2009 at 1:47 pm
What rebase really says is, to consider the changes that are about to made to the branch, FIRST get the changes that others have already COMMITED to the branch, and then re-apply changes on top of that, irrespective of when the changes were made. This allows you to get what others before you have already commited, and shows you where your changes cause merge conflicts. Also it makes the merge upwards more meaningful, since you would normally resolve conflicts caused by your changes to previously commited changes, before merging and pushing.
February 15th, 2010 at 5:05 am
And if I may add another difference: rebase will refuse (by default) to work if you have modified files in your worktree, thus attempting to goad you into having a clean up-to-date worktree (or at least stashing the local changes) before you pull the other mods. This is usually a good idea.
(This only regards files that would be touched by the commits you’re about to pull. It doesn’t care about modified files that have nothing to do with those mods.)
September 9th, 2011 at 2:51 am
Everyday git tricks & tips…
Create remote branch: \ git push \u origin git push \u origin newfeature1 Delete remote branch: \ git push origin : git push origin :newfeature1 Remove specific commit: \ git rebase \o……
September 10th, 2011 at 11:16 am
Would you explain where in the suggested workflow is fetch or pull? Also is there a problem to work on the code without creating a separate branch, just rebase regularly or once you are done and commit/push changes?
Thank you!
September 11th, 2011 at 9:05 pm
[...] if roundabout read. The anecdotal conclusions are useful to read, but a more analytical approach like this one resonates more clearly for me. Joel Spolsky makes the case that with any DVCS you should think of [...]
October 17th, 2011 at 5:36 pm
[...] Rebase vs Merge in Git 2. Avoid Merge commit in Git, this one shows very detail about the difference on these two options, [...]
December 6th, 2011 at 9:43 pm
[...] If you are using Git, the preferred way to do this is with the rebase command rather than merge. (Here is a good explanation of the difference between the two and why rebase is usually [...]
December 15th, 2011 at 9:29 am
[...] Rebase v Merge in Git [...]
February 2nd, 2012 at 6:44 am
hi!!!
February 3rd, 2012 at 1:18 am
Git branching strategy…
Introduction We follow the branching model Linus Torvaldus proposed and Vincent Driessen outlined in this article: …
April 17th, 2012 at 10:43 am
git…
Rebase on pull The default configuration is to pul…
May 13th, 2012 at 3:20 pm
I have read a lot of posts about rebase vs merge and linear vs non-linear history but I have to say after reading your post, it makes things a lot clearer which is to use both rebase and merge but at appropriate times
Awesome post mate….
July 21st, 2012 at 10:14 am
Could you clarify this point? I much appreciate it!
When you’re submitting changes back up the chain, you only want to add your changes on top of the existing commits of the higher-level branch. Merge is clearly the operation for that.
August 15th, 2012 at 11:46 pm
Git help page…
Introduction We follow the branching model Linus Torvaldus proposed and Vincent Driessen outlined in this article: …
August 26th, 2012 at 10:23 am
Hey look, this is what I think of your post:
A + B’ + A = AAB’ / B’ – B’ / A * C ≥ 6 ± Z
I’ve taken some liberties with my phrasing, hope you like the critic though.
November 2nd, 2012 at 8:27 pm
It’s a lot easier to apply own your changes on top of something that’s working rather then merging someone elses changes on top of what you’re doing. (re-base versus merge)
January 23rd, 2013 at 7:04 pm
Your choice of presentation (A/B and their derivations) was perfectly suitable for the structure of my brain. Thank you for sharing your thoughts!