当存在同名文件时 Git 更改分支

我的 Git 回购里有个叫 xyz 的文件。巧合的是,我也有一个分支命名为 xyz。现在我是主人,但我想结帐分行 xyz。要使用的命令很简单

$ git checkout xyz

但是这会将文件 xyz签出到当前的 HEAD。如何将我的分支更改为分支 xyz

63078 次浏览

你错了,它会结账的。

要签出文件,需要使用命令 git checkout -- xyz。 如果没有相同名称的分支,Git 只是为您提供了一个文件的快捷方式。

详情请参阅 git checkout --help

承认一个047faf(git 1.8.4.3 +)所示,您还可以尝试:

git checkout xyz --

(注: 使用 Git 2.21,Q12019,错误消息将更加清晰)

这将清楚地表明,xyz部分是一个分支或提交,而 --之后的所有内容都必须是一个路径(这里没有提供路径)。参见 这里有更多关于双连字符约定的信息

如果你尝试不使用“ --”,这可能会成功,也可能不会成功,如“ 为什么 git 签出 <remote_branchname>不创建新的跟踪分支?”所示:

git checkout name:

  • 如果它是本地分支或显式远程分支,则切换到它。
  • 如果是跟踪路径,重新设置
  • 如果是远程分支,创建一个跟踪分支并切换到它。

而且它的行为并不总是相同的。因此,‘ --’提供了一个明确的消歧。


2019年8月更新,Git 2.23 +

git checkout太令人困惑了,取而代之的是:

另外,正如我在“ 为什么我的 Git 回购进入了一个分离的 HEAD 状态?”中解释的那样,没有更多意想不到的分离 HEAD。

虽然 VonC 的解决方案有效,但我从来记不住语法,所以我通常使用一种技术含量较低的解决方案:

$ (cd somedir && git checkout my-branch)

或者,如果您没有任何子目录:

$ (cd .git && git -C .. checkout my-branch)

这样更容易记住,也更有效; -)

Git 2.21(2019年第一季度,4年以后)将成为 澄清错误信息并提出建议

git checkout frotz”(没有我最初建议的那种双破折号) 通过确保“ frotz”不能同时被解释为修订版和路径,避免了歧义

这种安全性已被更新,以检查一个独特的远程跟踪分支‘ frotz’在一个远程,当 游泳创建一个本地分支‘ frotz’从一个远程跟踪分支‘ frotz’。

注意: “ dwim”(下面使用)是“ do what I mean”,当计算机系统试图预测用户打算做什么时,自动纠正微小的错误,而不是盲目执行用户显式但可能不正确的输入。

犯罪(2018年11月13日) by 易懂的泰语(pclouds)
(由 朱尼奥 · C · 哈马诺 gitster于2019年1月4日在 提交8d7f9db合并)

checkout: 消除 dwim 跟踪分支和本地文件的歧义

当在 第七季,第9集中添加签出 dwim 时,它仅限于在满足某些条件时使用 dwim,否则返回到默认的签出行为。

后退可能会让人困惑。

转向的条件之一

git checkout frotz

git checkout -b frotz origin/frotz

frotz不能以文件的形式存在。

但是,当用户期望“ git checkout frotz”创建分支“ frotz”时,恰好有一个名为“ frotz”的文件 Git 默默地恢复“ frotz”文件内容是没有帮助的
这在 Git 邮件列表中被报道,甚至被用作 其他地方“ Git 很糟糕”的一个例子

我们通常试图做正确的事情,但是当有多个“正确的事情”要做时,最好让用户来决定。

检查这个案例,要求用户消除歧义:

  • git checkout -- foo”将检查路径“ foo”
  • git checkout foo --”将缩小并创建分支“ foo6

对于不需要 dim 的用户,使用 --no-guess 因为“ git checkout --no-guess foo --”会失败。
但是它可以被脚本使用。

git checkout的手册页现在包括:

--no-guess:

如果存在同名的远程跟踪分支,则不要尝试创建分支。


在 Git 2.26之前(2020年第一季度) ,当 X不是本地分支而是 可以说出一个以上的远程追踪分支时,“ git checkout X”没有正确地失败(即作为创建相应本地分支的起点) ,这已经被纠正。

提交 fa741802957709(2019年12月30日) by 亚历山大 · 米洛斯拉夫斯基(SyntevoAlex)
(由 朱尼奥 · C · 哈马诺 gitster于2020年2月5日在 提交 d0e70cd合并)

checkout : 不要恢复跟踪不明确的分支上的文件

签名: 亚历山大 · 米洛斯拉夫斯基

为了更容易理解,下面是现有的好方案:

  1. 拥有 没有文件‘ foo’、 没有本地分支‘ foo’和 单身远程分支‘ foo
  2. git checkout foo将创建本地分支 foo,请参阅 在上面写上70c9ac2在这里讨论

还有

  1. 具有 文件‘ foo’、 没有本地分支‘ foo’和 单身远程分支‘ foo
  2. git checkout foo会投诉,见 上面写着4908f

这个补丁可以防止以下情况:

  1. 文件‘ foo’,没有本地分支‘ foo’和 多个远程分支‘ foo
  2. git checkout foo将成功... 恢复文件 foo的内容!

也就是说,添加另一个遥控器会突然显著改变行为,这在最好的情况下是令人惊讶的,在最坏的情况下可能会被用户忽略。
请看 上面写着4908f,它给出了一些现实世界的抱怨。

根据我的理解,在 上面写着4908f(在这里讨论)中修复,忽略了多个远程的情况,并且回退到恢复文件的整个行为从来没有打算:

新的行为: 如果没有本地分支和多个远程候选分支,只有 die(),不管文件是否存在(防止意外)都不要尝试还原文件(改进错误消息)


在 Git 2.30(Q12021)中,“ git checkout(< a href = “ https://git-scm.com/docs/git-checkout”rel = “ nofollow noReferrer”> man )学会了使用 checkout.guess配置变量,并相应地启用/禁用其“ --[no-]guess”选项。

承诺64f1f58(2020年10月7日)及 犯罪现场调查,第九季,第7集(2020年10月6日) by 刘(Denton-L)
(由 朱尼奥 · C · 哈马诺 gitster合并于 承认吧,2020年10月27日)

学会尊重 checkout.guess

签名: Denton Liu

git checkout/switch的当前行为是当前默认启用 --guess
但是,有些用户可能不希望这种情况自动发生。
不要强迫用户每次都手动指定 --no-guess,而是教授这些命令 checkout.guess配置变量,它为用户提供设置默认行为的选项。

教完成脚本识别新的配置变量,如果设置为 false,则禁用 DWIM逻辑。

git config现在在其 手册中包括:

checkout.guess

提供 --guess--no-guess的默认值 选项在 git checkoutgit switch。参见 git switch git checkout

git checkout现在在其 手册中包括:

--guess是默认行为。使用 --no-guess禁用它。

可以通过 checkout.guess配置设置默认行为 变量。

git switch现在在其 手册中包括:

可以通过 checkout.guess配置设置默认行为 变量。