我的 git repo 中有一个名为 xyz 的文件。巧合的是,我还有一个名为 xyz 的分支。目前我在 master 上,但我想结帐到分支 xyz。使用的命令很简单
$ git checkout xyz
但这会将文件 xyz
检出到当前 HEAD。如何将我的分支更改为分支 xyz
?
如 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。
虽然 VonC 的解决方案有效,但我永远记不起语法,所以我通常使用技术含量更低的解决方案:
$ (cd somedir && git checkout my-branch)
或者,如果您没有任何子目录:
$ (cd .git && git -C .. checkout my-branch)
它更容易记住并且有效;-)
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 fa74180、commit 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 配置变量来设置。
你错了。它将结帐分支 xyz。
要签出文件,您需要使用命令 git checkout -- xyz
。如果没有同名的分支,Git 只允许您使用文件的快捷方式。
有关详细信息,请参阅 git checkout --help
。
Switched to branch 'xyz'
,但在我的情况下,没有响应。这是签出文件时的常见情况。此外,我看到 git branch -va
的输出得出结论,没有发生这种变化。
不定期副业成功案例分享
git checkout -- docs
? OpenGroup Guideline 10 谈到--
作为 选项参数的结尾,但我不明白为什么它在该命令的末尾起作用,而不是 before {4 }。xyz
是分支的名称,而不是路径,因此是--
afterxyz
。但是现在,您不会问自己这个问题:使用git switch
(仅限分支)或git restore
(仅限路径/文件)解决这个问题。git checkout
已过时,不应再使用。