git fetch vs. git fetch origin master have different effects on tracking branch

This is mostly of the nature of a curiosity as I’m trying to get familiar with Git. I have looked at the documentation for ‘git fetch‘ but I don’t see an obvious explanation for the below. Thanks in advance, and apologies if this is howlingly obvious.

1) From a central repository, say GitHub, I clone a repository named website on each of two machines, HostA and HostB.

  • 2 svn -> 1 git. How to map two svn repositories into one git with two branches with common origin?
  • git: Find the oldest commit of `mine` which does not exist in `theirs`
  • How to merge to get rid of head with Mercurial command line, like I can do with TortoiseHg?
  • How to rename an SVN branch and update references in an existing sandbox?
  • Branching in Mercurial
  • git staging and committing between multiple branches
  • 2) on HostA, I make a change to a file, say README.txt, and commit it.
    At this point on HostA, the commits for branches master and
    origin/master are, as expected different since I haven’t pushed yet

    git show master
    git show origin/master
    

    report different hashes (since master has the change and origin/master does not)

    3) Once I push, they are after that the same.


    4) Now, over on HostB, if I do the following:

    git fetch
    git merge FETCH_HEAD
    

    afterwards, on HostB master and origin/master report the same hash when queried with git show

    BUT

    if instead I had done, on HostB:

    git fetch origin master
    git merge FETCH_HEAD
    

    at that point the hashes still differ.

    git show origin
    git show origin/master
    

    report different hashes

    The tracking branch origin/master isn’t updated until I do a plain git fetch

    Why is this?

  • Cannot commit changes with intellij
  • Using HoloEverywhere library
  • Is there a way to force the creation of a remote repository?
  • Use ppk key when cloning a git repo
  • List all commits in a topic branch
  • Git fetch single file from remote repository programatically
  • 3 Solutions collect form web for “git fetch vs. git fetch origin master have different effects on tracking branch”

    If your branch has an associated remote tracking branch that means its configuration is like:

    git config branch.[branch-name].remote [remote-name]
    git config branch.[branch-name].merge [remote-master]
    

    The key part of git fetch which explain the difference between the two commands is:

    <refspec>
    

    The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>, followed by a colon :, followed by the destination ref <dst>.
    The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref that matches it is fast-forwarded using <src>.

    Let me repeat it:

    if <dst> is not empty string, the local ref that matches it is fast-forwarded using <src>.
    Knowing that:

    • git fetch is equivalent to git fetch origin master:master (from the default value of your branch config), so it will update the remote tracking branch: the destination of the refspec is specified for you.

    • git fetch origin master is equivalent to “git fetch origin master:“, not to “git fetch origin master:master“; it stores fetched value of ‘master‘ branch (of remote ‘origin‘) in FETCH_HEAD, and not in ‘master‘ branch or remote-tracking ‘remotes/origin/master‘ branch (from Jakub Narębski’s answer)
      In other words, you didn’t specify the destination of your refspec

    The answer lies in the messages you get back from git fetch. In the first case, when you fetch without providing a refspec, you’ll see that the remote tracking branches are updated:

    remote: Counting objects: 5, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /depot
       c67d1c8..1941673  master     -> origin/master
    

    Note how the message says that origin/master is updated with the master from the origin.

    Now in the second case, where you specify the refspec, you get something altogether different:

    remote: Counting objects: 5, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /depot
     * branch            master     -> FETCH_HEAD
    

    So when you specify the refspec, the remote tracking branch (origin/master) is NOT updated, only FETCH_HEAD.

    The end result is that you’ll appear to be ahead of origin/master when you’re not really. I can’t imagine why this behavior would be desirable, but it’s definitely an interesting little quirk of the fetch command.

    If you want to fast forward merge yourself, or use git pull. You don’t seem to understand that the purpose of git fetch is NOT to update your working tree. Fetch is meant to update your tracking branches.

    Git Baby is a git and github fan, let's start git clone.