git checkout --track 失败

git checkout --track failed

我已将 buildroot git 存储库 (https://git.buildroot.net/buildroot) 克隆到我的主机开发机器 运行 Debian Stretch 上的本地存储库中。

一切正常,git remote -v 的输出是:

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

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

现在我使用 git tag 列出 repo 标签,并想结帐最后一个标签(当前为 2018.02)并同时创建本地分支。

如果我使用 git checkout -b 2018.02 2018.02 它可以工作,但是如果我使用 git checkout --track origin/2018.02 它会失败:

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?

如何解决这个错误?

注意:我的 git 版本是 2.11.0.

谢谢。

使用 git checkout -b 2018.02 2018.02 确实有效,原因可能出乎您的意料。

首先,通读 the gitrevisions documentation,其中描述了 Git 将名称转换为提交哈希的正常过程:

<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:

(然后它列出了六个规则步骤)。在您的情况下,您给 Git 名称 2018.02(作为 git checkout 的最后一个参数),当匹配的唯一引用名称是 refs/tags/2018.02分支名称refs/heads/2018.02不存在(还不存在!)。

因此,Git 解析标签,最终找到提交哈希 ID 8a94ff12d232ada68cff5957089a78a1f0b8f192,并检查该提交。当它这样做时,它 创建 一个名为 2018.02 的分支,以便在 git checkout 完成后,refs/heads/2018.02 存在。

现在有个问题:引用名称不明确。 2018.02 是指 标签名称 2018.02 吗?还是指分支名称?

再次阅读同一句话,即六个步骤之前的句子:

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

第一个匹配是在名称前面添加refs/tags/的匹配,所以大多数命令,询问2018.02,将仍然参考提交8a94ff12d232ada68cff5957089a78a1f0b8f192,不管你的分支名称发生了什么。

git checkout命令不遵守六个步骤:如果你说git checkout 2018.02,Git看起来 for refs/heads/2018.02.如果存在,Git 通过将 HEAD 附加到 refs/heads/2018.02 并检查该名称标识的任何提交来检查 分支名称 。如果您在创建分支名称后进行了一些新提交,那将是其他提交——根本不是 8a94ff12d232ada68cff5957089a78a1f0b8f192

大多数其他 Git 命令将定位标签名称。再背一句考虑一下:

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

这也适用于您的名字 2018.02:您可以写出 tags/2018.02 表示标签名称,heads/2018.02 表示分支名称。但最好不要一开始就陷入这种情况:选择其他分支名称,完全没有歧义。