47

我对 Git 还比较陌生,而且我的存储库有点乱。我希望有一种方法可以在不重新克隆的情况下修复它。

我有一个从 Github 克隆的存储库。该存储库有几个分支。我在主分支上工作了一段时间,但后来需要切换到其他分支之一。

所以,我有:

$ git branch --all
* master
  remotes/origin/abc
  remotes/origin/def
  remotes/origin/HEAD -> origin/master
  remotes/origin/ghi

问题:我想切换到“abc”分支,但git checkout remotes/origin/abc我不小心做git branch remotes/origin/abc了,结果如下:

$ git branch --all
* master
  remotes/origin/abc
  remotes/origin/abc
  remotes/origin/def
  remotes/origin/HEAD -> origin/master
  remotes/origin/ghi

我的问题是:

  • 为什么 Git 允许你创建两个同名的分支?
  • 如何识别哪个是真正的 remotes/origin/abc 分支?
  • 如何删除我意外创建的不需要的遥控器/来源/abc?

非常感谢任何帮助。

4

5 回答 5

25

您不能创建两个本地分支或两个具有相同名称的远程分支。

  • 在这里,您有一个名为的本地分支remotes/origin/abc和一个名为abcremote 的远程分支origingit branch --all它们的名称不同,但在您使用命令时似乎如此。

  • 要识别哪个分支是哪个,您可以使用 显示本地分支git branch,或使用 显示远程分支git branch --remotegit branch --all即使使用分支语法着色 ( git config --global color.branch auto) ,您也可以轻松区分它们。

  • 要删除意外创建的本地分支abc,您必须这样做git branch -d abc(或git branch -D abc强制删除,请参阅man git-branch)。

于 2013-06-28T08:14:17.357 回答
7

真实的故事是 Git 对其“引用”(“引用”的 Git 术语,用于指代分支、标签等的术语)有一个简化方案。事实上,引用存在于它们的命名空间中,对于引用 Git 实现,它们只是.git. 例如,您的本地分支“master”实际上是“refs/heads/master”——位于.git/refs/heads目录中的名为“master”的文件。还有“refs/tags”命名空间和“refs/remotes”命名空间——用于标签和远程分支(由git fetch命令创建的那些)。

现在,当您告诉 Git 创建一个分支remotes/origin/abc时,它确实创建了refs/heads/remotes/origin/abc一个不会与之冲突的分支,refs/remotes/origin/abc因为处理该简化方案的规则使前者胜过后者。您可以随时使用完整形式的 ref 命名来消除歧义。

Git 如何解释引用名称的血淋淋的细节在git-rev-parse手册的“指定修订”部分中进行了描述:

<refname>,例如 master、heads/master、refs/heads/master

一个符号引用名称。例如,master 通常表示 refs/heads/master 引用的提交对象。如果你碰巧有 head/master 和 tags/master,你可以明确地说 head/master 来告诉 git 你指的是哪一个。当有歧义时,<refname> 会通过以下规则中的第一个匹配来消除歧义:

如果 $GIT_DIR/<refname> 存在,那就是你的意思(这通常只对 HEAD、FETCH_HEAD、ORIG_HEAD、MERGE_HEAD 和 CHERRY_PICK_HEAD 有用);

否则, refs/<refname> 如果存在;

否则, refs/tags/<refname> 如果存在;

否则,如果存在,则为 refs/heads/<refname>;

否则, refs/remotes/<refname> 如果存在;

否则,如果存在,则为 refs/remotes/<refname>/HEAD。

于 2013-06-28T08:34:54.617 回答
2

Git 对分支名称的限制很少,例如分支名称中的斜线非常好。还可以通过例如删除遥控器上的分支

$ git push origin :abc

而删除本地分支是例如

$ git branch -d remotes/origin/abc

没有歧义,因为这两个实体位于不同的名称空间中。

于 2013-06-28T08:09:54.663 回答
1

origin/...我犯了几次类似的错误(创建一个名为 的本地分支)。

为了防止出现此类错误(假设您永远不会想要名称实际上以 开头的本地分支origin/),您可以在 中运行以下命令repo/.git/refs/heads

mklink /d remotes nul
mklink /d origin nul
mklink /d upstream nul

他们创建符号链接nul,以防止在这些名称下创建子目录。现在像这样的意外错误git branch origin/feature会报错:

unable to create directory for .git/refs/heads/origin/feature
于 2020-06-15T21:24:46.950 回答
-1

使用gitkgitk --all检查分支。在那里你可以看到不同颜色的本地和远程分支。只需右键单击它们即可轻松创建、签出、删除本地分支。

对于您可以使用的远程跟踪分支git gui,创建分支菜单,只需选择远程分支和正确的本地命名理念。这样就很难搞砸了。

至于第一个问题:您不能真正创建具有相同名称的分支,但是如果您为之奋斗,则可能会出现看起来相似的合成名称。使用适当的工具,他们不会感到困惑,因此没有理由禁止这种情况。

于 2013-06-28T08:22:46.117 回答