存在同名文件时,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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 10:18:39  来源:igfitidea点击:

Git change branch when file of same name is present

gitgit-branchgit-checkout

提问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 xyzto 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 xyzpart 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 namedoes:

  • 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 checkoutis too confusingand is replaced with:

git checkout太混乱了,替换为:

  • git switch: meaning git switch xyzwill work even if you have a file xyz,
  • git restore: meaning git restore xyzwill work even if you have a branch xyz.
  • 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 files

When 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 frotzmust 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" 6

For 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 checkoutnow 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 Xis 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 fa74180commit 2957709(2019 年 12 月 30 日(由Junio C Hamano合并-- --d0e70cd 提交中,2020 年 2 月 5 日)SyntevoAlex
gitster

checkout: don't revert file on ambiguous tracking branches

Signed-off-by: Alexandr Miloslavskiy

For easier understanding, here are the existing good scenarios:

  1. Have nofile 'foo', nolocal branch 'foo' and a singleremote branch 'foo'
  2. git checkout foowill create local branch foo, see commit 70c9ac2 above, discussed here.

and

  1. Have afile 'foo', nolocal branch 'foo' and a singleremote branch 'foo'
  2. git checkout foowill complain, see commit be4908f above

This patch prevents the following scenario:

  1. Have afile 'foo', nolocal branch 'foo' and multipleremote branches 'foo'
  2. git checkout foowill successfully... revert contents of file foo!

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: 不要在不明确的跟踪分支上恢复文件

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

为了更容易理解,这里是现有的好场景:

  1. 没有文件“ foo”,没有本地分支“ foo”和一个单一的远程分支“ foo
  2. git checkout foo将创建本地分支foo,请参阅上面的提交 70c9ac2此处讨论

  1. 一个文件“ foo”,没有本地分支“ foo”和一个单一的远程分支“ foo
  2. git checkout foo会抱怨,请参阅上面的提交 be4908f

此补丁可防止以下情况:

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

也就是说,添加另一个遥控器会突然显着改变行为,这充其量是一个惊喜,最坏的情况可能会被用户忽视。
请参阅上面的提交 be4908f,它给出了一些现实世界的抱怨。

据我了解,在上面的提交 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 --helpfor details.

详情请参阅git checkout --help