Subtree 与 Submodule
Last updated
Last updated
subtree 和 submodule 的目的都是用于 git 子仓库管理,二者的主要区别在于,subtree 属于拷贝子仓库,而 submodule 属于引用子仓库。
subtree 在操作时,命令行较长,可以使用 remote 配置简化,例如
假如在执行 git submodule update 时出现以下类似错误信息:
发生错误的原因是,centos-config 子仓库在某电脑 A 的「本地」commit 了新的版本 「f869da471c5d8a185cd110bbe4842d6757b002f5」,且该次 commit 未 push origin。但其父级仓库中引用了该子仓库的版本号,且将引用记录 push origin,导致其他用户无法 update 。
解决方案是,在电脑 A 上将子仓库 push origin 后,在其他客户机上执行 git submodule update 。或者使用 git reset,将子仓库的引用版本号还原成 origin 上存在的最新版本号。
维度
subtree
submodule
优劣对比
空间占用
subtree 在初始化 add 时,会将子仓库 copy 到父仓库中,并产生至少一次 merge 记录。所以会占用大量父仓库空间
submodule 在初始化 add 时,会在父仓库新建一个 .gitmodules 文件,用于保存子仓库的 commit hash 引用。所以不会占用父仓库空间
submodule 更优
clone
subtree add 至父仓库之后,后续的 clone 操作与单一仓库操作相同
后续 clone 时 submodule 还需要 init/update 操作,且 submodule 子仓库有自己的分支
subtree 更优
update
子仓库更新后,父仓库需要 subtree pull 操作,且命令行略长,需要指定 --prefix 参数。由于无法感知子仓库的存在,可能会产生 merge 冲突需要处理
子仓库更新后,父仓库需要 submodule update 操作。父仓库只需变动子仓库 hash 引用,不会出现冲突
submodule 更优
commit
父仓库直接提交父子仓库目录里的变动。若修改了子仓库的文件,则需要执行 subtree push
父子仓库的变动需要单独分别提交。且注意先提交子仓库再提交父仓库
subtree 更优