当前位置:   article > 正文

git subtree

git subtree

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

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

前言

目前对 git 仓库拆分的已有实现之一。这里 git subtree 并不是 subtree merge strategy,这两个不是一个东西。


准备工作

  1. 首先创建主仓库 subrepo-master,随意提交一次文本,接着拉取到本地

  2. 建立子仓库 subrepo,随意提交一次文本,同时准备多个分支进行任意提交备用。


操作

  1. 运行 git remote add subtree1 <url> 添加子仓库链接

  2. 添加子仓库 git subtree add --prefix=subtree/subtree1 subtree1 master,这里的 prefix 指向的是本地存放子仓库的目录, subtree1 是第一步添加的远端链接 ,master 是远端分支。添加完成后,就得到了第一个子仓库。

  3. 运行 git status 会发现没有本地修改,接着运行 git log,会发现多了一次提交信息,看起来 git subtree 在添加的时候会自动提交一次,现在可以选择把提交推送到远端。

    1. commit 6cd935426f68cd670d50a7fb02065af9a0cded19 Merge: fbc33ec afdc5bf Add 'subtree/subtree1/' from commit 'afdc5bf559beacb08032e23d22a2beaa65d3ca9c'
    2. git-subtree-dir: subtree/subtree1
    3. git-subtree-mainline: fbc33ec2739057789595c13d2313b87848bf25c0
    4. git-subtree-split: afdc5bf559beacb08032e23d22a2beaa65d3ca9c复制代码
  4. 接着会做一些操作,模拟各种情况,如主仓库子仓库修改推送、子仓库远端拉取合并等。

  5. 主仓库子仓库修改推送到远端

    首先对主仓库子仓库的文件做一些修改并本地提交(记住提交的 message),接着可以直接推送到远端。观察远端主仓库会发现修改顺利提交,subrepo 没有发生改变,这时候就可以体会出一点 subtree 的设计了。如果想推送子仓库,需要使用命令 git subtree push --prefix=subtree/subtree1 subtree1 master。再次观察远端,会发现修改被推送上去了,而且 message 一致。当然你可以选择不推送到 master 分支,随意找一个 git subtree push --prefix=subtree/subtree1 subtree1 master2 也是可以的。观察远端会发现多出一个 master2 分支。

  6. 远端子仓库有修改

    对远端子仓库修改。然后拉取此次提交合并到主仓库。运行此命令拉取即可 git subtree pull --prefix=subtree/subtree1 subtree1 master2,这时候如果有冲突,就需要解决冲突,分别推送主仓库子仓库。然后观察远端仓库,会发现主仓库、子仓库都有了提交以及解决冲突的操作。

  7. 远端子仓库做了大量提交

    希望从远端拉取合并到主仓库 git subtree pull --prefix=subtree/subtree1 subtree1 master2,再运行 git log 然后会发现主仓库的提交日志多了很多,是子仓库的提交日志 + 1 条,如果不希望子仓库污染主仓库的提交日志,可以使用 --squash 这个命令。git subtree pull --prefix=subtree/subtree1 subtree1 master2 --squash,就得到干净了日志了(一次是 squash 整理的提交,一次是合并),但是合并的时候有冲突需要解决。

  8. 本地子仓库合并远端子仓库 branch、tag、commitid

    如果分支没有在本地拉取,则需要先 git fetch subtree1,接着再

    1. git subtree merge --prefix=subtree/subtree1 subtree1/a
    2. // or
    3. git subtree merge --prefix=subtree/subtree1 v2.0
    4. // or
    5. git subtree merge --prefix=subtree/subtree1 e1e9aef94c0ce5ede4716d3c1e48cc58c15b7ffe复制代码
  9. 本地子仓库改变分支

    可以通过 git subtree pull --prefix=subtree/subtree1 subtree1 b 的方式,但是方式的缺点显而易见,需要手工再次合并代码等等。还有另一种方案,先删去目录,然后重新添加进来。


技巧

  1. 命令表

    1. git subtree add -P <prefix> <commit>
    2. git subtree add -P <prefix> <repository> <ref>
    3. git subtree pull -P <prefix> <repository> <ref>
    4. git subtree push -P <prefix> <repository> <ref>
    5. git subtree merge -P <prefix> <commit>
    6. git subtree split -P <prefix> [OPTIONS] [<commit>]复制代码
  2. 如果想要历史记录干净一点,可以使用 --squash,可用于 add, merge, push, pull 命令。但是加了 --squash 也有自己的问题,上面已做描述,这个最好一开始就统一使用一种。当然有人也有解决方案 stackoverflow.com/questions/9…


缺点

  1. 合并策略的学习成本

  2. 返回历史版本稍显复杂

  3. 不要混合提交主仓库、子仓库代码

  4. 将子仓库推送到远端很慢,相当于对主仓库下某个子仓库的目录的提交记录进行分割,以找出子仓库的修改,这个过程有点慢,如果推送周期比较长倒是可以尝试。

  5. 需要添加多个远端,子仓库和远端没有地方存储映射关系。由命令 git subtree pull --prefix=subtree/subtree1 subtree1 master2 可以看出来,可以推送子仓库的代码到任意能推送的地方。

  6. 改子仓库的分支略坑


优点

  1. 拷贝主仓库后,可以直接使用

  2. 使用者可以不关注子树依赖,对使用者无感知,不需要子仓库权限

  3. 子树不像子模块会添加多余的文件,对仓库无污染

  4. 对子仓库的同步可交由单独的维护者


参考

  1. github.com/git/git/blo…

  2. developer.atlassian.com/blog/2015/0…

  3. www.atlassian.com/blog/git/al…

  4. medium.com/@porteneuve…


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

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


相关文章:
【推荐】 BRVAH(让RecyclerView变得更高效) (2)
【推荐】 内容社交产品中的关键数据——获得良好反馈的用户比例


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/861293
推荐阅读
相关标签
  

闽ICP备14008679号