Reputation: 100010
I am trying to understand git pull --rebase
...in order to do so, how is that command different from:
git fetch origin
git reset --soft remotes/origin/foo
git add .
git commit -am "bar"
git merge remotes/origin/foo
is git pull --rebase
the same as the above commands or different? Certainly is less verbose, obviously.
Upvotes: 0
Views: 479
Reputation: 50864
No, they are quite different.
Assuming you have master
checked out with a clean tree, your proposed set of commands will have the effect of pointing master
at a single commit whose parent is the fetched upstream but whose content has the effect of replacing the new upstream tree with a copy of your pre-fetch master
, without merging any of the upstream changes. (In particular, the final git merge remotes/origin/foo
will always say "Already up-to-date." and never make any changes.)
That's because the command:
git reset --soft remotes/origin/foo
sets master
to point to remotes/origin/foo
without changing the current working directory (or index). Then, the command:
git commit -am "bar"
checks in a single commit for the (unchanged) tree from your current master. As far as Git is concerned, you just freshly fetched the upstream, and then methodically changed it to look exactly like your own master
based on an earlier upstream, undoing any changes made since your previous pull, and then checked it in on top of the upstream. Since this commit is now a descendent of upstream, it's already considered merged, and the:
git merge remotes/origin/foo
will have no effect.
In constrast, git pull --rebase
is the equivalent of
git fetch origin
git rebase remotes/origin/foo # or wherever you pull from
This has the effect of replaying the sequence of commits that have been made on master
since you last pulled from upstream on top of the upstream branch and pointing master
at the result.
So, it differs from the above commands in that it adds a sequence of commits to upstream instead of adding a single commit, and it replays the contents of the commits (which means it tries to replay the changes made in those commits) on top of upstream, instead of replacing upstream with the old contents of master
and obliterating upstream changes. In the end, master
is still a descendent of remotes/origin/foo
, so running:
git merge remotes/origin/foo
would still do nothing, but it doesn't have to do anything, because newly fetched upstream changes will have been incorporated into the new master
branch.
Upvotes: 1