震惊:git分支和标签重名竟会有如此后果!
问题
前端同事在向公司某项目仓库推送代码时,习惯使用vscode的图形界面完成操作,过程中会从分支列表里选择要push到的分支。今天他照例操作推送完代码后,该分支出现了奇怪的现象:
- 按照惯例在该分支写代码
- 切换到名为v2.0.0的分支:
git checkout v2.0.0
- 写代码
- 像往常一样add、commit & push
- 切换到名为v2.0.0的分支:
- 但是当在gitlab页面查看分支的commit history时,并没有看到更新。
- 在本地
git checkout v2.0.0
尝试切换到该分支时,会看到分离头指针的提示。
分析
- 一开始看到分离头指针的提示,以为这是关键问题。所以考虑把头指针重新移动回分支的最新commit上以保持和分支的同步
git branch -f v2.0.0 HEAD && git checkout v2.0.0
,再尝试提交&推送,没什么卵用,所以头指针分离并不是关键问题。 - 结合git log图,想到
git checkout v2.0.0
除了能切换到名为v2.0.0
的分支以外,还能切换到名为v2.0.0
的tag,并且会提示头指针分离。 - 此时现象就可以得到解释了:
- 正常情况下是先有的分支
v2.0.0
,本地分支和远程的v2.0.0
分支建立了关联。 - 后来有了名为
v2.0.0
的tag,虽然同名,但是并未影响到原有本地分支和远程分支的关联,所以一切都可以正常工作。 - 直到同事在这次推送代码时,由于在图形界面选择分支时错误地选择了同名的标签,破坏了原来的分支关联关系,导致
git checkout v2.0.0
时,并不是checkout到v2.0.0
分支,而是回退到了同名的标签上,因此再去更新代码时,并未更新到该分支上。
- 正常情况下是先有的分支
解决
-
记下该标签对应的commitId
-
在本地和远程都删除该tag
-
重新checkout到该同名分支,并建立正确的本地远程关联关系。验证代码可以正常push
-
重新打标签
教训
- git最佳实践又学到一条:分支和标签最好不要重名
- 使用图形界面推送选择分支时需要注意,误点可能破坏关联关系
参考
git 的tag和branch 如果重名了 怎么处理 - SegmentFault 思否
Fixing GIT Branch and Tag Name Collisions - Geedew - Blogging about the web.
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。