git fetch失败:"refs/remotes/origin/pr/34 tracks both"

3

我是git的新手,卡在了git fetch上(我对TFS和SVN有更多经验,所以欢迎任何类比 :))

我在Github上找到了一个项目并进行了fork:

我进行了一些提交,并使用git pull从源获取了最新的更改。在某个时刻,我认为我点击了同步按钮(我正在使用AndroidStudio),从此我就迷失了方向。

它生成了这个提交,但我并不真正理解它。从这里开始,似乎我已经不能再从源获取最新的添加了(黑色源上的最后4个更改)。

我在git fetch上遇到了以下错误:

fatal: refs/remotes/origin/pr/34 tracks both refs/pull/34/head and refs/heads/pr/34

https://github.com/MohammadAG/Xposed-Tinted-Status-Bar/network 为什么我无法获取最新的3个更改?

谢谢


git config --get-all remotes.origin.fetch 会打印什么? - torek
嗯,什么也没有……该命令没有打印任何内容。 - MrLuje
抱歉,打错字了/脑子短路了,应该是remote.origin.fetch(这里的remote是单数)。我的想法是可能有两行将同一个远程引用映射到两个不同的本地引用。 - torek
是的,好多了 :)+refs/pull//head:refs/remotes/origin/pr/ +refs/heads/:refs/remotes/origin/ +refs/heads/:refs/remotes/origin/ - MrLuje
2个回答

9
简短版:远程分支上名为pr/34的分支变成了您的origin/pr/34。但是,远程上名为refs/pull/34/head的引用也变成了您的origin/pr/34。但它们不能同时成为那样,因此git会出错并退出。无论是设置分支映射的任何内容都与在github上设置pull请求分支的任何内容都不兼容(但我对这两个软件都不了解)。
也许删除+refs/pull/*/head:refs/remotes/origin/pr/* fetch配置行是合理的(我不确定)。或者,您可以将它们映射到其他本地参考名称空间,例如refs/pullreqs/origin/*(但这样的参考名称有点难以输入)。如果每个拉取请求都将在github上创建bothrefs/heads/pr/numberrefs/pull/number/head,我建议删除一个配置行。
问题来源的较长解释如下。给定以下内容:
+refs/pull/*/head:refs/remotes/origin/pr/*
+refs/heads/*:refs/remotes/origin/*
+refs/heads/*:refs/remotes/origin/*
从 "git config --get-all remote.origin.fetch" 的输出中,我可以解释出问题所在。 “如何修复” 取决于您想要的结果。
每个输出行都是一个“refspec”,由三个部分组成:左侧的“+”符号,两个“:”之间的名称和右侧的名称。两个名称中都允许使用一个 “*”,它的工作方式类似于文件名中的“*”匹配,例如“*.c”,“*.py”等,在第二个“*”处使用第一个“*”匹配的内容。不管怎样,在下面应该很明显。
(最后一行是多余的,因此无害,它只是使匹配发生了两次。)
那么,让我们看看上面对于名称为 “refs/pull/34/head” 和 “refs/heads/pr/34” 的 ref 名称意味着什么,这两个名称都存在于名为 “origin”(在 github 上)的远程仓库中。
对于 “refs/pull/34/head”:这仅匹配第一个 refspec。 “*” 部分匹配 “34”。该 refspec 的右侧指定将其重写为 “refs/remotes/origin/pr/*”,因此结果为:
refs/remotes/origin/pr/34

现在让我们来处理 refs/heads/pr/34。它不匹配第一个refspec,但匹配第二个。 * 部分匹配 pr/34。该refspec的右侧指示将其重写为 refs/remotes/origin/*,因此结果是:
refs/remotes/origin/pr/34

请注意,在你的本地仓库中,origin 上的两个不同名称已映射到同一个最终名称。Git 不知道将本地的 refs/remotes/origin/pr/34 设置为第一个还是第二个名称。
要解决错误,您必须完全放弃不需要的 "额外" 匹配,或更改重写规则,使得两个不同的远程 refs/whatever 变成两个不同的本地 refs/remotes/origin/whatever。这意味着您需要更改 git 配置文件中的 fetch = 行。
我不知道您想要什么结果,所以无法告诉您如何重写它们。(而且,我不知道最初是什么创建了这些内容 - 正常的 git clone 只会创建一个 +refs/heads/*:refs/remotes/origin/* 条目。其他东西添加了多余的条目和 refs/pull/*/head 的条目。正是这些导致了问题。另外,某个东西在github上创建了refs/heads/pr/34。)

4

当我在本地拉取了一个PR并对其进行更改后,将其推送到远程时,遇到了类似的问题。在尝试获取未来的PR时,出现了类似的错误。为了解决这个问题,我删除了新的本地分支(合并后),然后从远程中删除了该分支(在我的情况下是GitHub)。


2
是的,这也发生在我们团队身上了。如果你要更改一个PR,建议你从它创建一个新分支(这就是为什么它会提醒你进入“无头”模式),这样当你推送时就不会出现命名冲突。 - mattyb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接