【问题标题】:How can I import SVN with inconsistent branching structure into Git?如何将具有不一致分支结构的 SVN 导入 Git?
【发布时间】:2012-03-23 15:54:43
【问题描述】:

如果之前有人问过这个问题,我深表歉意,但我的情况是一个相对具体的问题。我在公司工作了一段时间并使用 SVN,但最近出于各种原因希望迁移到 Git。

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

据我所知,自从加入公司以来,我们使用一个主干分支,从中创建发布分支和功能分支。然而,这些分支的结构不仅仅是标准的主干/分支/标签结构。我们有几个用于不同类型分支的子文件夹。比如release分支放在branches_release中,特性分支放在branches_feature中等等,如下:

branches_feature/featureA
branches_release/2.0

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

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 回购历史是不够的,但我不确定如何修改配置的分支行以封装所有这些分支并且仍然正确使用新的分支格式。我一直在尝试以各种方式对其进行操作,但最终要么出错,要么尝试失败。

如果有人能提出一种在从 SVN 导入到 Git 时适当保留 SVN 存储库历史记录的好方法,我将不胜感激。

谢谢。

【问题讨论】:

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


    【解决方案1】:

    TL;DR:除了最琐碎的存储库之外,您永远无法将 Subversion 存储库的内容完全保留在 git svn 存储库中。

    我正在从 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 无法以特别明智的方式处理这样的存储库。你不会得到一个 Git 存储库,它包含你的 Subversion 存储库的所有分支,而没有它不应该有的分支。

    因此,您的选择是:

    • 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 版本中,将获得奖励积分。

    【讨论】:

    • 当然没有做任何 git svn 补丁(还)。我目前的计划是做一些类似branchs = branches_feature/{userA,userB}/*:refs/remotes/branches_feature/*的事情。 (就像您的第一个解决方案一样)我担心如果我使用这种方法,它是否会尝试创建两个分支,一个用于“userA”,一个用于“userA/feature”。考虑到这种不确定性,我有点害怕开始……哈哈。虽然我猜我最终还是得...
    • 就这样,它不会; svn-remote.branches 只为子目录创建分支。与branches = branches/*:refs/remotes/branches/* 的“标准”配置相比——那里没有一个名为“branches”的分支,每个子目录只有一个分支。
    • 另外,请随意尝试!如果您不喜欢结果,请从配置文件中删除相关行,并从 .git/logs/refs/remotes.git/refs/remotes.git/svn/refs/remotes 中删除要删除的文件/文件夹。
    • 好吧,我的意思是另外使用它。我需要为branchs_feature/* 和branchs_feature/{userA,userB}/* 做一个分支线。我想这有可能造成重复(某种)分支的不良情况。我真的需要一种方法来排除branchs_feature/{userA,userB},同时包括branchs_feature/{userA,userB}/*和branchs_feature/*。我想是时候开始试验了!
    • 我认为这是git svn 不支持的选项。可悲的是。不过,如果您找到了方法,请告诉我们!
    【解决方案2】:

    你当然可以处理这个,但你应该考虑与回报相比,你愿意付出多少努力。

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

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

    【讨论】:

    • 这里的问题是我正在尝试完全替换 SVN 存储库(如果可以的话)。对于个人工作流程,甚至对于目前的公司来说,发布分支和主干就足够了。但是,由于没有以前的历史记录,我们将无法杀死旧的 SVN 存储库。但是,我肯定不会将其排除在外。非常感谢。
    • 挺懂的,之前的migration都花了不少功夫,但是我几乎没用过。您可能会找到现有 repo 的 svn sync,压缩包(或使用 svnadmin dump 导出并压缩)并在某处备份以保护您的历史记录,而无需随身携带所有功能分支包袱。您的另一个选择是像@me_and 建议的那样单独提取您需要的功能分支。要记住的主要事情 - SVN 不会去任何地方,所以只要你做一个备份,你总是可以在以后返回你需要的导入。
    • 是的,对于我自己来说,我不太关心(旧)历史。我试图说服我的公司从 SVN 切换到 Git,我觉得对他们来说更大的问题是从现在开始分割历史。能够适当地构建历史只会让我的论点更容易一些。经理不会让事情变得比他们必须的更容易(或更简单),有时……哈哈。
    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多