为什么Git允许我创建两个同名的分支?

MrC*_*kle 37 git github

我对Git还是比较陌生的,而且我的存储库有点混乱.我希望有一种方法可以修复它而无需重新克隆.

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

所以,我有:

$ git branch --all
* master
  remotes/origin/abc
  remotes/origin/def
  remotes/origin/HEAD -> origin/master
  remotes/origin/ghi
Run Code Online (Sandbox Code Playgroud)

问题:我想切换到'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
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为什么在地球上Git允许你创建两个同名的分支?
  • 如何识别哪个是真正的遥控器/原点/ abc分支?
  • 如何删除偶然创建的不需要的遥控器/ origin/abc?

任何帮助非常感谢.

aym*_*met 22

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

  • 在这里,您有一个名为local的分支remotes/origin/abc和一个abc在远程上命名的远程分支origin.它们的名称不同,但似乎在使用git branch --all命令时.

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

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

  • 如果有人想知道,只要它们不同时存在,两个本地或两个远程分支就可以具有相同的名称.因此,如果您使用具有通用名称的主题分支并希望将来重用该分支名称,则只要具有该名称的分支尚不存在,您就可以.我不确定这是否可以使用GitHub,因为它们允许您恢复已删除的分支,但我猜他们在删除实际分支之前创建了一个具有唯一名称的分支用于恢复目的. (5认同)

kos*_*tix 6

真实的故事是Git对其"refs"有一个简化方案(一个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因为处理该简化方案的规则使得前者胜过后者.您可以随时使用完整形式的引用命名来消除任何歧义消除.

关于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(如果存在).

...


Ben*_*ier 2

Git 对分支名称的限制非常少,例如分支名称中的斜杠是完全可以的。还可以通过以下命令删除远程分支:

$ git push origin :abc
Run Code Online (Sandbox Code Playgroud)

删除本地分支时是​​例如

$ git branch -d remotes/origin/abc
Run Code Online (Sandbox Code Playgroud)

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