Git 推送提交显示错误:无法推送到非限定目标



我正在尝试使用 WIP 将头部提交推送到远程 - 显示错误,例如

$ git push remote 51447424149c671958a2f76ec1fefb135a5c2cea:WIP-51447424149c671958a2f76ec1fefb135a5c2cea

[结果]

error: unable to push to unqualified destination: WIP-51447424149c671958a2f76ec1fefb135a5c2cea
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to 'https://github.com/abc'

有什么帮助吗?

TL;博士

您可能想要:

$ git push remote 51447424149c671958a2f76ec1fefb135a5c2cea:refs/heads/WIP-51447424149c671958a2f76ec1fefb135a5c2cea

以创建名为WIP-51447424149c671958a2f76ec1fefb135a5c2cea的分支。 (确保你真的想创建这个名字,因为它有点不奇怪。 它是有效的,它没有问题,它只是

输入的东西。

Git 抱怨的内容需要一点解释:

  • 分支名称是一种特殊的引用形式。
  • 引用是以refs/开头的字符串。 熟悉的两种引用是分支名称和标记。 (稍后会详细介绍。
  • 参考文献可以缩写...有时,但并非总是如此。
  • 有时(只要对 Git 有意义),您就可以使用原始哈希 ID 而不是引用。
  • git push采用refspec,它是一对由冒号分隔的引用(可选地,整个内容可以用加号作为前缀)。

你正在用git push做的是使用(很长的)refspec51447424149c671958a2f76ec1fefb135a5c2cea:WIP-51447424149c671958a2f76ec1fefb135a5c2cea. 此 refspec 的左侧是引用,右侧是目标引用。

冒号左侧的东西显然是1个哈希 ID。 因此,这是利用特殊情况,您可以提供哈希 ID 而不是实际引用(只要该对象实际存在于您的 Git 存储库中)。

但是,冒号右侧的东西是一个名称,而不是哈希ID。 这很好,因为这是 Git需要名称的地方之一。 但这也是一个问题,因为WIP-something这个名字不是以refs/开头的。

请注意,Git 明确抱怨这一点:

目的地...也不以refs/开头

在我们开始其余部分之前,让我们再次提及分支和标签。 像master这样的分支名称是参考refs/heads/master的简写。 像v1.2这样的标签名称是引用refs/tags/v1.2的简写。 请注意,在这两种情况下,这些都以refs/开头。 他们继续命名我们正在使用的参考类型

  • 分支名称引用以refs/heads/开头。
  • 标记名称引用以refs/tags/开头。

换句话说,当我们说分支和标签是引用的形式时,我们的意思是给定一个引用,你可以查看refs/后面的内容,并弄清楚它是什么样的引用:refs/heads/表示"分支",refs/tags/表示"标签"。 (如果你看到refs/remotes/,这意味着它是一个远程跟踪名称;还有更多特殊的词在refs/之后,比如notes/表示git notes

我们在上面也说过,引用有时可以缩写。 不过,这是 Git 在这里抱怨的第一部分:

。都与遥控器上的现有参考不匹配...

你可以省略refs/heads/部分,让另一个 Git——你的 Git 推送到的那个——弄清楚master真正意味着refs/heads/master。 但这只有在他们已经有refs/heads/master时才有效. 如果你正在尝试创建一个新分支,你必须告诉另一个 Git我希望你创建一个新分支。

您可以通过提供引用的全名来执行此操作:例如refs/heads/WIP-something。 它以refs/heads/开头的事实告诉另一个 Git:我想创建一个分支名称。如果您向他们发送refs/tags/WIP-something,则告诉他们创建新的标签名称。

无论如何,这就是为什么你会得到相当长的抱怨,它有两个部分:"既不......也不是"。 因此,解决方案是向他们发送全名。


1什么,这不是很明显吗? :-) 这让我想起了那些通过做六个变换来证明定理的教授,然后说"其余的都是显而易见的......"。

Git 2.21(2019 年第 1 季度,1 年后)将改进该错误消息:"git push $there $src:$dst"在$dst不是完全限定的 refname 且不清楚最终用户的意思时拒绝。

代码路径已被教导给出更清晰的错误消息,并通过考虑推送对象的类型来猜测推送应该去哪里(例如,标签对象想要进入refs/tags/)。

注意:DWIM(下面使用)是"按照我的意思做":

计算机系统试图预测用户打算做什么,自动纠正琐碎的错误,而不是盲目地执行用户的明确但可能不正确的输入。

参见 Ævar Arnfjörð Bjarmason (avar
) 提交的 2219c09、提交 bf70636、提交 dd8dd30、提交 04d1728、提交 c83cca3、提交 8b0e542、提交 cab5398(2018 年 11 月 13 日)。(由Junio C Hamano --gitster-- 在提交 0a84724 中合并, 04 Jan 2019)

push:改进不合格<dst>推送显示的错误

改进 f8aae12 中添加的错误消息("push:允许 不合格的 dest refspecs to DWIM", 2008-04-23, Git v1.5.5.2),在此之前 更改如下所示:

$ git push avar v2.19.0^{commit}:newbranch -n
error: unable to push to unqualified destination: newbranch
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to 'git@github.com:avar/git.git'

需要非常仔细地阅读此消息以发现如何修复错误,即推送到refs/heads/newbranch

现在,消息将如下所示:

$ ./git-push avar v2.19.0^{commit}:newbranch -n
error: The destination you provided is not a full refname (i.e.,
starting with "refs/"). We tried to guess what you meant by:
- Looking for a ref that matches 'newbranch' on the remote side.
- Checking if the <src> being pushed ('v2.19.0^{commit}')
is a ref in "refs/{heads,tags}/". If so we add a corresponding
refs/{heads,tags}/ prefix on the remote side.
Neither worked, so we gave up. You must fully qualify the ref.
error: failed to push some refs to 'git@github.com:avar/git.git'

此改进是线程"Re:[PATCH 2/2]push:添加关于不合格<dst> push的建议"评论#1(2018年10月)和评论#2中列表讨论的结果,以及我自己的修复/重新格式化/措辞。

杰夫在名单上的建议是将第二个要点"Looking at the refname of the local source."。
此处添加的版本更详细,但也更准确。
说"本地源"可以指本地引用存储中的任何引用,包括refs/remotes/*中的某些内容。以后的更改将教guess_ref()推断引用 从远程跟踪引用键入,所以我们不要混淆两者。

这还不是全部:现在有一个新的设置。

现在有了advice.pushUnqualifiedRefName=true(默认情况下打开),我们显示一个 关于如何继续的提示:

$ ./git-push avar v2.19.0^{commit}:newbranch -n
error: The destination you provided is not a full refname (i.e.,
starting with "refs/"). We tried to guess what you meant by:
- Looking for a ref that matches 'newbranch' on the remote side.
- Checking if the <src> being pushed ('v2.19.0^{commit}')
is a ref in "refs/{heads,tags}/". If so we add a corresponding
refs/{heads,tags}/ prefix on the remote side.
Neither worked, so we gave up. You must fully qualify the ref.
hint: The <src> part of the refspec is a commit object.
hint: Did you mean to create a new branch by pushing to
hint: 'v2.19.0^{commit}:refs/heads/newbranch'?
error: failed to push some refs to 'git@github.com:avar/git.git'

当尝试推送标记、树或 blob 时,我们建议用户可能打算将它们推送到refs/tags/

该配置有一个新的建议:

pushUnqualifiedRefname:

git push放弃尝试根据源和目标 ref 猜测源属于哪个远程 ref 命名空间时显示,但我们仍然可以建议用户根据源对象的类型推送到refs/heads/*refs/tags/*

最新更新