git submodule允許其他的倉庫指定以一個commit嵌入倉庫的子目錄。
git subtree替代git submodule命令,合並子倉庫到項目中的子目錄。不用像submodule那樣每次子項目修改了后要init和update.萬一哪次沒update就直接"commit -a" 或者 "add ." 全commit上去就悲劇了。
git subtree雖然比git submodule更好用,但也不是特別完美的解決方案,使用時一定要特別注意。
git-subtree參考文檔:https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt
使用語法
'git subtree' add -P <prefix> <commit> 'git subtree' add -P <prefix> <repository> <ref> 'git subtree' pull -P <prefix> <repository> <ref> 'git subtree' push -P <prefix> <repository> <ref> 'git subtree' merge -P <prefix> <commit> 'git subtree' split -P <prefix> [OPTIONS] [<commit>]
-q | --quiet -d | --debug -P <prefix> | --prefix=<prefix> 引用庫對應的本地目錄 -m <message> | --message=<message> 適用於add/pull/merge子命令。設置產生的合並提交的說明文本 --squash 適用於add/pull/merge子命令。先合並引用庫的更新記錄,將合並結果並到主項目中。 使用此選項時,subtree add/pull會產生兩個提交版本:一個是子項目的歷史記錄,一個是Merge操作。好處是可以讓主項目歷史記錄很規整,缺點是子項目更新時常常需要解決沖突。一個更好的解決方案是:單獨建一個分支進行--no-squash的subtree更新,然后再--squash合並到主分支。每次在此分支做操作前都需要先把主分支合並進來。參考:http://www.fwolf.com/blog/post/246
split子命令選項:
--annotate=<annotation> 創建合成歷史時有可能形成內容不同但提交信息完全相同的提交版本,使用這個選項在每個提交消息前加上此前綴用來區分。
-b <branch> | --branch=<branch> 創建合成的提交歷史時,創建此參數指定的新分支包含生成的合成歷史。<branch>必須是還不存在的。
--onto=<onto>
--rejoin
--ignore-joins
更多的內容參考前面的文檔鏈接。
git subtree用法簡單示例
引用外部庫到項目子目錄
git subtree add --prefix=Vendor/AFNetworking --squash http://demorepo.com/AFNetworking/AFNetworking.git master 或 git remote add -f librepo ../lib-rep #-f:遠端庫添加后立即執行fetch操作 git subtree add -P lib librepo master
提取引用庫的修改到新分支
git subtree split --prefix=Vendro/AFNetworking/ --branch AFNetworking #提取與引用庫子目錄相關的變更並生成一個新的合成歷史到新分支
推送引用庫分支到引用庫遠端
git push git@github.com:kvnsmth/AFNetworking.git AFNetworking:critical-bug-fix 或 git subtree push -P lib librepo master
拉取引用庫的最新代碼
git subtree pull --prefix=Vendor/AFNetworking --squash git@github.com:AFNetworking/AFNetworking.git master
或
git subtree pull -P lib librepo master
git-subtree不能處理快進(Fast-forward),快進的情況也會誤報沖突,還需要手動解決沖突