Seeker.Log

一个笨拙的探索者的思考

0%

git checkout

Git 双远程仓库导致的 checkout 分支歧义问题

在日常开发中,我们通常只需要面对一个远程仓库(origin)。但有时候,为了同步代码或迁移仓库,我们会在本地配置多个 Remote(例如同时存在 origingitlab)。

最近遇到了一个有趣的报错:明明远程有这个分支,但我执行 git checkout 时却失败了。

这篇文章记录了原因和解决方法。

问题现场

假设我在终端执行以下命令,想切换到一个老分支:

1
git checkout v3.0_old

Git 报错或者提示找不到该分支(尽管我知道远程肯定有)。

经过检查 git remote -vgit branch -r,我发现我的本地仓库配置了两个远程源:

双远程仓库

  1. gitlab
  2. origin

而且,这两个远程仓库里都有一个同名的分支

  • gitlab/v3.0_old
  • origin/v3.0_old

Git 为什么“困惑”了?

当我输入简短的 git checkout v3.0_old 时,Git 的内部逻辑是这样的:

  1. 查本地:先看本地有没有叫 v3.0_old 的分支? -> 结果:没有
  2. 查远程:既然本地没有,那我尝试去远程找找,看能不能自动建立追踪关系。
  3. 发现冲突:坏了!我在 gitlab 里找到了一个,在 origin 里也找到了一个。
  4. 中止操作:Git 不敢擅自决定你到底想要基于哪一个来建立本地分支(虽然它们的代码内容可能完全一样,但上游追踪目标不同)。出于谨慎,Git 选择报错。

简单来说,就是目标不唯一,Git 犯了选择困难症

解决方案

解决方法非常简单:显式地告诉 Git,你想用哪一个远程仓库的分支作为“基准”。

通用公式如下:

1
git checkout -b <本地新分支名> <远程仓库名>/<远程分支名>

方案 A:基于 origin

如果你主要向 origin 提交代码,或者它是主仓库:

1
git checkout -b v3.0_old origin/v3.0_old

这条命令的意思是:在本地新建一个叫 v3.0_old 的分支,并让它明确追踪 origin 下的对应分支。

方案 B:基于 gitlab

如果你更倾向于使用 gitlab 这个源:

1
git checkout -b v3.0_old gitlab/v3.0_old

总结

当你的 Git 环境中存在多个 Remote 时,偷懒使用 git checkout <branch_name> 可能会失效。
建议养成习惯,在多 Remote 环境下,使用 git checkout -b ... origin/... 这种显式指定上游的写法,可以避免很多不必要的混淆。

江湖卖艺,有钱的捧个钱场,有人的捧个人场:P