git-svn clone | 虚假的分支

cra*_*rty 22 git git-svn git-branch

我使用以下命令将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
Run Code Online (Sandbox Code Playgroud)

在svn中创建的实际分支是abc,branch_test_script,modules和release.有人可以帮助理解'abc-1.3.x@113346','abc-1.3.x @ 541512'......'release-1.1@468862'等是什么?

我们如何摆脱这些虚假的分支/它们意味着什么?

谢谢,
Gayathri

sle*_*ske 17

TL;博士:

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的子目录分支,它将创建:

  • 从r1233向后的每个SVN修订的新git提交(注意该数字是创建分支之前的最后一个修订).这些提交的树只包含已分支的子目录.因此,对于r1233向后的每个修订版,通常会有两个git提交,一个包含整个树(在git-svn处理历史记录时创建trunk)和新的.
  • 一个名为"bar @ 1233"的虚拟分支(分支名称@ revision),它突然出现在上面的r1233创建的提交中.
  • 来自r1234的提交,即创建分支的提交.这个提交将上面的分支作为其(唯一的)祖先.
  • 一个名为"bar"的分支,指向第二个提交.

这样,对于子目录分支栏,你在git中得到两个分支

  • bar @ 1233,表示创建分支的存储库的状态
  • 酒吧,代表分支

我不太清楚为什么要创建这个虚拟分支.我认为这样做是为了表示分支从哪个版本分支出来的信息,并为分支提供完整的历史记录.


请注意,可以使用标志关闭整个机制--no-follow-parent.在这种情况下,每个SVN分支将产生一个git分支,只有来自SVN分支目录的提交.每个分支将与历史的其余部分不连接,并且将具有其自己的根提交,对应于分支中的第一个提交.


eck*_*kes 5

当我将我的 SVN 存储库克隆到 Git 存储库时,我也有如此奇怪的分支。

在查看了预期的分支(在您的情况下modules-1.2abc-1.3.xbranch_test_scriptrelease-1.1)之后,我注意到@revisionnumber分支只不过是其前缀分支中的提交。

如果您想手动执行此操作,请gitk在分支上打开abc-1.3.x并验证abc-1.3.x@113346abc-1.3.x@541512显示在该分支的历史记录中。如果是这样,您可以删除相应的分支。

如果您有许多分支或许多提交要浏览,这可能会有点麻烦。

自动方式:让 git 为你做:

git branch -r --contains abc-1.3.x@113346
Run Code Online (Sandbox Code Playgroud)

会回声(或至少应该

abc-1.3.x
abc-1.3.x@113346
abc-1.3.x@541512
Run Code Online (Sandbox Code Playgroud)

这意味着您可以安全地删除,abc-1.3.x@113346因为它包含在abc-1.3.x

git branch -r -d abc-1.3.x@113346
Run Code Online (Sandbox Code Playgroud)

由于 SVN 的线性历史,它当然也包含它(较新的) commit 541512


旁注:
您可能已经注意到,您的 SVN 标签实际上并未转换为 Git 标签和本机 Git 分支。这可以使用svn2git将 SVN存储库克隆到 Git 存储库中来实现。