略删改。
对于处理子项目,即Git仓库包含Git仓库的情况:Git一开始引入了submodule功能,后面Git在1.8.0版本引入了git subtree这个命令,它使用Git的subtree merge
策略来得到类似git submodule
的结果。但本质上,它是将子项目的代码全部merge
进父项目。使用git subtree,你不仅可以将其他项目合并为父项目的一个子目录,而且可以从父项目提取某个子目录的全部历史作为一个单独的项目。
我看到还有不少人在使用submodule,不过操作这玩意有点复杂,既然有了高级的,就学习和使用高级点的。
添加子项目
将一个已存在的Git仓库以Subtree方式添加为子项目可以使用git subtree add --prefix=<prefix> <repository> <ref>
命令,其中--prefix
选项指定了子项目对应的子目录,--squash
选项用以压缩Subtree的提交为一个,这样父项目的历史记录里就不会出现子项目完整的历史记录。我们还是以Hexo博客添加Hacker主题为例:
$ git clone /private/tmp/remote/feilongwang.org.git
Cloning into 'feilongwang.org'...
done.
$ cd feilongwang.org/
$ git subtree add --prefix=themes/Hacker /private/tmp/remote/Hacker.git master --squash
git fetch /private/tmp/remote/Hacker.git master
warning: no common commits
remote: Counting objects: 216, done.
remote: Compressing objects: 100% (143/143), done.
remote: Total 216 (delta 70), reused 216 (delta 70)
Receiving objects: 100% (216/216), 56.22 KiB | 0 bytes/s, done.
Resolving deltas: 100% (70/70), done.
From /private/tmp/remote/Hacker
* branch master -> FETCH_HEAD
Added dir 'themes/Hacker'
更新子项目
一段时间之后,子项目可能有大量新的代码,父项目也想使用这些代码。此时父项目的维护者只需执行:
$ git subtree pull --prefix=themes/Hacker /private/tmp/remote/Hacker.git master --squash
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From /private/tmp/remote/Hacker
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
themes/Hacker/README.md | 2 +-
themes/Hacker/layout/components/footer.ejs | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
就可以将父项目中子项目对应目录里的内容更新为子项目最新的代码了。
如果你觉得每次都输入子项目完整的仓库url太麻烦,你也可以将子项目添加为追踪的仓库。
$ git remote add hacker /private/tmp/remote/Hacker.git
$ git subtree add --prefix=themes/Hacker hacker master --squash
git fetch hacker master
From /private/tmp/remote/Hacker
* branch master -> FETCH_HEAD
* [new branch] master -> hacker/master
Added dir 'themes/Hacker'
提交子项目
如果我们在使用子项目的过程中,对子项目做了一些改动,同时我们又希望子项目的其他使用者也能共享这些改动,此时可以将我们的改动提交到子项目的远程仓库中。
$ git subtree push --prefix=themes/Hacker /private/tmp/remote/Hacker.git master
git push using: /private/tmp/remote/Hacker.git master
Counting objects: 301, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (211/211), done.
Writing objects: 100% (301/301), 579.91 KiB | 0 bytes/s, done.
Total 301 (delta 67), reused 292 (delta 64)
remote: Resolving deltas: 100% (67/67), completed with 2 local objects.
To /private/tmp/remote/Hacker.git
96ca04b..5565513 556551375034489fc8710070a29a2f22240a39b3 -> master
提取子项目
当我们开发一个项目若干时间后,希望将某个目录单独出一个项目来开发,同时又保留这部分代码历史提交记录,使用git subtree split
可以很轻松的完成这个操作。以Hexo博客分离Hacker主题为例:
$ git subtree split --prefix=themes/Hacker --branch hacker
Created branch 'hacker'
843147f3181399b06528251451bc498e01425f34
$ git branch -a
hacker
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
$ git checkout hacker
Switched to branch 'hacker'
$ git log
commit 843147f3181399b06528251451bc498e01425f34
Author: Feilong Wang <i@feilongwang.org>
Date: Mon Sep 19 01:16:02 2016 +0800
Change theme to Hacker
其中--branch
指定将生成的历史提交记录保存到一个新的分支。
作者:feil0n9wan9
链接:https://www.jianshu.com/p/284ded3d191b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。