如何将具有不一致分支结构的SVN导入Git?

时间:2012-03-06 06:46:53

标签: git svn git-svn git-branch git-clone

如果以前曾问过这个问题,我很抱歉,但我的情况比较具体。我已经在我的公司工作了一段时间并使用SVN,但最近因为各种原因希望搬到Git。

我现在遇到的问题是我的公司使用非标准的分支结构,不幸的是,过去有时它甚至不是一致的非标准分支结构。

自从加入公司以来,我所知道的历史是,我们使用一个主干线分支,我们从中创建分支分支和功能分支。然而,这些分支的结构不仅仅是标准的主干/分支/标签结构。我们为不同类型的分支提供了几个子文件夹。例如,发布分支进入branches_release,branches_feature中的功能分支等,如下所示:

branches_feature/featureA
branches_release/2.0

我想出了如何通过修改Git repo的配置来使克隆/获取正常工作,以便

branches = {branches_feature,branches_release}/*:refs/remotes/branches/*

这在取得适当的分支方面相对成功。我遇到的一个问题是,当我的公司刚开始时,它使用的结构更像是:

branches_feature/username/branchname

不幸的是,为了找到这个(困难的方法)我不得不“git svn fetch”并发现所有这些分支遵循旧的分支约定已被折叠,因此在Git中每个用户都有一个分支,其中每个分支都存在分支机构。所以,

branches_feature/username/featureA
branches_feature/username/featureB

已经崩溃成:

branches_feature/username

显然这对于​​正确复制的SVN repo历史记录是不够的,但我不确定如何修改config的分支行来封装所有这些分支并仍然正确使用新的分支格式。我一直试图以各种方式操纵它,但我最终得到错误或者只是在尝试中失败。

如果有人能够在从SVN导入Git时建议一个合适的方法来保存SVN repo的历史,我将不胜感激。

感谢。

2 个答案:

答案 0 :(得分:1)

你当然可以解决这个问题,但你应该考虑与回归相比你愿意花多少钱。

如果您只是限制转换为发布分支机构和主干,那么功能分支的缺失会成为主要问题吗?你应该仍然有提交(因为它们将出现在合并中),因此唯一不存在的提交是那些尚未合并回主干的提交。

如有必要,您可以稍后转换所需的功能分支,并使用git replacegit filter-branch将其移植到位。

答案 1 :(得分:1)

TL; DR :对于除了最简单的存储库之外的任何内容,您将永远无法完全保留git svn存储库中Subversion存储库的内容。

我正在调整my answer to a similar question

根据我的理解,您的Subversion树看起来像这样,其中*表示Subversion历史记录中某个位置的文件夹是工作副本的根目录:

/
|--branches_feature/
|  |--featureA/       *
|  |--userB/          *
|  |  |--featureB/    * (Possibly now deleted, but existed previously)
|  |  `--featureC/    *
|  `--userC/          *
|--branches_release/
|  |--V1.0/           *
|  `--V2.0/           *
`trunk/               *

可悲的是,git svn无法以特别合理的方式处理类似的存储库。你不会得到一个拥有你的Subversion存储库的所有分支的Git存储库,而不是它不应该有的。

您的选择因此是:

  • branches_featurebranches_feature/userB视为分支文件夹。

    你最终会得到一些Git分支,如果你要检查它们,会给你一堆文件夹,每个文件夹包含一个Subversion分支文件夹,对这些文件夹的git svn fetch操作可能需要更长时间,如需要为容器分支和真实分支完成提取。因为Git很聪明,它至少会占用极少的额外磁盘空间。

    我希望你的.git/config有如下所示的行:

    branches = branches_feature/*:refs/remotes/branches/*
    branches = branches_feature/userB/*:refs/remotes/branches/*
    branches = branches_release/*:refs/remotes/branches/*
    
  • 忽略一些分支文件夹。只是不要告诉git svn关于他们的事情,并继续快乐地无知。

  • 选择您感兴趣的分支机构,然后手动选择它们。如果你想要userB文件夹,你仍然需要注意你选择的历史记录,如果它的子分支已被删除而你不想拿起它们。

    在这里,我希望你的.git/config有如下所示的整行:

    fetch = branches_feature/featureA:refs/remotes/branches/featureA
    fetch = branches_feature/userB/featureB:refs/remotes/branches/featureB
    fetch = branches_feature/userC:refs/remotes/branches/userC
    
  • 修补您的git svn版本,以某种方式让它能够应对这种情况。如果你将它包含在未来的官方Git版本中,可以获得奖励积分。