Consider the following situation:

  • You have a clone of a git repository
  • You have some local commits (commits that have not yet been pushed anywhere)
  • The remote repository has new commits that you have not yet reconciled

So something like this:

Unmerged commits

If you execute git pull with the default settings, you'll get something like this:

merge commit

This is because git performed a merge.

There's an alternative, though. You can tell pull to do a rebase instead:

git pull --rebase

and you'll get this:


In my opinion, the rebased version has numerous advantages that mostly center around keeping both your code and the history clean, so I'm a little struck by the fact that git does the merge by default. Yes, the hashes of your local commits will get changed, but this seems like a small price to pay for the simpler history you get in return.

By no means am I suggesting that this is somehow a bad or a wrong default, though. I am just having trouble thinking of reasons why the merge might be preferred for the default. Do we have any insight into why it was chosen? Are there benefits that make it more suitable as a default?

The primary motivation for this question is that my company is trying to establish some baseline standards (hopefully, more like guidelines) for how we organize and manage our repositories to make it easier for developers to approach a repository they haven't worked with before. I am interested in making a case that we should usually rebase in this type of situation (and probably for recommending developers set their global config to rebase by default), but if I were opposed to that, I would certainly be asking why rebase isn't the default if it's so great. So I'm wondering if there is something I'm missing.

It has been suggested that this question is a duplicate of Why do so many websites prefer “git rebase” over “git merge”?; however, that question is somewhat the reverse of this one. It discusses the merits of rebase over merge, while this question asks about the benefits of merge over rebase. The answers there reflect this, focusing on problems with merge and benefits of rebase.

  • 6
    Possible duplicate of Why do so many websites prefer "git rebase" over "git merge"? – gbjbaanb Jan 11 '16 at 8:44
  • The other problem is that if you accidentally commit to master, then do a pull which merged, the two masters can be out of sync even though the merge looks normal. This is why my pull alias includes --ff-only. – Ixrec Jan 11 '16 at 10:14
  • 1
    @Ewan SourceTree shouldn't change its graph view of this. It accurately represents the graph. – jpmc26 Jan 11 '16 at 19:56
  • 4
    For dupe voters, please note that the content in the answer I accepted is most definitely not present in the question you're claiming is a duplicate. – jpmc26 Jan 12 '16 at 3:28
  • 1
    The answers touched on this but I'll reiterate that changing hashes in Git is not "a small price". Git revolves around each commit's hash (and other object hashes) and any change to them (especially if it were default behaviour) goes against some the fundamental ideas Git is built upon. Yes, there are scenarios where we mutating hashes is acceptable, but as this as an out-of-the-box default would be madness. – Whymarrh Jan 17 '16 at 22:30

It is hard to know for sure why merge is the default without hearing from the person who made that decision.

Here is a theory...

Git cannot presume it is ok to --rebase every pull. Listen to how that sounds. "Rebase every pull." just sounds wrong if you use pull requests or similar. Would you rebase on a pull request?

In a team that is not just using Git for centralized source control...

  • You may pull from upstream and from downstream. Some people do a lot of pulling from downstream, from contributors, etc.

  • You may work on features in close collaboration with other developers, pulling from them or from a shared topic branch and still occasionally updated from upstream. If you always rebase then you end up changing shared history, not to mention fun conflict cycles.

Git was designed for a large highly distributed team where everyone does not pull and push to a single central repo. So the default makes sense.

  • Developers who do not know when it's ok to rebase will merge by default.
  • Developers can rebase when they want to.
  • Commiters who do a lot of pulls and have a lot of pull get the default that suits them best.

For evidence of intent, here's a link to a well known email from Linus Torvalds with his views on when they should not rebase. Dri-devel git pull email

If you follow the whole thread you can see that one developer is pulling from another developer and Linus is pulling from both of them. He makes his opinion pretty clear. Since he probably decided Git's defaults, this might explain why.

A lot of people now use Git in a centralized way, where everyone in a small team pulls only from an upstream central repo and pushes to that same remote. This scenario avoids some of the situations where a rebase is not good, but usually does not eliminate them.

Suggestion: Don't make a policy of changing the default. Any time you put Git together with a big group of developers some of the developers won't understand Git all that deeply (myself included). They will go to Google, SO, get cookbook advice and then wonder why some things don't work, e.g. why does git checkout --ours <path> get the wrong version of the file? You can always revise your local environment, make aliases, etc. to suit your taste.

  • 5
    +1 for not changing the default - rather than rolling your own git workflow it's probably better to grab one that exists (e.g. any of the ones documented by Atlassian atlassian.com/git/tutorials/comparing-workflows/… ) – Rob Church Jan 11 '16 at 13:17
  • 2
    Thanks for the answer. The info about pulling from downstream was what I was missing. Also, interestingly enough, the link you gave encourages exactly what I would like to achieve: "People can (and probably should) rebase their private trees (their own work)." – jpmc26 Jan 12 '16 at 3:36
  • 2
    @jpmc Great. Indeed. Rebasing private trees can keep a lot of distracting crud out of the shared history. I do it. It's the clarity on when not to do it that's important. – joshp Jan 12 '16 at 4:06
  • "some of the developers won't understand Git all that deeply". Rebase is NOT a super fancy ("deep", etc) feature of Git. Do you really consider this thing that hard to understand? I think that this should be a trigger to call dev incompetent. – Victor Yarema Aug 26 '18 at 8:36
  • There is a caveat to all arguments you have listed, git sometimes when there are tons of merges is losing commits. If you have a large de-centrilzed team working on one branch history becomes pretty useless for developers and sometimes even git does not know what is where. Happened to me 3 times in my career of about 12 years on git. – Drachenfels Apr 22 at 12:42

If you read the git manpage for rebase, it says:

Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone downstream of it is forced to manually fix their history. This section explains how to do the fix from the downstream’s point of view. The real fix, however, would be to avoid rebasing the upstream in the first place.

I think that says it well enough as a reason not to use rebase at all, let alone automatically do it for every pull. Some people consider rebase to be harmful. Perhaps it should never have been put into git at all, as all it appears to do is prettify the history, something that shouldn't be necessary in any SCM whose single essential job is to preserve history.

When you say 'keeping ... the history clean', think you're wrong. It may look nicer, but for a tool that is designed to keep history of revisions, it is much cleaner to keep every commit so you can see what happened. Sanitising the history afterwards is like polishing the patina away, making a rich antique look like a shiny repro :-)

  • 3
    @Ewan IMHO "doesn't work but looks pretty" is something that should be solely reserved for the fashion industry not IT. IMHO git should remove it as it obviously encourages too many people to think style is more important than substance. – gbjbaanb Jan 11 '16 at 16:03
  • 15
    I would dispute your suggestion that keeping the history clean is useless. It's not. A repository history is intended for human consumption, and as such, there's a lot of value in making it readable. In my particular use case, we're even intending that non-developer Project Managers should be able to read the history. A clean history can only help with that, and it can help a new developer who has never seen the code base and has to dive in and fix a bug understand what happened in a particular area of code. – jpmc26 Jan 12 '16 at 4:42
  • 3
    Code exists first and foremost to be executed by a machine (possibly after being compiled). Applying you philosophy above, we would conclude that readability of the code doesn't matter because no amount of readability will solve the difficulty of understanding code. I never suggested that anything should be squashed. I am merely saying that a complex graph that diverges into a lot of crossing paths is difficult to follow, so it's worth investing a little into keeping your history fairly clean. Note also that a linear history is more conducive to leveraging git tools like blame and bisect. – jpmc26 Jan 23 '16 at 21:12
  • 8
    The docs don't say "do not rebase." It says, "don't rebase changes that are upstream of other people." There is a world of difference between those two. Linus himself advises some rebasing for organizing history, as can be seen in the link in the accepted answer. And how would any tool know which commits are irrelevant (especially if tools have difficulty analyzing a non-linear history!), and how would you know which commit you want to diff with (especially without being able to dig through the history!)? You are taking a word of caution about a specific situation to a dogmatic extreme. – jpmc26 Jan 24 '16 at 17:20
  • 4
    You definitely do not want "keep history of revisions" if that includes every commit a developer has ever made. Following that logic we should also record the original version of code every time the backspace key has been hit. Every commit should be a minimal and complete change that still keeps the whole project in stable state. If your original commit is later found to be buggy, it's much better to rebase/edit/amend the commit than to create another. However, see also mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html – Mikko Rantalainen Jul 7 '16 at 9:16

You're correct, assuming you have only one local/changed repository. However, consider there being a second local PC, for example.

Once your local/modified copy is pushed somewhere else rebasing will screw up those copies. Of course, you could force pushing, but that quickly becomes complicated. What happens if one or more of these have another completely new commit?

As you can see, it's very situational, but the base strategy seems (to me) a lot more practical in non-special/collaboration cases.

A second difference: The merge strategy will keep a clear and time consistent structure. After rebases it's very likely that older commits might follow newer changes, making the whole history and its flow harder to understand.

  • 2
    "After rebases it's very likely that older commits might follow newer changes" -- that happens with merges too, though, which is why you (might) need the pretty graph to make sense of it. The time at which a commit was made might be long before the merge that brought it into this branch. – Steve Jessop Jan 12 '16 at 15:33

The big reason is probably that the default behaviour should "just work" in public repos. Rebasing history that other people have already merged is going to cause them trouble. I know you're talking about your private repo, but generally speaking git doesn't know or care what's private or public, so the chosen default is going to be the default for both.

I use git pull --rebase quite a lot in my private repo, but even there it has a potential disadvantage, which is that the history of my HEAD no longer reflects the tree as I actually worked on it.

So for a big example, suppose that I always run tests and ensure they pass before doing a commit. This has less relevance after I do a git pull --rebase, because it is no longer true that the tree at each of my commits has passed the tests. As long as the changes don't interfere in any way, and the code I pull has been tested, then presumably it would pass the tests, but we don't know because I never tried it. If continuous integration is an important part of your workflow, then any kind of rebase in a repo that's being CIed is troubling.

I don't really mind this, but it does bother some people: they'd prefer that their history in git reflects the code they actually worked on (or perhaps by the time they push it, a simplified version of the truth after some use of "fixup").

I don't know whether this issue in particular is the reason that Linus chose to merge rather than rebasing by default. There could be other disadvantages I haven't encountered. But since he's not shy of expressing his opinion in code, I'm pretty sure it comes down to what he thinks is a suitable workflow for people who don't want to think about it too much (and especially those working in a public rather than a private repo). Avoiding parallel lines in the pretty graph, in favour of a clean straight line that doesn't represent the parallel development as it happened, is probably not his top priority even though it is yours :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.