10

Start situation (no unpushed changes, > indicates the current branch):

o C [> master][origin/master]
|
o B
|
o A
|
...

After a git fetch the log structure often looks like

o E [origin/master]
|
o C'
|
o B'
|
o D
|
| o C [>master]
| |
| o B
|/
o A
|
...

Now git rebase origin/master master often produces conflicts. Is git pull --rebase smarter and just uses git reset to make master also point to E if master==origin/master initially?

Mot
  • 28,248
  • 23
  • 84
  • 121

3 Answers3

18

You can pull with rebase instead of merge - that's the way my team works and it works quite well.

From "A few git tips you didn't know about":

Because branch merges in git are recorded with a merge commit, they are supposed to be meaningful—for example, to indicate when a feature has been merged to a release branch. However, during a regular daily workflow where several team members sync a single branch often, the timeline gets polluted with unnecessary micro-merges on regular git pull. Rebasing ensures that the commits are always re-applied so that the history stays linear.

You can configure certain branches to always do this without the --rebase flag:

#make 'git pull' on master always use rebase
$ git config branch.master.rebase true

You can also set up a global option to set the last property for every new tracked branch:

# setup rebase for every tracking branch
$ git config --global branch.autosetuprebase always

mahalie
  • 2,647
  • 20
  • 21
17

git pull --rebase is NOT the same as git fetch; git rebase. Unfortunately the git-pull man page is rather cryptic about the difference:

   --rebase
       Rebase the current branch on top of the upstream branch
       after fetching. If there is a remote-tracking branch
       corresponding to the upstream branch and the upstream branch
       was rebased since last fetched, the rebase uses that
       information to avoid rebasing non-local changes.

It turns out that the difference doesn't involve git reset as the original poster guessed - in fact it involves the reflog (see here if you haven't encountered that term before).

For the complete story around the extra magic in git pull --rebase, see this answer:

https://stackoverflow.com/a/11531502/179332

Community
  • 1
  • 1
Adam Spiers
  • 17,397
  • 5
  • 46
  • 65
7

git pull --rebase is similar to what the following would do:

git fetch
git rebase

So in your case it will leave the repository like this:

o C [> master]
|
o B
|
o E [origin/master]
|
o C'
|
o B'
|
o D
|
o A
|
...

Note that the two commits you have are different from origin where re-created on top of commit E.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
grzuy
  • 4,791
  • 2
  • 20
  • 17
  • It looks like you've mixed `B` with `B'` and `C` with `C'`. Unfortunately, in practice this does not work well if `B` and `C` are already part of `origin/master` (as a result of a previous cherry-pick or rebase). – Mot May 03 '11 at 04:54
  • 8
    `git pull --rebase` is *not* the same as `git fetch; git rebase` - see [my answer below which gives the difference](http://stackoverflow.com/a/11531552/179332). – Adam Spiers Jul 17 '12 at 22:43
  • The last sentence is incomprehensible. – Peter Mortensen Aug 08 '18 at 14:22