git推送错误:dst参考规格参考/头/主匹配多个

i2byvkas  于 2023-03-28  发布在  Git
关注(0)|答案(3)|浏览(273)

现在我不得不在每一次修改的时候推到一个新的分支上,而这个分支必须被删除,因为这个错误会在每一个新创建的分支上再次出现。
git push origin main给出以下输出

error: dst refspec refs/heads/main matches more than one
error: failed to push some refs to 'https://github.com/CarloCattano/fastesTube'

我的git tag输出:

refs/heads/dev
refs/heads/dev2
refs/heads/dev3
refs/heads/main
v1.1
win64

不管我是否用-d手动删除它们。甚至试图将项目迁移到新的repo,几次推送后问题仍然存在。
git remote -v

origin  https://github.com/CarloCattano/fastesTube (fetch)
origin  https://github.com/CarloCattano/fastesTube (push)

git ls-remote

ac4cac50b79ff682ddd01f6c0c3913d0bd765e64        HEAD
77273d612953f96e72ce305ab94f0a535a4c332d        refs/heads/dev3
3c344e7af2feb33db2d05f08866cad5fe624b57c        refs/heads/develop
ac4cac50b79ff682ddd01f6c0c3913d0bd765e64        refs/heads/main
fde3bb1ed7c770a5b8eb94a368bb34f25566f00e        refs/pull/1/head
ffe33059c3fcc12899953bc588772072d9a18bf0        refs/pull/2/head
77273d612953f96e72ce305ab94f0a535a4c332d        refs/pull/3/head
3c344e7af2feb33db2d05f08866cad5fe624b57c        refs/pull/4/head
b9d1c3f8b83ea1ac868143ec647776d03f9bacc7        refs/tags/refs/heads/dev
ffe33059c3fcc12899953bc588772072d9a18bf0        refs/tags/refs/heads/dev2
77273d612953f96e72ce305ab94f0a535a4c332d        refs/tags/refs/heads/dev3
4098ea71b5a0873db6be41e859e5b8242d81c708        refs/tags/refs/heads/main
a42341ba40635bd5063a0bf988eab6c00b0e62d1        refs/tags/v1.1
37220afec1d13dcac99c61ef766ac800fc6438f5        refs/tags/win64

用力推似乎也不起作用。
可能是我错误地配置了.yml文件,并为每个版本创建了标记。

ngynwnxp

ngynwnxp1#

这里的问题是,您创建了名为refs/heads/...的 * 标记 *(填写三个点)。
在Git中,refreference 是一个字符串,通常以refs/开头,然后有一个命名空间限定符:

  • refs/heads/*是 * 分支 * 名称:与*匹配的部分是分支名称;
  • refs/tags/*是 * 标签 * 名称:与*匹配的部分是标签名称;
  • refs/remotes/*是 * 远程跟踪 * 名称;

通常你可以给予Git一个缩写的名字,比如mainv1.1,它可以通过查看现有的名字来判断这个名字是分支名还是标签名:

  • 通常有一个refs/heads/mainrefs/heads/master,但没有refs/tags/mainrefs/tags/master,因此mainmaster是一个 * 分支 * 名称。
  • 可能有一个refs/tags/v1.1,但通常没有refs/heads/v1.1,因此v1.1是一个 * 标签 * 名称。

当使用这种方案时,你提供一个模糊的名称,如mainv1.1,Git会自己判断它是一个分支或标签名称,* 或者 * 你提供一个 * 完整 * 名称,如refs/heads/main,Git会立即知道它是一个 * 分支 * 名称。短名称,前面没有refs/heads/refs/tags/限定符,是一个 * 非限定名称 *。全名是一个 * 限定名称 *。
git push命令比大多数其他Git命令更复杂(除了git fetch类似地复杂),因为它必须处理 * 两个 * Git仓库,而不是一个。所以git push可以接受 refspec,而不是 ref,这是一对由冒号:分隔的refs。如果你使用完整的refspec:

git push origin refs/heads/main:refs/tags/v1.2

然后左边和右边的部分都是 refs,每个部分都是非限定的或限定的。非限定的名称可以通过查看本地Git存储库的名称(对于那些是本地的)或远程的名称(对于那些是远程的)来解决。
但是,如果使用 partial refspec:

git push origin main

那么Git就不能确定你的意思是“在本地找到的main”还是“在远程找到的main”。所以Git会在这两个地方寻找最好的猜测。
然而,在本例中,destination Git(其引用显示在git ls-remote输出中)同时具有refs/heads/main * 和 * refs/tags/refs/heads/main。它现在在另一个Git仓库的refs集中查找,并且 * 无法将其转换为一个ref*,因为 * refs/heads/main-一个完全限定的分支名称-* 和 * refs/tags/refs/heads/main-一个完全限定的 * 标记 * 名称-匹配可能不限定的refs/heads/main。结果是您得到此错误消息。
我不知道你是否会在git push origin refs/heads/main:refs/heads/main上得到这个错误。不过,最好的解决方法是纠正 destination 上的名称集,这样就不再有refs/tags/refs/*名称了。也就是说,这四个名称:

b9d1c3f8b83ea1ac868143ec647776d03f9bacc7        refs/tags/refs/heads/dev
ffe33059c3fcc12899953bc588772072d9a18bf0        refs/tags/refs/heads/dev2
77273d612953f96e72ce305ab94f0a535a4c332d        refs/tags/refs/heads/dev3
4098ea71b5a0873db6be41e859e5b8242d81c708        refs/tags/refs/heads/main

应该调整(或完全删除),以便GitHub上的Git存储库中没有标签名称以refs/开头。理想情况下,这些标签名称也不应该匹配任何分支名称:标记名通常应该符合v*,或者其他一些“明确的标记”模式,这样就不会有人意外地认为它们是分支名,反之亦然。
一旦你修复了这个问题,简单的git push命令将再次工作。

5f0d552i

5f0d552i2#

更新:不知道这对于多个推送有多可靠!我似乎遇到了一些奇怪的事情。我在查看git ls-remote时,我的分支名称存储在多个引用下
我通过以下方式解决了这个问题:

git push origin -u --force <sha>:origin/feature/branch

我认为我真正需要的是origin/前缀,可能不需要origin -u

nbewdwxp

nbewdwxp3#

我的git tag输出:

refs/heads/dev
...

好消息是,自2023年3月起,将无法再向GitHub推送此类“标签”名称:

Block ambiguous branch and tag names(2023年3月)

GitHub阻止以refs/开始的分支和标签名称。
在后台,所有的Git引用都以前缀开始(分支为refs/heads/,标签为refs/tags/)。
然而,在典型的使用中,用户很少看到这些前缀,因此它们由GitHub、Git客户端和其他工具静默处理。
当类似的字符串用作分支或标记名称的可见部分的开头时,这会导致歧义:用户是否打算使用refs/heads/featurerefs/heads/refs/heads/feature
几乎在所有情况下,分支或标记名称前面的refs/都是偶然的,后来会成为一个有问题的惊喜。
此更改阻止新引入此类名称。
具有以这种方式命名的现有分支的存储库仍然可以将更新推送到这些分支。

相关问题