Rebase v Merge in Git

February 3rd, 2009

If 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:


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”


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:

  1. Create new branch B from existing branch A
  2. Add/commit changes on branch B
  3. Rebase updates from branch A
  4. Merge changes from branch B onto branch A

24 responses

  1. Joseph comments:

    I really would like to understand this, but I don’t understand the notation.

  2. long comments:

    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.

  3. Marc comments:

    Does rebase make the comparison between the two branches faster?

  4. Harjit comments:

    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.

  5. Shoo comments:

    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.)

  6. Confluence: Qt Commercial tracks back:

    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……

  7. A comments:

    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!

  8. The Case for Git Rebase : pings back:

    [...] 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 [...]

  9. Jeff Yu@IT » Git merge or rebase? pings back:

    [...] Rebase vs Merge in Git 2. Avoid Merge commit in Git, this one shows very detail about the difference on these two options, [...]

  10. .Net Head » Rebasing can fail with an updated .gitignore file. pings back:

    [...] 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 [...]

  11. tools by Programming - Pearltrees pings back:

    [...] Rebase v Merge in Git [...]

  12. icole comments:


  13. Confluence: Verzekeringssite tracks back:

    Git branching strategy…

    Introduction We follow the branching model Linus Torvaldus proposed and Vincent Driessen outlined in this article: …

  14. Confluence: Development tracks back:


    Rebase on pull The default configuration is to pul…

  15. MickJr comments:

    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….

  16. Daisuke comments:

    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.

  17. Confluence: Verzekeringssite tracks back:

    Git help page…

    Introduction We follow the branching model Linus Torvaldus proposed and Vincent Driessen outlined in this article: …

  18. The Dude comments:

    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.

  19. Tom comments:

    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)

  20. Lars comments:

    Your choice of presentation (A/B and their derivations) was perfectly suitable for the structure of my brain. Thank you for sharing your thoughts!

  21. J comments:

    You made it much simpler .
    Thanks for posting .


  22. Git: Keeping branches up to date | techfortytwo pings back:

    [...] is a very nice article that explains differences between rebase and merge at Rebase vs Merge. Make sure that you read second comment in that article which explains the notation used in the [...]

  23. Confluence: Development tracks back:

    Configuring GIT…

    Tools msysgit – make sure to choose checkout as is…

  24. Craig R Morton comments:

    The notation isn’t the easiest to understand here unfortunately.

Leave a comment