Git – Why Does Git Pull Perform a Merge Instead of a Rebase by Default?

git

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:

rebased

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.

Best Answer

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.