在Git分支名称中使用斜杠字符

302

我很确定在一个流行的Git项目中看到过分支名称的模式是"feature/xyz"。

然而,当我尝试创建一个带有斜杠字符的分支时,我会收到一个错误:

$ git branch labs/feature
error: unable to resolve reference refs/heads/labs/feature: Not a directory
fatal: Failed to lock ref for update: Not a directory

对于我的初始尝试,出现了相同的问题:

$ git checkout -b labs/feature

如何在 Git 中使用斜杠字符创建分支?


1
实际上,看起来你的HEAD出了问题。Git似乎认为你的HEAD是指向尚未创建的分支labs/feature的链接。我不知道这是怎么发生的,但这意味着你试图基于它创建一个名为foo/bar的分支是行不通的。你有任何想法是如何让你的HEAD变得不稳定的吗? - CB Bailey
很抱歉造成混淆,正确的是“labs/feature”,而不是“foo/bar”(已编辑过的示例)。 - user58777
1
值得一提的是,斜杠前面的任何内容都会在.git/refs/heads下生成一个目录。例如,如果您执行git checkout -b feature/123,则在projectRootFolder/.git/refs/heads目录中,您将看到一个名为feature的目录,在该目录中,您将看到一个名为123的分支。稍后,如果您创建另一个feature/124,则在feature目录中,您将看到一个名为124的分支。 - mfaani
8个回答

294

你确定分支labs不存在吗?(例如在这个帖子中的情况)?

不能同时拥有同名的文件和目录。

你正在尝试让git做如下操作:

% cd .git/refs/heads
% ls -l
total 0
-rw-rw-r-- 1 jhe jhe 41 2009-11-14 23:51 labs
-rw-rw-r-- 1 jhe jhe 41 2009-11-14 23:51 master
% mkdir labs
mkdir: cannot create directory 'labs': File exists
你得到了相当于“无法创建目录”的错误。
当你有一个带有斜杠的分支时,它会被存储为目录层次结构在.git/refs/heads下。
请注意,如ddruganov评论中指出的那样,labs必须不是现有的分支
 git switch -c 19023-commerce/19033-commerce-view 19023-commerce

 # Fails with:

 fatal: cannot lock ref 'refs/heads/19073-commerce-view/99999-test-branch': 
 'refs/heads/19073-commerce-view' exists; 
  cannot create 'refs/heads/19073-commerce-view/99999-test-branch'

此处所述:

  • 如果分支 b 已存在,则无法创建名为 b/anything 的分支。
  • 同样,如果分支 dev/b 存在,则无法创建 dev/b/c。

这是 Git 的内部限制。


3
感谢您详细的回复。有趣的是,我尝试了"git branch foo/bar"(成功了);然后尝试了"git branch -d foo/bar",但我发现foo/目录(现在是空的)仍然存在!编辑:当我执行"git branch foo"时,它会立即被替换掉。一切都很好。 - user58777
1
@faB: 非常糟糕...但并不意外:您删除了foo命名空间中的bar,但没有删除foo本身(它可以作为其他分支的命名空间或者是一个分支)。 - VonC
54
总结答案:分支名称可以包含斜杠。原问题提问者已经有一个名为 labs 的分支,试图创建 labs/feature 分支,但 Git 拒绝了此操作。 - duozmo
@duozmo 那么解决方案是什么?我该如何指定我是从某个特定的参考分支进行分支的? - ddruganov
@ddruganov 只需确保您没有一个属于您要创建的分支的文件即可。 - VonC
显示剩余7条评论

136

可以使用层次化的分支名称(带有斜杠的分支名称)。例如,在我的代码库中,我有这样的分支。但需要注意的是,您不能在存储库中同时拥有分支“foo”和分支“foo/bar”。

您的问题并不在于创建具有斜杠名称的分支。

$ git branch foo/bar
错误:无法解析参考refs/heads/labs/feature:不是目录
致命错误:无法锁定要更新的引用:不是目录

上述错误消息提到了“labs/feature”分支,而不是“foo/bar”(除非这是复制和粘贴的错误,即您编辑了会话的某些部分)。请问git branchgit rev-parse --symbolic-full-name HEAD的结果是什么?


2
谢谢,对于混淆感到抱歉,我最初写了一个foo/bar的例子,但是复制了我的实际测试中的错误消息。不会再这样做了 :) 对于我的错误也很抱歉,事实上我已经有一个“labs”分支了。 - user58777

65

我忘记了我已经有一个未使用的labs分支。删除它解决了我的问题:

git branch -d labs
git checkout -b labs/feature

解释:

每个 名称 只能是一个父分支或者普通分支,不能同时拥有两种身份。这就是为什么分支 labs labs/feature 不能同时存在的原因。

原因:分支存储在文件系统中,你也不能在同一层级上同时拥有文件 labs 和目录 labs


正是我想要的!谢谢 - Tai Le

42
有时候,如果您已经有一个与基础名称相同的分支,就会出现这个问题。
我尝试过这个:
git checkout -b features/aName origin/features/aName

很不幸,我已经有一个名为features的分支,而我遇到了问题提问者的异常。

删除分支features解决了这个问题,上述命令起作用了。


1

分支名称区分大小写,如果您的发布管理员在Azure中创建了文件夹,则文件夹名称应完全匹配。我曾经吃过亏,向经理提出此问题。


1

如果有人遇到这样的问题,无法检出到一个分支,比如:features/23,因为它说分支features存在,但你在Github上找不到它-可能是你有一个本地分支命名为features导致的。

使用git branch -D features删除本地分支,然后你应该能够用git checkout features/23检出,它应该按预期工作。


0

刚遇到了同样的问题,但我找不到冲突的分支了。

在我的情况下,仓库之前有一个“foo”分支,但现在没有了,我尝试从远程创建和检出“foo/bar”。 就像我说的,“foo”不再存在,但问题仍然存在。

最后,在.git/config文件中仍然存在“foo”分支,删除它后一切都正常了:)


0

我是通过Visual Studio Git Changes完成的

如先前所述,我犯了一个错误,创建了一个dev分支。 main dev

认为以后可以通过dev/somebranchname来调用它们。

解决方案是删除dev,然后创建dev/somebranchname。下一个dev分支将被称为dev/nextbranchname。 这非常适用于Visual Studio,其中dev变成了一个文件夹视图,然后分支排列在其后面。


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