ChatGPT解决这个技术问题 Extra ChatGPT

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

我的 git repo 中有一个名为 xyz 的文件。巧合的是,我还有一个名为 xyz 的分支。目前我在 master 上,但我想结帐到分支 xyz。使用的命令很简单

$ git checkout xyz

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


V
VonC

commit a047faf (git 1.8.4.3+) 所示,您也可以尝试:

git checkout xyz --

(注:error message will be clearer with Git 2.21, Q1 2019

这将清楚地表明 xyz 部分是分支或提交,而 -- 之后的所有内容都必须是路径(此处未提供路径)。请参阅more here on the double-hyphen convention

如果您尝试不使用“--”,则可能会或可能不会起作用,如“Why does git checkout <remote_branchname> not create new tracking branch?”所示:

git checkout name 可以:如果它是本地分支或显式远程分支,则切换到它。如果是跟踪路径,如果是远程分支,则重置它,创建跟踪分支并切换到它。

它的行为并不总是相同的。因此,“--”提供了明确的歧义。

2019 年 8 月更新,Git 2.23+

git checkout is too confusing 并替换为:

git switch:意思是 git switch xyz 即使你有一个文件 xyz 也能工作,

git restore:意思是 git restore xyz 即使你有一个分支 xyz 也可以工作。

另外,正如我在“Why did my Git repo enter a detached HEAD state?”中解释的那样,不再有意外的分离 HEAD。


更好的解决方案,IMO:stackoverflow.com/a/9537923/1096596
@BobbyA 我已经用更好的答案更新了答案
为什么不git checkout -- docsOpenGroup Guideline 10 谈到 -- 作为 选项参数的结尾,但我不明白为什么它在该命令的末尾起作用,而不是 before {4 }。
@FernandoBasso 在答案中,xyz 是分支的名称,而不是路径,因此是 -- after xyz。但是现在,您不会问自己这个问题:使用 git switch(仅限分支)或 git restore(仅限路径/文件)解决这个问题。 git checkout 已过时,不应再使用。
M
Martin Tournoij

虽然 VonC 的解决方案有效,但我永远记不起语法,所以我通常使用技术含量更低的解决方案:

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

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

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

它更容易记住并且有效;-)


V
VonC

Git 2.21 (Q1 2019, 4+ years later) 将澄清错误信息并提出建议

"git checkout frotz" (without any double-dash that I suggested initially) 通过确保“frotz”不能同时被解释为修订和路径来避免歧义

dwimming 从远程跟踪分支“frotz”从一个遥控器。

注意:"dwim" (used below) is "do what I mean",当计算机系统试图预测用户打算做什么时,会自动纠正微不足道的错误,而不是盲目地执行用户明确但可能不正确的输入。

请参阅 Nguyễn Thái Ngọc Duy (pclouds)commit be4908f(2018 年 11 月 13 日)。
(由 Junio C Hamano -- gitster --commit 8d7f9db 中合并,2019 年 1 月 4 日)

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

当在提交 70c9ac2 中添加 checkout dwim 时,它被限制为仅在满足某些条件时使用 dwim,否则回退到默认的 checkout 行为。事实证明,后退可能会令人困惑。将 git checkout frotz 转换为 git checkout -b frotz origin/frotz 的条件之一是 frotz 不能作为文件存在。但是当用户期望“git checkout frotz”创建分支“frotz”并且恰好有一个名为“frotz”的文件时,git 默默地恢复“frotz”文件内容并没有帮助。这在 Git 邮件列表中有所报道,甚至在其他地方用作“Git is bad”的示例。我们通常会尝试做正确的事情,但是当有多个“正确的事情”要做时,最好留给用户来决定。检查这种情况,要求用户消除歧义: "git checkout -- foo" 将检查路径 "foo" "git checkout foo --" 将 dwim 并创建分支 "foo" 6 对于不想要 dwim 的用户,请使用——猜不透。在这种特殊情况下它是没有用的,因为“git checkout --no-guess foo --”只会失败。但它可以被脚本使用。

man page for git checkout 现在包括:

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

在 Git 2.26(2020 年第一季度)之前,“git checkout X”在 X 不是本地分支但可以命名多个远程跟踪分支(即被缩小为起点创建相应的本地分支),已更正。

请参阅 Alexandr Miloslavskiy (SyntevoAlex)commit fa74180commit 2957709(2019 年 12 月 30 日)。
(由 Junio C Hamano -- gitster --commit d0e70cd 中合并,2020 年 2 月 5 日)

结帐:不要在不明确的跟踪分支上恢复文件签名者:Alexandr Miloslavskiy

为了更容易理解,这里是现有的好场景:没有文件 'foo',没有本地分支 'foo' 和单个远程分支 'foo' git checkout foo 将创建本地分支 foo,参见上面的提交 70c9ac2,在此处讨论。并且有一个文件 'foo',没有本地分支 'foo' 和一个远程分支 'foo' git checkout foo 会抱怨,请参阅上面的提交 be4908f 这个补丁可以防止以下情况:有一个文件 'foo',没有本地分支' foo' 和多个远程分支 'foo' git checkout foo 将成功...恢复文件 foo 的内容!也就是说,添加另一个遥控器会突然显着改变行为,这充其量是一个惊喜,最坏的情况可能会被用户忽视。请参阅上面的提交 be4908f,它给出了一些现实世界的抱怨。据我了解,修复了上面的提交 be4908f(在此处讨论),忽略了多个遥控器的情况,并且从未打算回退到恢复文件的整个行为:上面的提交 70c9ac2 引入了意外行为。之前,有从 not-a-ref 到 pathspec 的回退。这是合理的后备。之后,还有另一个从 ambiguous-remote 到 pathspec 的回退。我知道这是复制和粘贴的疏忽。提交 ad8d510,来自“Can't do a checkout with multiple remotes”,并在此处讨论,注意到了意外行为,但选择半记录它而不是禁止,因为补丁系列的目标专注于其他事情。当分支和文件之间存在歧义时,上面的 commit be4908f 添加 die()。多个跟踪分支的情况似乎被忽略了。新行为:如果没有本地分支和多个远程候选者,只需 die() 并且不要尝试恢复文件是否存在(防止意外)或不(改进错误消息)。

在 Git 2.30(2021 年第一季度)中,“git checkout(man) 学会了使用 checkout.guess 配置变量并启用/禁用其“--[no-]guess”相应的选项。

请参阅 Denton Liu (Denton-L)commit 64f1f58(2020 年 10 月 7 日)和 commit ef09e7d(2020 年 10 月 6 日)。
(由 Junio C Hamano -- gitster --commit 0e41cfa 中合并,2020 年 10 月 27 日)

checkout:学会尊重 checkout.guess 签字人:Denton Liu

git checkout/switch 的当前行为是 --guess 当前默认启用。但是,一些用户可能不希望这种情况自动发生。与其每次都强制用户手动指定 --no-guess,不如教这些命令 checkout.guess 配置变量,让用户可以选择设置默认行为。指导完成脚本识别新的配置变量并禁用 DWIM 逻辑(如果设置为 false)。

git config 现在在其 man page 中包含:

checkout.guess 为 git checkout 和 git switch 中的 --guess 或 --no-guess 选项提供默认值。请参阅 git switch 和 git checkout。

git checkout 现在在其 man page 中包含:

--guess 是默认行为。使用 --no-guess 禁用它。默认行为可以通过 checkout.guess 配置变量来设置。

git switch 现在在其 man page 中包含:

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


A
Alexey Ten

你错了。它将结帐分支 xyz。

要签出文件,您需要使用命令 git checkout -- xyz。如果没有同名的分支,Git 只允许您使用文件的快捷方式。

有关详细信息,请参阅 git checkout --help


如果没有发生,我为什么要问这个问题?我正在发生在我身上。通常在签出分支时,响应是 Switched to branch 'xyz',但在我的情况下,没有响应。这是签出文件时的常见情况。此外,我看到 git branch -va 的输出得出结论,没有发生这种变化。