我使用以下命令将svn repo克隆到git中,在执行它之后,我看到了一些虚假的分支。
git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp
git branch -a
*(no branch)
master
remotes/abc-1.3.x
remotes/abc-1.3.x@113346
remotes/abc-1.3.x@541512
remotes/branch_test_script
remotes/tags/modules-1.2
remotes/tags/modules-1.2@113346
remotes/tags/modules-1.2@516265
remotes/tags/release-1.1
remotes/tags/release-1.1@113346
remotes/tags/release-1.1@468862
remotes/trunk
在svn中创建的实际分支是abc,branch_test_script,modules和release。 有人可以帮助理解'abc-1.3.x@113346','abc-1.3.x @ 541512'......'release-1.1@468862'等是什么?
我们如何摆脱这些虚假的分支/它们意味着什么?
谢谢,
Gayathri
答案 0 :(得分:17)
TL; DR:
如果为子目录(或未由git-svn跟踪的另一个目录)创建了分支(或标记),则 git svn
创建这些“@” - 分支。总会有一个同名的“常规”分支,但没有“@”后缀。 “@” - 分支仅作为常规分支的分支点存在。
注意:我为此提交了一个补丁;此解释的编辑版本现在是官方git svn
联机帮助页的一部分,作为“处理SVN分支”的新部分(自Git 1.8.1起)。
在Subversion中,分支和标签只是目录树的副本,因此可以(尽管通常不鼓励)从一个本身不是分支(或主干)的目录创建分支。例如,通过将/ trunk / foo复制到/ branches / bar,而不是复制/ trunk(“子目录分支”,可以这么说),或者复制位于trunk / tags / branches结构之外的目录(这是可能在SVN)。
然而,在git中,一个分支总是用于整个repo,子目录分支不存在。因此git svn
使用了一种解决方法。如果它检测到从git-svn本身未跟踪为分支的目录中复制的分支,则会创建新的历史记录。例如,对于将/ trunk / foo复制到r1234中的/ branches / bar的子目录分支,它将创建:
trunk
的历史时创建)和新的。这样,对于子目录分支栏,你会在git中得到两个分支
我不太清楚为什么会创建这个虚拟分支。我认为这样做是为了表示分支从哪个版本分支出来的信息,并为分支提供完整的历史记录。
请注意,可以使用标记--no-follow-parent
关闭整个机制。在这种情况下,每个SVN分支将产生一个git分支,只有来自SVN分支目录的提交。每个分支都将与历史记录的其余部分无关,并且将具有自己的根提交,对应于分支中的第一个提交。
答案 1 :(得分:4)
在审核了预期的分支(在您的情况下为modules-1.2
,abc-1.3.x
,branch_test_script
和release-1.1
)后,我注意到@revisionnumber
分支只不过是承诺在他们的前缀分支。
如果您想手动执行此操作,请在分支gitk
上打开abc-1.3.x
,并验证abc-1.3.x@113346
和abc-1.3.x@541512
是否显示在该分支的历史记录中。如果是这样,您可以删除相应的分支。
如果你有很多分支或许多提交要浏览,这可能有点麻烦。
自动方式:让git为你做这件事:
git branch -r --contains abc-1.3.x@113346
将回显(或至少应该)
abc-1.3.x
abc-1.3.x@113346
abc-1.3.x@541512
这意味着您可以放心地删除abc-1.3.x@113346
,因为它包含在abc-1.3.x
中:
git branch -r -d abc-1.3.x@113346
由于SVN的线性历史,它当然也包含(较新的)提交541512
。
旁注:
您可能已经注意到您的SVN标记实际上并未转换为Git标记和本机Git分支。这可以使用svn2git将SVN repo克隆到Git仓库中来实现。