我还是相对较新的Git而且我的存储库有点混乱。我希望有一种方法可以修复它而无需重新克隆。
我有一个我从Github克隆的存储库。存储库有几个分支。我在master分支上工作了一段时间,但之后需要切换到其他分支。
所以,我有:
$ 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
我的问题是:
任何帮助都非常感激。
答案 0 :(得分:19)
您不能创建两个具有相同名称的本地分支或两个远程分支。
这里有一个名为remotes/origin/abc
的本地分支和一个名为abc
的远程分支,位于远程origin
上。它们的名称不同,但似乎在使用git branch --all
命令时。
要确定哪个分支是哪个,您可以使用git branch
显示本地分支,或使用git branch --remote
显示远程分支。即使将git branch --all
与分支语法着色(git config --global color.branch auto
)一起使用,您也可以轻松区分它们。
要删除意外创建的本地分支abc
,您必须执行git branch -d abc
(或git branch -D abc
强制删除,请参阅man git-branch
)。
答案 1 :(得分: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-rev-parse
manual的“指定修订”部分中描述了Git如何解释引用名称的详细信息:
< refname>,例如master,heads / master,refs / heads / master
符号引用名称。例如。 master通常表示refs / heads / master引用的commit对象。如果你碰巧有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(如果存在)。
...
答案 2 :(得分:1)
Git对分支名称的限制很少,例如分支名称中的斜杠非常好。同样删除遥控器上的分支也可以通过例如
完成$ git push origin :abc
删除本地分支时,例如
$ git branch -d remotes/origin/abc
没有歧义,因为这两个实体存在于不同的名称空间中。
答案 3 :(得分: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
答案 4 :(得分:-2)
使用gitk
或gitk --all
检查分支机构。在那里你可以看到不同颜色的本地和远程分支。并且只需右键单击它们,即可轻松创建,签出,删除本地分支,而不会产生歧义。
对于远程跟踪分支,您可以使用git gui
,创建分支菜单,只需选择远程分支和正确的本地命名理念。这样很难搞砸。
关于第一个问题:你不能真正创建具有相同名称的分支,但如果你为它而战,可能会发生看似相似的合成名称。使用适当的工具,他们不会混淆,所以没有理由禁止这种情况。