git-subtree 的基本用法
Last updated
Last updated
变量说明:
$prefix
:子仓库在主仓库的路径
$sub_repo_name
:子仓库的别名
$remote_url
:子仓库的远程地址
$sub_repo_branch
:子仓库的推送/拉取分支,一般为 master
$sub_branch
:子仓库在主仓库中分离出来的分支,一般取子仓库所在的目录名
选项说明:
--squash
:“merge subtree changes as a single commit”;
使用前提:主/子仓库不能有待提交的 commit;
对 split
和 push
命令,必须在 --rejoin
下才能使用;
--rejoin
:“merge the new branch back into HEAD”
使用前提:主/子仓库不能有待提交的 commit;
效果:建立一个新的起点,避免从头开始遍历与子仓库相关的提交;
建议配合 --squash
一起使用;
如果长时间没有 --rejoin
,可能导致遍历时间过长,甚至超过内存上限导致奔溃;
--rejoin
的时候建议带上 --squash
,否则会导致所有与子仓库相关的 commit 都重新提交一次,进而污染 commit 日志;
关联子仓库与 git 地址(一般为空仓库):git remote add $name xxx.git
将子仓库提取到单独的分支:git subtree split --prefix=$prefix --branch $name --rejoin
推送子仓库代码:git subtree push --prefix=$prefix $name master --squash
推荐在每次 push 子仓库代码时,都
git subtree split --rejoin
一次; 因为当主项目的 commit 变多后,再推送子项目到远程库的时候,subtree 每次都要遍历很多 commit;解决方法就是使用 split 打点,作为下次遍历的起点。解决这个问题后就可以彻底抛弃
git submodule
了;
关联子仓库与 git 地址:git remote add $name xxx.git
设置子仓库路径(第一次执行时会自动拉取代码):git subtree add --prefix=$prefix $name master --squash
拉取子仓库代码:git subtree pull --prefix=$prefix $name master --squash
切断子仓库关联:git remote remove $name
删除子仓库:rm -r $prefix
How do I force a subtree push to overwrite remote changes? - Stack Overflow 使用场景:有时因为 rebase 等操作导致远程子仓库与本地不一致,而
git subtree push
并不支持--force
选项,导致推送失败;
命令:
不要对 git subtree split 产生的 commit 进行 rebase/merge 操作,会导致文件错乱!
git subtree split
时报 Merge with strategy ours failed.
完整命令:git subtree split --prefix=$prefix --branch $name --rejoin
原因:本地有文件还没提交;