问题描述

多人在一个仓库协作时,在本地进行git pull操作,遇到下面的错误,注意,已对下面中的项目信息进行了省略和替换

error: cannot lock ref '...':is at <commit_id1> but expected <commit_id2>
From https://....
! <commit_id1>..<commit_id2> <branchName> -> origin/<branchName> (unable to update local ref)

问题分析

从错误日志来看,大概是本地分支和远程分支的HEAD不太一致,比较奇怪的是这个分支并不是我的。

  1. 去远程看,就是代码托管网站,查找该错误信息提到的branchName,发现有两个名字一样的分支,只是它们的大小写不一样,然后分别查看这两个分支的最后一次commit id,发现就是错误日志中列出来的。
    看到这里,问题就相对比较清楚了,锁定大概方向。

  2. 进入到本地项目的路径,进入到下面的子文件夹:(.git是个隐藏文件夹;如果没有,那就是windows电脑没有设置显示隐藏文件,怎么设置就不赘述了)
    .git\refs\remotes\origin

    发现里面确实是有个小写的branchName的文件,里面保存的是一条完整的commit id,这就是ref。

  3. 再次看到这里时,马上想到怎么没有大写的branchName的文件。
    熟悉windows系统的话,应该马上想到,windows下,文件名不区分大小写,所以导致它们两个文件不能共存。

总结如下:

  1. Git是区分大小写的,所以可以存在两个大小写不同但名字是一样的分支。
  2. Windows系统的文件,是不区分大小写的,导致.git\refs\remotes\origin下只存在小写的文件,以致于git pull时commit id不一致的问题。

解决方案

分2种情况

解决当次

如果这个分支不是你的,所以你不要想动这两个分支,还是请分支拥有者来查看这个问题。
步骤:

  1. 进入到本地项目的路径,进入到下面的子文件夹:
    \.git\refs\remotes\origin
  2. 删除出问题分支名的文件
  3. 再次执行git pull,就可以成功拉取代码,你会发现,上面的文件夹下,又有了刚刚删除的文件了,所以只能解决当次。

一劳永逸

如果这两个分支一直存在,又在windows下工作,这个问题就会一直存在。
一劳永逸的办法,就是只保留一个分支,根据项目具体情况来权衡。

  1. 删除两个中不需要保留的分支

    • 从代码托管网站直接删掉
    • 本地执行git命令,可以参考下面的文章

      git branch使用

  2. 进入到本地项目的路径,进入到下面的子文件夹:
    \.git\refs\remotes\origin

  3. 删除出问题分支名的文件

  4. 再次执行git pull,就可以成功拉取代码,以后也是可以的,因为以后该路径下,只会有一个这样名字的ref文件。

建议

通过这个问题,所以大家以后在windows下使用git时,还是需要注意下分支的命名,不要使用同名而大小写不同的取名方式,尽量有描述性一点,如果有Jira系统,可以把Jira号放到分支名开头。

最后,如果这篇博客有帮助到大家,就点个赞吧!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐