问题是如何发现的
今天整理之前的老项目,发现前期遗留下很多无用分支,于是,有点强迫症的我就删删删,删出了下列这个错误:
当时吓了我一跳,以为自己不小心错误操作了什么,然而并不是,删除其他的分支还是正常的,就是只有其中一个分支不行。
然后我 Google 了这个问题,果然遇到错误的不是我一个人(这个心理活动,真的每次都会有····)
error: dst refspec dev_test matches more than one.
当远程仓库同时存在相同名称的 branch 和 tag 时,不指明绝对路径的前提下,操作这个名称的 branch 和 tag 都会出现这个问题。
答案先行
解决方法很简单,指明操作对象的绝对路径就能准确操作了
对象 | 路径 |
---|---|
branch | refs/heads/branch_name |
tag | refs/tags/tag_name |
举个删除的例子:
//删除 dev_test 分支
git push origin :refs/heads/dev_test
//删除 dev_test 标签
git push origin :refs/tags/dev_test
看这里可以验证真相
error: dst refspec dev_test matches more than one.
其实,仔细看看返回的错误提示,基本都明白了。(是的,其实当时我没看懂)
上面的提示指出失败原因是 在 refspec 中 ,dev_test
这个名字,对应了多个。
于是,我就去项目的 .git/refs
中看了一下,果然如此
得了一种非要自己试试才能相信的病
我承认,我有病,一种非要自己试试才能相信的病,特别是,最近刚开始用 git 命令行 ,总想自己敲敲敲,感觉很爽。
我准备创建一个叫 dev_test
的分支和标签,然后删除一下试试看,重现错误。
我脑海中的重现命令行是这样的:
1.git branch branch dev_test //创建本地分支 dev_test
2.git push origin dev_test //创建远程分支 dev_test
3.git tag dev_test //创建本地标签 dev_test
4.git push origin dev_test //创建远程标签 dev_test
5.git push origin :dev_test //删除远程分支 dev_test
//然后出现错误
事实是到到第4步就出现了这个错误,如下:
那我真是好奇了,当初我们的开发是怎么做到,把相同的分支和标签给推上去远程的?
参考问题的解决方法,我尝试使用完成路径推送,果然成功了,命令如下:
git push origin refs/tags/dev_test
- 1
好吧,到这里,下面的删除远程 dev_test
命令,我用眉毛想都知道百分之百会报错。
# 总结
重现问题的过程中,对 git 的认知又更加清楚了一点。
一是,git 真的很智能,当我们使用 git push origin <name>
的时候,会自动判断 <name>
在本地版本中是 branch 还是 tag ,然后分别推送对应的位置。
二是,第一次对.git
文件夹中的目录结构和对应的内容感觉到一种非常强烈的好奇,好想知道 git 是怎么把代码管理的这么井井有条,使用起来这么方便的。
三是,Linus Torvalds 真是太强大了。
加油!
PS:
测试完之后,我试图删除这个远程仓库用来测试的dev_test
分支,但是遇到了一个新的错误,如下:
原因是因为当时dev_test
是远程仓库的默认分支,无法删除,去 github 把远程仓库的默认分支修改一下就好了。
具体见: Git- [!remote rejected]:refusing to delete the current branch