gitgit-branchgit-remotegit-track

"git remote show origin": why all branches show "tracked" even when some aren't?


Why does "git remote show origin" list remote branches as "tracked" even when those branches are not linked to a local branch for pull/push? Does "tracked" mean something else in this context? I thought that was the whole meaning of "tracked": git docs on branch tracking.

1) clone a repo with more than one remote branch

2) run git remote show origin -- says "testBranch" is tracked. But git branch -vv correctly shows only master tracking origin/master, and git branch -a correctly shows that there's only the one local branch, master.

3) So: what does git remote show origin mean when it lists testBranch as "tracked"? To be clear: there's nothing "wrong" with how things are setup: everything works fine. I just don't understand why the remote testBranch is labeled as "tracked". That's what I want an answer to.

hawk@Tug:~/temp/TestRepo (master)$ git remote show origin
* remote origin
  Fetch URL: git@github.com:haughki/TestRepo.git
  Push  URL: git@github.com:haughki/TestRepo.git
  HEAD branch: master
  Remote branches:
    master     tracked
    testBranch tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)
hawk@Tug:~/temp/TestRepo (master)$ git branch -vv
* master 8df130e [origin/master] shoulda done this last time
hawk@Tug:~/temp/TestRepo (master)$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/testBranch

Solution

  • The "tracked" that git remote show mentions is different from the "tracking" that git branch -vv talks about, that occurs with git checkout -b <branch> <upstream>. (Or maybe "different" is too strong a word, since the underlying idea is the same, it's talking about the remote-tracking branches in your repository, rather than whether you have a local branch that happens to have one of those as its upstream.)

    In particular, git remote show examines the fetch = line(s) for the given remote, and compares this with the references actually available now on the remote (run git ls-remote to see those).

    The default fetch = line for the remote named origin reads:

    fetch = +refs/heads/*:refs/remotes/origin/*
    

    Note the two *s. The one on the left matches all branches that exist on the remote, while the one on the right means "replace with the same name matched on the left".

    Suppose that remote origin currently has the following refs:

    refs/heads/master
    refs/heads/newbr
    refs/tags/v1.2
    refs/notes/commits
    

    Suppose further that branch newbr is new since the last time you cloned, fetched, or otherwise talked to remote origin, so that git branch -r will only list origin/master, not origin/newbr.

    If you now run git remote show origin you will get (along with the other stuff) this bit:

        master tracked
        newbr  new (next fetch will store in remotes/origin)
    

    This means that both branches match, and you already have refs/remotes/origin/master, but you do not yet have refs/remotes/origin/newbr.

    Once you run git fetch, you will acquire origin/newbr. But if, before you do run git fetch, you change your fetch = line so that you won't acquire origin/newbr, git remote show origin will stop mentioning it.