Difference between git pull and git pull --rebase
GitGit PullGit Problem Overview
I started using git sometime back and do not fully understand the intricacies. My basic question here is to find out the difference between a git pull
and git pull --rebase
, since adding the --rebase
option does not seem to do something very different : just does a pull.
Please help me with understanding the difference.
Git Solutions
Solution 1 - Git
git pull
= git fetch
+ git merge
against tracking upstream branch
git pull --rebase
= git fetch
+ git rebase
against tracking upstream branch
If you want to know how git merge
and git rebase
differ, read this.
Solution 2 - Git
> Sometimes we have an upstream that rebased/rewound a branch we're depending on. This can be a big problem -- causing messy conflicts for us if we're downstream.
>
> The magic is git pull --rebase
>
> A normal git pull is, loosely speaking, something like this (we'll use a remote called origin and a branch called foo in all these examples):
>
> # assume current checked out branch is "foo"
> git fetch origin
> git merge origin/foo
>
> At first glance, you might think that a git pull --rebase does just this:
>
> git fetch origin
> git rebase origin/foo
>
> But that will not help if the upstream rebase involved any "squashing" (meaning that the patch-ids of the commits changed, not just their order).
>
> Which means git pull --rebase has to do a little bit more than that. Here's an explanation of what it does and how.
>
> Let's say your starting point is this:
>
> a---b---c---d---e (origin/foo) (also your local "foo")
> Time passes, and you have made some commits on top of your own "foo":
>
> a---b---c---d---e---p---q---r (foo)
>
> Meanwhile, in a fit of anti-social rage, the upstream maintainer has not only rebased his "foo", he even used a squash or two. His commit chain now looks like this:
>
> a---b+c---d+e---f (origin/foo)
>
> A git pull at this point would result in chaos. Even a git fetch; git rebase origin/foo would not cut it, because commits "b" and "c" on one side, and commit "b+c" on the other, would conflict. (And similarly with d, e, and d+e).
>
> What git pull --rebase
does, in this case, is:
>
> git fetch origin
> git rebase --onto origin/foo e foo
>
> This gives you:
a---b+c---d+e---f---p'---q'---r' (foo)
> You may still get conflicts, but they will be genuine conflicts (between p/q/r and a/b+c/d+e/f), and not conflicts caused by b/c conflicting with b+c, etc.
Answer taken from (and slightly modified):
http://gitolite.com/git-pull--rebase
Solution 3 - Git
Suppose you have two commits in local branch:
D---E master
/
A---B---C---F origin/master
After "git pull", will be:
D--------E
/ \
A---B---C---F----G master, origin/master
After "git pull --rebase", there will be no merge point G. Note that D and E become different commits:
A---B---C---F---D'---E' master, origin/master
Solution 4 - Git
In the very most simple case of no collisions
- with rebase: rebases your local commits ontop of remote HEAD and does not create a merge/merge commit
- without/normal: merges and creates a merge commit
See also:
man git-pull
> More precisely, git pull runs git fetch with the given parameters and > calls git merge to merge the retrieved branch heads into the current > branch. With --rebase, it runs git rebase instead of git merge.
See also:
https://stackoverflow.com/questions/2472254/when-should-i-use-git-pull-rebase
http://git-scm.com/book/en/Git-Branching-Rebasing
Solution 5 - Git
For this is important to understand the difference between Merge and Rebase.
> Rebases are how changes should pass from the top of hierarchy downwards > and merges are how they flow back upwards.
For details refer - http://www.derekgourlay.com/archives/428