What's the difference between `git fetch` then `git rebase`, and `git pull --rebase`?

Ryan Lundy picture Ryan Lundy · Jun 8, 2011 · Viewed 18.5k times · Source

In reading the git pull page, it gives this stern warning about git pull --rebase:

This is a potentially dangerous mode of operation. It rewrites history, which does not bode well when you published that history already. Do not use this option unless you have read git-rebase(1) carefully.

In the git rebase page, it gives a lot of description but no warning of this sort.

In addition, I've seen some people say that

git fetch
git rebase

is the same as

git pull --rebase

while others say they're slightly different.

What's the truth?

Answer

Adam Spiers picture Adam Spiers · Jul 18, 2012

The truth is that they ARE different. Here's a really helpful web page which explains it beautifully:

http://gitolite.com/git-pull--rebase.html

So git pull --rebase has some significant magic over git fetch; git rebase which most of the time you won't notice, but in cases where the upstream maintainer has naughtily ignored all those stern warnings and decided to rewrite the history of a public branch, it can really help out by consulting your local reflog and doing the local rebase in a more intelligent way.

That said, this is still a rebase, so you are still rewriting history! Therefore all the standard stern warnings still apply. But if you're working on a private (i.e. unpublished) branch, then that's OK.

I'll say a bit more regarding the stern warnings. They are valid, but personally I find most people just a bit too paranoid about rebase, like a git rebase crept into their bedroom in the middle of the night when they were young and ate their sister or something. It really shouldn't be that scary:

  • if it's a private branch, rebase to your heart's content
  • if it's a public branch don't rebase unless you really have to, and if you do, make sure you understand the impact, and make sure anyone who might be impacted is properly informed about what you've done, so they don't get a nasty surprise and waste a load of time figuring out what happened.

It's that simple. And yes, I would go as far as actively encouraging people to regularly git rebase -i on their private branches. Polishing history before pushing to somewhere public/upstream is a good thing, because no one wants to wade through a project's history which is full of commits like 'oops, fixing a mistake I made 3 commits ago'. (OTOH, don't get totally obsessed with rebasing in quest of a flawless history. We're human. We make mistakes. Deal with it.)

One last observation regarding the git pull --rebase magic. If the upstream public branch has been rebased in a sensible way (e.g. squashing / fixing up commits, or dropping commits which shouldn't have been put there) then the magic works in your favour. However if the upstream rebase accidentally dropped commits, then the magic will silently prevent you from putting them back. In this case if you want to put back those dropped commits, you should instead use git fetch; git rebase.