历史
使用 git svn 可以为所有提到的方法保留历史记录:http: //git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git
甚至可以切换回以前的提交。
但是,有人建议不要保留历史记录,只需将 svn 存储库冻结大约 6 个月,而所有历史记录都会在 git 存储库中更改。我不同意这样的建议,因为历史对我们的项目至关重要。我敢打赌没有人接受这样的解决方案。
巨型树干方法
- 您必须克隆整个大树,即使您只计划处理一个子目录(主要用例)
- 一些 git 命令会很慢(例如:git status,因为它需要检查整个树)
- 即使您将 jenkins 调整为仅针对 repo 的特定部分触发构建(这可以使用 jenkins git 插件的“include”属性来完成)。仍然需要拉取所有 repo 来执行构建。这几乎不会影响所有的工作,因为即使是构建小模块,“干净”的结账也会花费很多时间。
关注点:整个团队有 200 多名开发人员和质量保证人员,我怀疑最终推动更改会很困难。
- 只有在 gerrit 审核通过并通过测试后,才会将更改推送到 master 分支,因此我们不会有持续的 pull-push-fail-pull-push 流程
- 但是,如果主分支在提交被推送到 gerrit 后发生更改,则 gerrit 可能会拒绝合并,它将需要单击“rebase”按钮并重新运行测试。
- Linux 内核有单体 repo,因为 c/c++ 没有像 java 那样的依赖管理:构建一个内核 tar 像战争与 jar 依赖不是这种情况。
测验
使用这种方法迁移的步骤、成本和总成本是什么?
- git svn clone SVN_URL REPO_NAME
- 詹金斯的东西
它如何支持代码门控?从 VCS / 工具的角度来看,需要进行哪些更改?在这里假设完整的 CI 运行需要 15 分钟。
- Jenkins 应该在 scm 触发器中包含“包含”过滤器,以过滤项目特定部分的更改。并不难,但仍然需要一些努力来设置和验证它们。在“构建前擦除工作空间”构建的情况下,应该一直克隆整个 repo。它可以增加从提交到“测试批准”的总体时间,因为结帐会很慢。
什么是高效的开发人员工作流程?
- 开发人员使用本地/远程功能分支
- 将更改推送到 gerrit
- Gerrit 根据测试验证更改
- 更改合并到主分支
子模块
此处解释了大多数警告http://git-scm.com/book/en/Git-Tools-Submodules和此处http://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use -git子模块/
主要问题是您将不得不提交两次
- 子模块本身
- 聚合回购 - 更新子模块没有意义。如果依赖项是通过工件存储库管理的,为什么还需要聚合存储库?
实际上,子模块是为存在可以在不同项目中重用的库的情况下创建的,但是您希望依赖库的特定标签以能够在将来更新参考。但是,我们不会标记每个提交(仅在每次提交后发布),并且在战争中更改依赖项版本(到已发布的版本)将比维护子模块方法更容易。Java 依赖管理使事情变得更简单。
不建议指向子模块头部,会导致子模块出现问题,因此这种方法对于快照来说是死路一条。再一次,我们不需要它,因为 java 依赖管理将为我们做所有事情。
测验
使用这种方法迁移的步骤、成本和总成本是什么?
- git svn clone 每个模块的 SVN_URL REPO_NAME
- 创建聚合 git repo
- 将模块存储库作为子模块添加到聚合存储库
它如何支持代码门控?从 VCS / 工具的角度来看,需要进行哪些更改?在这里假设完整的 CI 运行需要 15 分钟。
- Gerrit 支持合并和提交子模块,所以应该没问题。
- Jenkins 的东西 - 触发子模块更改和聚合 repo 更改(啊!在两个地方没有意义!)
什么是高效的开发人员工作流程?(省略Gerrit进程)
- 开发人员提交到子模块
- 标记他的提交
- 开发人员进入聚合回购
- cd 进入子模块,结帐标签
- 提交具有更改的子模块哈希的聚合 repo
或者
- 开发者更改子模块
- 将更改推送到子模块以不丢失更改
- 提交具有更改的子模块哈希的聚合 repo
如您所见,开发人员的工作流程很麻烦(需要始终更新两个位置)并且不适合我们的需求。
子树
主要问题是您必须提交两次树合并子目录将更改推送到原始仓库
子树是子模块的更好替代方案,它更健壮,并且将子模块的源代码合并到聚合 repo 而不是仅仅引用它。维护这样的聚合存储库使事情变得更简单,但是子树的问题与子模块的问题相同,进行双重提交是完全没用的。您不必被迫提交对原始模块 repo 的更改,并且可以通过聚合 repo 提交它,这可能导致 repos 之间的不一致......
这些差异在这里得到了很好的解释:http: //blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
测验
使用这种方法迁移的步骤、成本和总成本是什么?
- git svn clone 每个模块的 SVN_URL REPO_NAME
- 创建聚合存储库
- 对每个模块执行子树合并
它如何支持代码门控?从 VCS / 工具的角度来看,需要进行哪些更改?在这里假设完整的 CI 运行需要 15 分钟。
什么是高效的开发人员工作流程?(省略Gerrit进程)
- 开发人员更改子树中的某些内容(在聚合存储库中)
- 开发人员提交聚合回购
- 开发人员不会忘记将更改推送到原始仓库(没有意义!)
- 开发人员不要忘记在一次提交中不要将子树更改与聚合 repo 更改混合
再次像子模块一样,有两个地方(repo)存在代码/更改是没有意义的。不适合我们的情况。
单独的回购
单独的 repos 看起来是一个最好的解决方案,并遵循原始的 git 意图。回购的粒度可能会有所不同。最细粒度的情况是每个 maven 发布组都有一个 repo,但是它可能导致太多的 repo。我们还需要考虑一个特定的 svn 提交影响多个模块或发布组的频率。如果我们看到,该提交通常会影响 3-4 个发布组,那么这些组应该形成一个 repo。
我也相信至少将 api 模块与实现模块分开是值得的。
测验
使用这种方法迁移的步骤、成本和总成本是什么?
- git svn clone SVN_URL REPO_NAME 为每个或多或少的细粒度模块数
它如何支持代码门控?从 VCS / 工具的角度来看,需要进行哪些更改?在这里假设完整的 CI 运行需要 15 分钟。
- Jenkins 分别为每个 repo 触发。没有“包含”过滤器。只需签出、构建、部署。
什么是高效的开发人员工作流程?
- 开发人员为每个 repo 使用本地/远程功能分支
- 将更改推送到 gerrit
- Gerrit 根据测试验证更改
- 更改合并到主分支