Do the following three sequences of command do the same:
Commands 1:
git fetch origin master
git rebase origin master
Commands 2:
git pull origin master --rebase
Commands 3:
git fetch origin master
git checkout FETCH_HEAD
My understanding is that all three commands do the same, which is:
In your first set of commands, the rebase
probably isn't what you intended; rebase
doesn't take a remote as an argument.
(UPDATE: That said, under some circumstances git
will interpret a remote name like a ref, and it's possible it will even represent what you mean. I wouldn't rely on it myself, but: If there is a symbolic ref refs/remotes/origin/HEAD
- which can be interpreted as the "default branch" of origin
and normally would exist if you created the local by cloning the origin at a time when it had a valid HEAD
reference - then origin
will expand to whatever refs/remotes/origin/HEAD
points to.)
I think you meant
git rebase origin/master master
There are shorthand ways to write that based on the upstream configuration and already having master
checked out, but whatever. I'll go on assuming this is what you meant to do.
In that case your second command is more or less a shorthand for your first set of commands.
The third command, however, is not equivalent. Whereas rebase
creates new commits and moves refs (appearing to "move" an existing set of commits), checkout
does neither of those things. checkout
merely moves the current HEAD
.
To illustrate, let's suppose you have
A -- B <--(master)
^HEAD
and origin has
A -- C <--(master)
So if you fetch
you'll get
A -- B <--(master)
\ ^(HEAD)
C <--(origin/master)
Now if you do a rebase
as
git rebase origin/master master
(or just
git rebase
in a typical configuraiton) you'll end up with
B
/
A -- C <--(origin/master)
\
B' <--(master)
^HEAD
I kept B
in the diagram to illustrate why the commit at master
is marked B'
. The original B
commit does still exist (for now), and B'
is a new and separate commit created in the rebase
. Because B
is "dangling" it could eventually be garbage-collected.
That's also what you could expect if, instead of fetch
, you had started with
git pull --rebase origin master
On the other hand, if you don't do a rebase
and instead, after a fetch
, say
git checkout FETCH_HEAD
you'd get
A -- B <--(master)
\
C <--(origin/master)
^(HEAD)
No new commit, no moved ref; just HEAD
changes (and you're in detached HEAD
state).