为什么使用 git checkout <remote_branchname> 不会创建新的跟踪分支?

8
如果X作为远程分支存在,则git checkout X应该创建一个本地分支。在我的情况下,对于单个分支,它没有这样做。
远程仓库有一个masterrelease和一些其他的分支(比如refactor-update)。 我执行以下操作: git clone WHATEVER/repo.git git checkout release 但是我没有收到正常的分支切换消息,也没有创建一个本地分支来跟踪origin/release(根据git checkout的手册)。我还停留在master上。请注意,如果我执行git checkout refactor-update,则一切都按预期工作。
这在其他计算机上也可以重现(尽管是相同的平台和可能是相同版本的git)。出于绝望的原因(而不是因为我认为它会起作用),我删除了release分支,并用备份和master替换了它,但行为没有改变(git push origin :release && git push origin master:release)。
我被困在可能导致问题的原因上。我怀疑git checkout似乎出于某种原因无法识别单词release,这使它很像只执行git checkout。为了尝试跟进这个问题,在另一个仓库中,我创建了一个发布分支,以查看它是否是保留字或其他原因,但它确实只存在于这个仓库中。在.git/config中似乎没有任何异常。
Git版本:1.8

你是否忘记获取远程分支了?尝试执行 git fetch --prune,然后再执行相同的 git checkout X - Miguelgraz
是的,-p / --prune 仅添加了“删除不匹配”的行为,拾取内容始终启用(前提是您没有破坏远程 git 配置 fetch = 行 :-))。 - torek
“--prune”与普通的“fetch”没有不同的行为。我尝试创建了一个几乎没有私人信息的空仓库,以提供复制步骤,然后发布分支开始工作。不幸的是,我没有用处的仓库,因为我删除了所有文件并用空的“TESTFILE”替换它们:P - medwards
作为一次实验,我执行了 gitk somebranchonlyontheremote,并且如预期的那样,gitk 说 'wut?'。然后我执行了 gitk release(本地没有名为 release 的分支),它展示了一个历史... - medwards
1
你的项目根目录中是否包含与你想要检出的分支同名的文件或文件夹?也就是说,是否有一个名为 repo/release 的文件/文件夹?这是我的问题之一。你使用的 Git 版本是哪个? - jcsahnwaldt Reinstate Monica
显示剩余2条评论
4个回答

4
在我的情况下,问题在于我有一个与项目根目录中的分支同名的文件夹。Git似乎认为git checkout xyz中的xyz是文件夹而不是分支。
首次切换到分支xyz时,我必须执行以下操作:git checkout -t origin/xyz
显然,这会向.git/config(或其他配置文件)添加几行内容。之后,我可以通过调用git checkout xyz/git checkout masterxyzmaster之间进行切换。
当我在根文件夹中并在克隆存储库后立即调用git checkout xyz时,Git什么也不做,也没有任何响应。当我进入子文件夹,以便文件夹xyz不再在范围内,并调用git checkout xyz时,Git会抱怨:error: pathspec 'xyz' did not match any file(s) known to git

2
那看起来像是一个 bug -- 你应该写出一个能够复现问题的程序,并将 bug 报告发送给 git 邮件列表。 - torek
1
我的意思是,那种花哨的“哦哇,那是一个分支名而不是路径名”的东西(你不需要 -b)。我总是对 DWIM 持谨慎态度,因为它会导致像你遇到的这种情况,即分支名称和路径元素匹配。 - torek
1
@jthill:幸运的是,我不负责git命令,也许。 :-) 我可能会将“checkout”拆分为至少两个完全不同的命令,一个是“切换到(可选创建)分支”,另一个是“从当前或命名分支提取文件”。 - torek
1
可能是个小bug,但这就是正确的答案。我删掉了release文件夹,现在git checkout release可以按预期工作了。感谢@JonaChristopherSahnwaldt和@torek一直关注并假设我不是一个git新手,从未见过-b或-t参数。 - medwards
1
这是一个错误,修复方案正在git邮件列表中讨论。关于git checkout x是指分支 x还是路径 x存在争议,但是git checkout x --应该明确表示“分支x”,而它现在却有问题。 - torek
显示剩余4条评论

1

Clone操作为您提供了所有源的远程分支,但仅在请求时为源的HEAD分支(或任何其他分支)提供本地分支。

简而言之:如果X作为远程分支存在,则git checkout X应创建一个本地分支。在我的情况下,对于单个分支,它没有这样做。

我不太赞同这个说法。如果您想要checkout创建一个分支,请告诉它创建一个分支。

git checkout -t origin/release     # create branch `release` tracking `origin/release`.

git checkout -b foobar             # create branch `foobar` based on your HEAD commit

[编辑:]

我现在认为我理解了投诉。

git checkout name 的作用:

  • 如果是本地分支或明确的远程分支,则切换到它。
  • 如果是已跟踪的路径,则重置它。
  • 如果是远程分支,则创建一个跟踪分支并切换到它。

由于它优先考虑重置,因此当可以选择安全操作时,它可能会选择执行不安全操作。


2
混淆的是,git checkout foo通常会检出远程分支 - 除非有一个名为“foo”的文件/文件夹。所以我不同意你的反对。;-) - jcsahnwaldt Reinstate Monica
活到老,学到老。当远程仓库添加了错误的分支名称时,我的路径检出会受到警报,就像你的路径检出因错误的路径名而受到警报一样。我同意@torek的评论,这种行为是如此不可预测,以至于它属于错误领域。Git应该在两个方便都可能适用时发出警告,而不是默默地选择我喜欢的那一个。 - jthill

0

您缺少了-b选项

尝试执行

git checkout -b branch_name

编辑说明:如下方评论所讨论的,这只适用于使用 git 版本 1.7.9 或更早版本的情况,而我当时正是使用这个版本。


即使远程存在该分支,使用“-b”选项是否必要? - Miguelgraz
2
实际上,这取决于您使用的git版本。对于相当新的版本,您不再需要-b,因为git会自动检测到您没有foo分支,但有一个remotes/origin/foo,所以它会隐式地执行-b foo origin/foo - torek
@ansh0l:请注意,我说的是“根据git checkout的手册”,它明确说明了我的用例应该有效。不仅如此,我还概述了我的用例如何适用于其他分支。在我的情况下,我正在运行1.8分支中的某些操作。 - medwards
1
我在1.8.3.2版本的发布说明中看到了这个。1.6.1版本的发布说明提到添加git checkout --track origin/hack作为创建本地分支hack的方法,但是1.8.3可能是第一个通过只命名远程分支而不需要origin/来完成此操作的版本。 - torek
“git checkout -b x” 在我的电脑上(Mac,git 1.8.3.2)无法正常工作。它会显示“Switched to a new branch 'x'”,但不会更改工作树。如果我先将该分支添加到.git/config中,git会显示“Switched to a new branch 'x'”,但同时也会显示“Your branch and 'origin/x' have diverged”,并提示我执行“git pull”。当我运行“git pull”时,git会尝试将x分支合并到我的本地主分支副本中,结果一团糟。 - jcsahnwaldt Reinstate Monica
显示剩余2条评论

0
你缺少了 -t 选项。
git checkout -t origin/release

将创建并检出本地分支release来跟踪origin/release

使用更新的Git版本,这就足够了:

git checkout release

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接