Search code examples
gitgit-pullgit-fetch

Git: Track branch without checking out?


So, I know you can pull a branch without checking it out by:

git fetch origin branchname:branchname

Is there way to also track that branch without checking it out? (Normally, this is accomplished by: git checkout --track origin/branchname or git branch -u origin branchname) Answer could either be a separate command entirely, or a part of the fetch mentioned above.


Solution

  • The answer is already embedded in your question, as several commenters note: use git branch --set-upstream-to=origin/branchname branchname (or the shorter version with -u). It might be important to add a few notes here, though.

    That's not pulling a branch (or, well, maybe it is, since that phrase is not well defined :-) ). What git fetch origin branchname:branchname does is:

    • fetch any required commits from origin, and then
    • create or update the local branch named branchname based on what the fetch saw in origin's branch branchname.

    The update, if it is an update, fails if the change to branchname is not a fast-forward operation. To force it to succeed in this case, add a force flag: either --force or a leading plus sign +.

    This git fetch-based update also fails if branchname is the currently-checked-out branch, i.e., if HEAD is a symbolic reference to that branch. That is, you can only git fetch origin branchname:branchname if that branch name is not actually checked out right now.

    Meanwhile, git branch --set-upstream-to sets (or overwrites) the upstream setting of a (local) branch. Each local branch can have one upstream setting (or no upstream setting). Having an upstream makes other Git commands—other than git fetch that is—easier to use. Or at least, that's its purpose; whether you personally find the result "easier" is a matter of personal preference. (I've never encountered anyone who found it harder though.)

    If the local branch already existed and already has an upstream set, you might not want to overwrite the current upstream setting. You can check by using git rev-parse: branchname@{upstream} names the current upstream setting of branchname, or fails if it does not have one, so:

    if ! git rev-parse $branchname@{upstream} >/dev/null 2>&1; then
        git branch --set-upstream-to=origin/$branchname $branchname
    fi
    

    will set the upstream if it was unset, but do nothing if it was already set.