What's the difference between 'git merge' and 'git rebase'?

GitMergeGit MergeRebaseGit Rebase

Git Problem Overview


What's the difference between git merge and git rebase?

Git Solutions


Solution 1 - Git

Suppose originally there were 3 commits, A,B,C:

A-B-C

Then developer Dan created commit D, and developer Ed created commit E:

A-B-C-D-E

Obviously, this conflict should be resolved somehow. For this, there are 2 ways:

MERGE:

A-B-C-D-E-M

Both commits D and E are still here, but we create merge commit M that inherits changes from both D and E. However, this creates diamond shape, which many people find very confusing.

REBASE:

A-B-C-D-E-R

We create commit R, which actual file content is identical to that of merge commit M above. But, we get rid of commit E, like it never existed (denoted by dots - vanishing line). Because of this obliteration, E should be local to developer Ed and should have never been pushed to any other repository. Advantage of rebase is that diamond shape is avoided, and history stays nice straight line - most developers love that!

Solution 2 - Git

Personally I don't find the standard diagramming technique very helpful - the arrows always seem to point the wrong way for me. (They generally point towards the "parent" of each commit, which ends up being backwards in time, which is weird).

To explain it in words:

  • When you rebase your branch onto their branch, you tell Git to make it look as though you checked out their branch cleanly, then did all your work starting from there. That makes a clean, conceptually simple package of changes that someone can review. You can repeat this process again when there are new changes on their branch, and you will always end up with a clean set of changes "on the tip" of their branch.
  • When you merge their branch into your branch, you tie the two branch histories together at this point. If you do this again later with more changes, you begin to create an interleaved thread of histories: some of their changes, some of my changes, some of their changes. Some people find this messy or undesirable.

For reasons I don't understand, GUI tools for Git have never made much of an effort to present merge histories more cleanly, abstracting out the individual merges. So if you want a "clean history", you need to use rebase.

I seem to recall having read blog posts from programmers who only use rebase and others that never use rebase.

Example

I'll try explaining this with a just-words example. Let's say other people on your project are working on the user interface, and you're writing documentation. Without rebase, your history might look something like:

Write tutorial
Merge remote-tracking branch 'origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md

That is, merges and UI commits in the middle of your documentation commits.

If you rebased your code onto master instead of merging it, it would look like this:

Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger

All of your commits are at the top (newest), followed by the rest of the master branch.

(Disclaimer: I'm the author of the "10 things I hate about Git" post referred to in another answer)

Solution 3 - Git

While the accepted and most upvoted answer is great, I additionally find it useful trying to explain the difference only by words:

merge

  • “okay, we got two differently developed states of our repository. Let's merge them together. Two parents, one resulting child.”

rebase

  • “Give the changes of the main branch (whatever its name) to my feature branch. Do so by pretending my feature work started later, in fact on the current state of the main branch.”
  • “Rewrite the history of my changes to reflect that.” (need to force-push them, because normally versioning is all about not tampering with given history)
  • “Likely —if the changes I raked in have little to do with my work— history actually won't change much, if I look at my commits diff by diff (you may also think of ‘patches’).“

summary: When possible, rebase is almost always better. Making re-integration into the main branch easier.

Because? ➝ your feature work can be presented as one big ‘patch file’ (aka diff) in respect to the main branch, not having to ‘explain’ multiple parents: At least two, coming from one merge, but likely many more, if there were several merges. Unlike merges, multiple rebases do not add up. (another big plus)

Solution 4 - Git

Git rebase is closer to a merge. The difference in rebase is:

  • the local commits are removed temporally from the branch.
  • run the git pull
  • insert again all your local commits.

So that means that all your local commits are moved to the end, after all the remote commits. If you have a merge conflict, you have to solve it too.

Solution 5 - Git

For easy understand can see my figure.

Rebase will change commit hash, so that if you want to avoid much of conflict, just use rebase when that branch is done/complete as stable.

enter image description here

Solution 6 - Git

What's the difference between merge and rebase?

Reading the official Git manual it states that “rebase reapplies commits on top of another base branch”, whereas “merge joins two or more development histories together”. In other words, the key difference between merge and rebase is that while merge preserves history as it happened, rebase rewrites it.

Let's contextualize these statements with a side-by-side example!

Comparison of merge vs rebase

As illustrated above, the merge operation intertwined the branches together by creating a new single merge commit (C7), causing a diamond shaped non-linear history — essentially preserving history as it happened. By comparing this result with the outcome from the rebase action we see that no merge commit was created, instead the two commits C5 and C6 simply got rewinded and reapplied straight on top of C4, keeping the history linear.

If we scrutinise the two reapplied commits even further, we can see that the hashes have changed, indicating that rebase truly rewrites history.

Worth noting

Whenever you rebase a branch, new commits will always be generated even though the content might still be the same! That said, any former commits will eventually (post garbage collection) be deleted from history if no other pointer (branch/tag) is referencing them.

With great power comes great responsibility

We’ve seen how rebase rewrites history, while merge preserves it. But what does this mean in a broader sense? And what possibilities and potential drawbacks do the two operations come with?

Conflicting changes

Let’s say, for example, you’ve had some nasty conflicts trying to integrate the changes. In the merge scenario, you would have only needed to solve the conflicts once, straight in the C7 commit. With rebase, on the other hand, you could potentially have been forced to solve similar conflicts in each commit (C5 and C6) as they were reapplied.

Published branches

Another potential problem related to rebase occurs when the branch you are rebasing has already been published remotely, and someone else has based their work on it. Then, your rebased branch can cause serious confusion and headaches for all involved parties as Git will tell you that your branch is both ahead and behind at the same time. If this happens, pulling remote changes using the rebase flag (git pull --rebase) generally solves the problem.

Furthermore, whenever you are rebasing an already published branch, regardless if no one else has based their work on it, you’ll still need to force push it to get your updates to the remote server — overwriting the existing remote reference completely.

Loss of data (to your advantage)

Finally, as rebase rewrites history while merge preserves it, it’s possible to actually lose data when rebasing. When new commits are reapplied, the old ones are (eventually, post garbage collection) deleted. This same trait is in fact what makes rebase so powerful — it allows you to tidy up your development history before making it publicly available!

Conclusion

While merge is safe to use from a potential data loss perspective, and can feel more straight forward to use. Here are some pointers that can help you avoid the most common issues related to rebase.

  • Don't rebase a branch that’s been published remotely…
  • …unless you know you are the only one working on it (and feel safe force pushing)
  • Prior to rebasing, create a backup branch from the tip of the branch you’re about to rebase, as it will allow you to easily compare the outcome (once done) and jump back to the pre-rebase state if necessary.

Source: Above excerpt is taken from this full length post on the subject: Differences Between Git Merge and Rebase — and Why You Should Care

Solution 7 - Git

I found one really interesting article on git rebase vs merge, thought of sharing it here

  • If you want to see the history completely same as it happened, you should use merge. Merge preserves history whereas rebase rewrites it.

  • Merging adds a new commit to your history

  • Rebasing is better to streamline a complex history, you are able to change the commit history by interactive rebase.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaniel PeñalbaView Question on Stackoverflow
Solution 1 - GitmvpView Answer on Stackoverflow
Solution 2 - GitSteve BennettView Answer on Stackoverflow
Solution 3 - GitFrank NockeView Answer on Stackoverflow
Solution 4 - GitWillem FrancoView Answer on Stackoverflow
Solution 5 - GitNhan CaoView Answer on Stackoverflow
Solution 6 - GitAlexis Määttä VinklerView Answer on Stackoverflow
Solution 7 - Gitnagendra547View Answer on Stackoverflow