Roman
Roman

Reputation: 131268

Do these three sets of git commands do the same?

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:

  1. "Download" all the commit from the specified branch of the specified remote repository.
  2. Put the commit from the current branch "on top" of the downloaded commits.

Upvotes: 0

Views: 68

Answers (1)

Mark Adelsberger
Mark Adelsberger

Reputation: 45819

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).

Upvotes: 4

Related Questions