git 仓库拆分方案对比

勿忘初心2018-11-07 10:00

此文已由作者张磊授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

前言

git 拆分仓库在网上已有的案例上来看,分为 submodule 和 subtree。 还有基于这两个方案进行改进的 subrepo、git-repo 等,当然还可以使用 npm 去管理。


准备工作

  1. 可以先阅读之前的 submodule 、 subtree 以及 subrepo 的文章

  2. git-repo 可以阅读 https://code.google.com/archive/p/git-repo/ 和https://source.android.com/source/developing 以及网上其他内容

  3. https://www.atlassian.com/blog/git/git-project-dependencies 这里推荐了很多工具。


仓库拆分

无论是最终使用哪种方式,首先是要把代码拆开放到新仓库里。


  • 方案1:手工强拆

    把目录的代码备份,然后从主仓库删除,再将代码上传到新建的子仓库,问题在于提交历史去丢失,这个问题很严重,以后找背锅的人都难 :(。

  • 方案2:git subtree split

    使用 git subtree split -P path/to/module -b branchName,注意 branchName 不要重名,如果历史记录多的话这个比较慢,看起来是检索历史提交记录,抓出符合条件(某个文件夹下)的提交日志,具体可以查看说明文档,支持并行。这种做法主仓库的历史记录还保留提交。

  • 方案3:filter-branch

    这个命令本质上是重写提交,但是反过来想一想,如果你把指定目录之外的文件都删除了,那不就是得到一个干净的子仓库了? git filter-branch -f --prune-empty --subdirectory-filter  path/to/module。这在文件被添加的时候才会开始遍历,这样在某些情况下就比 方案2 快很多,不支持并行。

    使用举例:比如说历史记录中提交某个网站的帐号密码,又过了很多提交才发现,希望删除掉,就可以使用这个方案。这种做法也会让历史记录变的干净。


看起来方案3好用很多。


方案选择

  1. submodule 在代码频繁更新的时候,需要处理的冲突会比较多,而且一开始会比较迷惑,实际上还算简单。但是在频繁的冲突处理的过程中,无疑增大了时间消耗。submodule 本质上是子仓库自身做修改推送合并,而主仓库获取的是子仓库的最新的 commitid,对子仓库的更新仅仅是更新其 commitid。

  2. subtree 可以向正常使用 git 仓库一样操作子仓库,成员感知不到子仓库的存在,复杂度被隐藏在了维护主仓库和子仓库的同步的人那里。

  3. subrepo 需要安装相关程序,且还在发展中,虽然解决了一些 submodule 和 subtree 的问题。

  4. npm 在只是引用仓库的情况下,不失为是一种好办法,但是实际上更改频率会很高,故不考虑。

  5. git-repo 增加了学习成本,需要学习 repo 的用法,同时需要寻找安装  Windows 版本的方法,以及用于管理 Android 项目,看完官网说明就准备舍弃这个方案了。


参考

  1. https://services.github.com/on-demand/downloads/submodule-vs-subtree-cheat-sheet/

  2. https://stackoverflow.com/questions/359424/detach-move-subdirectory-into-separate-git-repository


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击


相关文章:
【推荐】 改进网易云音乐的“音乐社交”构想
【推荐】 移动端爬虫工具与方法介绍
【推荐】 数据采集与分析的那些事——从数据埋点到AB测试