存在同名文件时,Git 更改分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25322335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git change branch when file of same name is present
提问by venky
I have in my git repo, a file named xyz. Coincidently, I also have a branch named xyz. Presently I am on master, but I want to checkout to branch xyz. The command to be used is simple
我的 git repo 中有一个名为 xyz 的文件。巧合的是,我也有一个名为 xyz 的分支。目前我在 master 上,但我想结帐到分支 xyz。要使用的命令很简单
$ git checkout xyz
But this would checkout the file xyz
to the present HEAD. How would I change my branch to branch xyz
?
但这会将文件检出xyz
到当前的 HEAD。我将如何将我的分支更改为分支xyz
?
回答by VonC
As illustrated by commit a047faf(git 1.8.4.3+), you can also try:
如commit a047faf(git 1.8.4.3+) 所示,您也可以尝试:
git checkout xyz --
(Note: the error message will be clearer with Git 2.21, Q1 2019)
(注意:错误信息在 Git 2.21, Q1 2019 中会更清晰)
That would make clear that the xyz
part is a branch or commit, while everything after --
must be a path (here no path is provided). See more here on the double-hyphen convention.
这将清楚表明该xyz
部分是分支或提交,而后面的所有内容都--
必须是路径(此处未提供路径)。参见更多在这里的双连字符约定。
If you try without the '--
', that might or might not work, as shown in "Why does git checkout <remote_branchname>
not create new tracking branch?":
如果您尝试不使用 ' --
',那可能会也可能不会起作用,如“为什么 git checkout<remote_branchname>
不创建新的跟踪分支?”所示:
git checkout name
does:
- if it's local branch or explicit remote branch, switch to it.
- if it's a tracked path, reset it
- if it's a remote branch, create a tracking branch and switch to it.
git checkout name
做:
- 如果是本地分支或显式远程分支,请切换到它。
- 如果是跟踪路径,则重置它
- 如果是远程分支,则创建一个跟踪分支并切换到它。
And its behavior isn't always the same. Hence the '--
' to provide a clear disambiguation.
它的行为并不总是相同的。因此,' --
' 提供了明确的消歧。
Update August 2019, Git 2.23+
2019 年 8 月更新,Git 2.23+
git checkout
is too confusingand is replaced with:
git checkout
太混乱了,替换为:
git switch
: meaninggit switch xyz
will work even if you have a filexyz
,git restore
: meaninggit restore xyz
will work even if you have a branchxyz
.
git switch
: 意思是git switch xyz
即使你有文件也能工作xyz
,git restore
:git restore xyz
即使你有一个分支,意思也会起作用xyz
。
Plus, as I explain in "Why did my Git repo enter a detached HEAD state?", no more unexpected detached HEAD.
另外,正如我在“为什么我的 Git 存储库进入分离的 HEAD 状态?”中所解释的那样,不再出现意外的分离的 HEAD。
回答by Martin Tournoij
While VonC's solution works, I can never remember the syntax, so I typically use a more low-tech solution:
虽然 VonC 的解决方案有效,但我永远记不起语法,所以我通常使用技术含量较低的解决方案:
$ (cd somedir && git checkout my-branch)
Or, if you don't have any subdirectories:
或者,如果您没有任何子目录:
$ (cd .git && git -C .. checkout my-branch)
It's easier to remember and it works ;-)
它更容易记住并且有效;-)
回答by VonC
Git 2.21 (Q1 2019, 4+ years later) will clarify the error message and make suggestions
Git 2.21 (Q1 2019, 4+ years later) 将澄清错误信息并提出建议
"git checkout frotz
" (without any double-dash that I suggested initially) avoids ambiguity by making sure 'frotz
' cannot be interpreted as a revision and as a path at the same time.
“ git checkout frotz
”(没有我最初建议的任何双破折号)通过确保 ' frotz
' 不能同时被解释为修订和路径来避免歧义。
This safety has been updated to check also a unique remote-tracking branch 'frotz
' in a remote, when dwimmingto create a local branch 'frotz
' out of a remote-tracking branch 'frotz
' from a remote.
此安全性得到了更新,还检查了独特的远程追踪分支“ frotz
”在一个偏僻的,当dwimming创建本地分支“ frotz
”出来的远程跟踪分支“的frotz
从远程”。
Note: "dwim" (used below) is "do what I mean", when a computer system attempts to anticipate what users intend to do, correcting trivial errors automatically rather than blindly executing users' explicit but potentially incorrect inputs.
注意:“dwim”(以下使用)是“做我的意思”,当计算机系统尝试预测用户打算做什么时,会自动纠正琐碎的错误,而不是盲目地执行用户明确但可能不正确的输入。
See commit be4908f(13 Nov 2018) by Nguy?n Thái Ng?c Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
--in commit 8d7f9db, 04 Jan 2019)
请参阅Nguy?n Thái Ng?c Duy ( ) 的提交 be4908f(2018 年 11 月 13 日)。(由Junio C Hamano合并-- --在提交 8d7f9db 中,2019 年 1 月 4 日)pclouds
gitster
checkout
: disambiguate dwim tracking branches and local filesWhen checkout dwim is added in commit 70c9ac2, it is restricted to only dwim when certain conditions are met and fall back to default checkout behavior otherwise.
It turns out falling back could be confusing.
One of the conditions to turn
git checkout frotz
to
git checkout -b frotz origin/frotz
is that
frotz
must not exist as a file.But when the user comes to expect "
git checkout frotz
" to create the branch "frotz
" and there happens to be a file named "frotz
", git's silently reverting "frotz
" file content is not helping.
This is reported in Git mailing listand even used as an example of "Git is bad" elsewhere.We normally try to do the right thing, but when there are multiple "right things" to do, it's best to leave it to the user to decide.
Check this case, ask the user to to disambiguate:
- "
git checkout -- foo
" will check out path "foo"- "
git checkout foo --
" will dwim and create branch "foo
" 6For users who do not want dwim, use
--no-guess
. It's useless in this particular case because "git checkout --no-guess foo --
" will just fail.
But it could be used by scripts.
checkout
: 消除 dwim 跟踪分支和本地文件的歧义当在commit 70c9ac2 中添加 checkout dwim 时,它会在满足某些条件时仅限于 dwim,否则将退回到默认的 checkout 行为。
事实证明,回落可能会令人困惑。
转的条件之一
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 --
" 将 dwim 并创建分支 "foo
" 6对于不想要 dwim 的用户,请使用
--no-guess
. 在这种特殊情况下它没有用,因为“git checkout --no-guess foo --
”只会失败。
但它可以被脚本使用。
The man page for git checkout
now includes:
现在的手册页git checkout
包括:
--no-guess:
Do not attempt to create a branch if a remote tracking branch of the same name exists.
--no-guess:
如果存在同名的远程跟踪分支,请不要尝试创建分支。
Before Git 2.26 (Q1 2020), "git checkout X
" did not correctly fail when X
is not a local branch but could name more than one remote-tracking branches(i.e. to be dwimmed as the starting point to create a corresponding local branch), which has been corrected.
在 Git 2.26(2020 年第一季度)之前,“ git checkout X
”在不是X
本地分支时不会正确失败,但可以命名多个远程跟踪分支(即以 dwimmed 作为起点创建相应的本地分支),这已被更正。
See commit fa74180, commit 2957709(30 Dec 2019) by Alexandr Miloslavskiy (SyntevoAlex
).
(Merged by Junio C Hamano -- gitster
--in commit d0e70cd, 05 Feb 2020)
参见Alexandr Miloslavskiy ( ) 的commit fa74180和commit 2957709(2019 年 12 月 30 日)。(由Junio C Hamano合并-- --在d0e70cd 提交中,2020 年 2 月 5 日)SyntevoAlex
gitster
checkout
: don't revert file on ambiguous tracking branchesSigned-off-by: Alexandr Miloslavskiy
For easier understanding, here are the existing good scenarios:
- Have nofile '
foo
', nolocal branch 'foo
' and a singleremote branch 'foo
'git checkout foo
will create local branchfoo
, see commit 70c9ac2 above, discussed here.and
- Have afile '
foo
', nolocal branch 'foo
' and a singleremote branch 'foo
'git checkout foo
will complain, see commit be4908f aboveThis patch prevents the following scenario:
- Have afile '
foo
', nolocal branch 'foo
' and multipleremote branches 'foo
'git checkout foo
will successfully... revert contents of filefoo
!That is, adding another remote suddenly changes behavior significantly, which is a surprise at best and could go unnoticed by user at worst.
Please see commit be4908f above, which gives some real world complaints.To my understanding, fix in commit be4908f above(discussed here), overlooked the case of multiple remotes, and the whole behavior of falling back to reverting file was never intended:
commit 70c9ac2 aboveintroduces the unexpected behavior.
Before, there was fallback from not-a-ref to pathspec. This is reasonable fallback.
After, there is another fallback from ambiguous-remote to pathspec.
I understand that it was a copy&paste oversight.commit ad8d510, from "Can't do a checkout with multiple remotes", and discussed here, noticed the unexpected behavior but chose to semi-document it instead of forbidding, because the goal of the patch series was focused on something else.
commit be4908f aboveadds
die()
when there is ambiguity between branch and file.
The case of multiple tracking branches is seemingly overlooked.The new behavior: if there is no local branch and multiple remote candidates, just
die()
and don't try reverting file whether it exists (prevents surprise) or not (improves error message).
checkout
: 不要在不明确的跟踪分支上恢复文件签字人:亚历山大·米洛斯拉夫斯基
为了更容易理解,这里是现有的好场景:
- 有没有文件“
foo
”,没有本地分支“foo
”和一个单一的远程分支“foo
”git checkout foo
将创建本地分支foo
,请参阅上面的提交 70c9ac2,此处讨论。和
- 有一个文件“
foo
”,没有本地分支“foo
”和一个单一的远程分支“foo
”git checkout foo
会抱怨,请参阅上面的提交 be4908f此补丁可防止以下情况:
- 有一个文件 '
foo
',没有本地分支 'foo
' 和多个远程分支 'foo
'git checkout foo
将成功...恢复文件的内容foo
!也就是说,添加另一个遥控器会突然显着改变行为,这充其量是一个惊喜,最坏的情况可能会被用户忽视。
请参阅上面的提交 be4908f,它给出了一些现实世界的抱怨。据我了解,在上面的提交 be4908f 中修复(此处讨论),忽略了多个遥控器的情况,并且从未打算回退到恢复文件的整个行为:
上面的 commit 70c9ac2引入了意外行为。
之前,有从 not-a-ref 到 pathspec 的回退。这是合理的回退。
之后,还有另一个从 ambiguous-remote 到 pathspec 的回退。
我知道这是复制和粘贴的疏忽。提交 ad8d510,来自“无法使用多个遥控器进行结账”,并在此处讨论,注意到意外行为,但选择半记录它而不是禁止,因为补丁系列的目标集中在别的东西上。
die()
当分支和文件之间存在歧义时,上面的 commit be4908f添加。
多个跟踪分支的情况似乎被忽略了。新行为:如果没有本地分支和多个远程候选者,
die()
则不要尝试恢复文件是否存在(防止意外)(改善错误消息)。
回答by Alexey Ten
You're wrong. It will checkout branch xyz.
你错了。它将结帐分支 xyz。
To checkout a file, you need to use command git checkout -- xyz
.
Git just allow you a shortcut for files if there is no branch with the same name.
要签出文件,您需要使用 command git checkout -- xyz
。如果没有同名的分支,Git 只允许您创建文件的快捷方式。
See git checkout --help
for details.
详情请参阅git checkout --help
。