Search code examples
gitdebianbuildroot

git checkout --track failed


I have cloned the buildroot git repository (https://git.buildroot.net/buildroot) into a local repository on my host developement machine running Debian Stretch.

Everything's fine and the output of git remote -v is :

origin https://git.buildroot.net/buildroot (fetch)

origin https://git.buildroot.net/buildroot (push)

Now i list the repo tags using git tag and want to checkout on the last tag (currently 2018.02) and create the local branch at the same time.

if i use git checkout -b 2018.02 2018.02 it works but if i use git checkout --track origin/2018.02 it fails with :

fatal: Cannot update paths and switch to branch '2018.02' at the same time. Did you intend to checkout 'origin/2018.02' which can not be resolved a s commit?

How to fix this error ?

Note : my git version is 2.11.0.

Thank you.


Solution

  • Using git checkout -b 2018.02 2018.02 does indeed work, for reasons you might not be expecting.

    First, read through the gitrevisions documentation, which describes the normal process by which Git turns a name into a commit hash:

    <refname>, e.g., master, heads/master, refs/heads/master

      A symbolc ref name. ... When ambiguous, a <refname> is disambiguated by taking the first match in the following rules:

    (and then it lists six rule steps). In your case you are giving Git the name 2018.02 (as the final argument to git checkout), when the only reference name that matches is refs/tags/2018.02—the branch name refs/heads/2018.02 does not exist (not yet!).

    So, Git resolves the tag, ultimately finding commit hash ID 8a94ff12d232ada68cff5957089a78a1f0b8f192, and checks out that commit. As it does so, it creates a branch named 2018.02, so that after the git checkout finishes, refs/heads/2018.02 also exists.

    Now there is a problem: the reference name is ambiguous. Does 2018.02 mean the tag name 2018.02? Or does it mean the branch name?

    Read that same sentence, the one just before the six steps, again:

    ... When ambiguous, a <refname> is disambiguated by taking the first match in the following rules:

    The first match is the one that adds refs/tags/ in front of the name, so most commands, asked about 2018.02, will still refer to commit 8a94ff12d232ada68cff5957089a78a1f0b8f192, regardless of what happens with your branch name.

    The git checkout command does not obey the six steps: if you say git checkout 2018.02, Git looks first for refs/heads/2018.02. If that exists, Git checks out the branch name, by attaching your HEAD to refs/heads/2018.02 and checking out whichever commit that name identifies. If you've made a few new commits since creating the branch name, that will be some other commit—not 8a94ff12d232ada68cff5957089a78a1f0b8f192 at all.

    Most other Git commands will locate the tag name. Back up one more sentence and consider:

    If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell Git which one you mean.

    This applies to your name 2018.02 as well: you can write out tags/2018.02 to mean the tag name, and heads/2018.02 to mean the branch name. But it's wiser not to get into the situation in the first place: choose some other branch name and there's no ambiguity at all.