从svn迁移到git.哪个选项最好:巨型主干,子模块,子树

Vad*_*huk 7 svn migration git

我知道有很多关于同样的问题,但我仍然需要更多的信息.我正在研究将我们的SVN repo迁移到git并试图了解什么方法(整体主干,子模块,子树等)对我们的回购最好的可能性.

以下是有关我们的项目和SVN存储库的一些信息:

  • 项目是java web应用程序打包的战争.
  • 它是模块化应用程序.每个模块由独立团队开发,然后打包为jar.
  • 战争取决于这个罐子.

基本上我们的结构看起来像:

repo
|-application(war)
|-module1 (for example, ui stuff)
|--module1Submodule1
|--module1Submodule2
|-module2 (for example, database access stuff)
|-...
Run Code Online (Sandbox Code Playgroud)

每个模块都有自己的标签和分支.

我的本地机器上的svn repo的大小包括所有分支,标签等:

  • 超过250万个文件
  • 超过20Gb的空间
  • 有311615个修订版
  • 文件主要是源代码,没有大的二进制对象

典型用例:

  • 整个团队200+开发和QA
  • 不同的团队承诺他们的模块/子模块.(这可能是monolith git repo的一个问题,因为git需要在推送之前提取所有更改,svn警告只有过时的更改)
  • 分支模块
  • 分行申请

未来的用例:

  • 格里特
  • 开发人员提交,提交审核,测试针对提交运行,如果是绿色,则提交被批准合并到"主"分支

问题是:

  1. 我们是否可以将这样的回购视为一个大的git(我的意思是有很多帖子注意到git在大型回购中的规模很大,但是什么是'大'?)
  2. 每种方法的优缺点是什么:
    • Monolith repo(只是git as svn,anti-pattern?)
    • 子模块
    • 子树(我是对的,模块中的每个更改都需要在子树repo中提交,然后将更改拉到聚合子树repo?)
    • 每个模块的单独回购
    • 任何其他..
  3. 可以为每个人保留SVN的历史记录吗?
  4. 我需要尽可能多的链接(我没有找到'缓慢的大型回购'的官方链接)

先感谢您!

Vad*_*huk 7

历史

使用git svn可以为所有提到的方法保留历史记录:http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git 甚至可以切换回以前的提交.

但是,有人建议不要保存历史记录,只需将svn存储库冻结约6个月,而所有历史记录都会在git repo中发生变化.我不同意这些建议,因为历史对我们的项目至关重要.我打赌没有人接受这样的解决方案.

巨树干进场

  • 你必须克隆整个大树,即使你只计划在一个子目录上工作(主要用例)
  • 一些git命令会很慢(例如:git status,因为它需要检查整个树)
  • 即使你调整jenkins只触发repo的特定部分的构建(这可以使用jenkins git插件的"include"属性来完成).仍然需要拉动所有仓库来执行构建.这几乎不会对所有工作产生影响,因为即使是构建小模块,"干净"结账也需要很长时间.

关注:在整个团队中拥有200多个Dev和QA,我怀疑最终推动变革会非常不安.

  • 只有在对gerrit进行审核并且测试通过后才会将更改推送到主分支,因此我们不会持续推送 - 推 - 失 - 拉 - 推
  • 然而,如果由于提交被推送到gerrit而改变了master分支,gerrit可以拒绝合并,它将需要单击"rebase"按钮并重新运行测试.
  • Linux内核有monolith repo,因为c/c ++没有像java这样的依赖管理:构建一个像jar依赖的战争的内核tar并非如此.

测验

使用这种方法迁移的步骤,成本和总成本是多少?

  • git svn clone SVN_URL REPO_NAME
  • 詹金斯的东西

它如何支持代码选通?从VCS /工具的角度来看,需要进行哪些更改?假设完整的CI运行需要15分钟.

  • Jenkins应该在scm触发器中使用"include"过滤器来过滤项目特定部分的更改.不是那么难,但仍需要一些努力来设置和验证它们.如果"在构建之前擦除工作空间"构建,则应始终克隆整个存储库.它可以增加从提交到"通过测试批准"的总时间,因为结账将非常缓慢.

什么是高效的开发人员工作流程

  • 开发人员使用本地/远程功能分支
  • 推动变革
  • Gerrit验证对测试的更改
  • 更改合并到主分支

子模块

大多数警告在这里解释http://git-scm.com/book/en/Git-Tools-Submoduleshttp://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use -git-子模块/

主要问题是你必须提交两次

  • 子模块本身
  • 聚合repo - 更新子模块没有意义.如果通过工件repo管理依赖项,为什么需要聚合repo?

实际上,当存在可以与不同项目重用的库时创建的子模块,但是您希望依赖于库的特定标记以及将来更新引用的能力.但是,我们不打算标记每个提交(仅在每次提交后发布),并且在战争中更改依赖关系版本(对于已发布的提交)将比维护子模块方法更容易.Java依赖关系管理使事情变得更简单.

不建议指向子模块头并导致子模块出现问题,因此这种方法对于转到快照来说是死路一条.而且我们不再需要它,因为java依赖管理将为我们做所有事情.

测验 使用这种方法,迁移的步骤,成本和总成本是多少?

  • 每个模块的git svn clone SVN_URL REPO_NAME
  • 创建聚合git repo
  • 将模块存储库添加为子模块以聚合repo

它如何支持代码选通?从VCS /工具的角度来看,需要进行哪些更改?假设完整的CI运行需要15分钟.

  • Gerrit支持对子模块的合并和提交,所以它应该没问题.
  • Jenkins的东西 - 在子模块上触发更改并聚合repo更改(唉!在两个地方都没有意义!)

什么是高效的开发人员工作流程 (Gerrit过程被忽略)

  • 开发人员承诺进入子模块
  • 制作他的提交标签
  • 开发人员进入聚合回购
  • cd进入子模块,检查标签
  • 使用更改的子模块哈希提交聚合repo

要么

  • 开发人员更改子模块
  • 将更改推送到子模块以不丢失更改
  • 使用更改的子模块哈希提交聚合repo

如您所见,开发人员工作流程很麻烦(需要始终更新两个地方),并且不适合我们的需求.

子树

主要问题是您必须提交两次To tree merged子目录将更改推送到原始repo

子树是子模块的更好替代品,它更强大,并且将子模块的源代码合并到聚合repo而不是仅仅引用它.它使得维护这样的聚合repo变得更简单,但是子树的问题与子模块的问题相同,使得双重提交完全没用.您不必被迫对原始模块仓库进行更改,并且可以使用聚合仓库进行更改,这可能导致仓库之间的不一致...

这里的差异很好解释:http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/

测验 使用这种方法,迁移的步骤,成本和总成本是多少?

  • 每个模块的git svn clone SVN_URL REPO_NAME
  • 创建聚合回购
  • 为每个模块执行子树合并

它如何支持代码选通?从VCS /工具的角度来看,需要进行哪些更改?假设完整的CI运行需要15分钟.

  • 看起来Gerrit支持子树合并不是很好(https://www.google.com/#q=Gerrit+subtrees)
  • 但我们不能确定直到尝试
  • 詹金斯的东西.触发子树复制并聚合repo更改(唉!两个地方都没有意义!)

什么是高效的开发人员工作流程 (Gerrit过程被忽略)

  • 开发人员更改子树中的内容(内部聚合仓库)
  • 开发人员提交聚合回购
  • 开发人员不会忘记将更改推送到原始仓库(没有意义!)
  • 开发人员不会忘记在一次提交中不将子树更改与聚合repo更改混合在一起

与子模块一样,有两个地方(repoes)存在代码/更改是没有意义的.不适合我们的情况.

单独的回购

单独的回购看起来像是一个最好的解决方案,并遵循原始的git内涵.复制的粒度可以变化.最细粒度的情况是每个maven发布组都有repo,但是它可能会导致太多的回购.此外,我们需要考虑一个特定的svn提交对多个模块或发布组的影响.如果我们看到,该提交通常会影响3-4个发布组,那么这些组应该形成一个repo.

另外我认为至少将api模块与实现模块分开是值得的.

测验 使用这种方法,迁移的步骤,成本和总成本是多少?

  • git svn clone SVN_URL REPO_NAME,用于每个或多或少细粒度的模块

它如何支持代码选通?从VCS /工具的角度来看,需要进行哪些更改?假设完整的CI运行需要15分钟.

  • 詹金斯分别触发了每个回购.没有'包含'过滤器.只需结账,构建,部署.

什么是高效的开发人员工作流程

  • 开发人员为每个仓库使用本地/远程功能分支
  • 推动变革
  • Gerrit验证对测试的更改
  • 更改合并到主分支