1、基本介紹:
- 當項目比較大的時候便于復用,或者多個項目共用module。這個時候需要抽取項目公共模塊,而且現在基本是使用git作為版本控制工具,這樣就變成App Project 有多個module,每個module都是一個獨立的git repository。而且我們希望單個的module都可以獨立維護,可以更方便查看和隨時隨地同步更新。
- 為了達成這樣的目的我們可以使用git-submodule、git-repo 、gitslave 、git-subtree。
- git-repo更適合管理比較大、module比較多、module會經常變更的項目,Android源碼就是采用這種方式管理。如果module比較少的情況,使用git-submodule完全夠用。
2、使用步驟:
-
進入到主項目根目錄中輸入命令:
-
git submodule add <子module的git地址>
: 從遠程倉庫將子module導入到該項目中,這時候會自動生成.gitmodules文件
。
-
git submodule add <子module的git地址> <主項目內的文件夾>
: 從遠程倉庫將子module導入到該項目中的特定文件夾中。
-
git submodule init
:初始化本地.gitmodules文件。
-
git submodule update
:在父項目中更新子module的修改。
-
git submodule foreach git pull
:拉取所有子模塊。
-
git submodule foreach git submodule update
:如果你的submodule又依賴了submodule,可以使用git submodule foreach
命令來實現一次性全更新。
-
git clone --recurse-submodules <主項目倉庫地址>
:獲取主項目和所有子項目源碼【git pull <主項目倉庫地址>
的時候不會同時獲取submodules的源碼】。
-
進入到子module目錄中輸入命令:
- 走正常的git add、git commit、git push流程。
3、注意點:
3.1、更新 submodule 的坑:
- 在父項目中
git pull
只會更新父項目中的代碼,并不會更新子module項目中的代碼,這時忘記了調用 git submodule update
,那么git push
極有可能再次把舊的 submodule 依賴信息提交上去。
-
git pull
之后,立即執行 git status
, 如果發現 submodule 有修改,立即執行 git submodule update
。
- 如果你的 submodule 又依賴了 submodule,那么很可能你需要在
git pull
和 git submodule update
之后,再分別到每個 submodule 中再執行一次 git submodule update
,這里可以使用 git submodule foreach git submodule update
命令來實現。
3.2、修改 submodule 的坑:
- 默認
git submodule update
并不會將 submodule 切到任何 branch,所以,默認下 submodule 的 HEAD 是處于游離狀態的 (‘detached HEAD’ state)。所以在修改前,記得一定要用 git checkout master
將當前的 submodule 分支切換到 master,然后才能做修改和提交。
- 如果你不慎忘記切換到 master 分支,又做了提交,可以用 cherry-pick 命令挽救。具體做法如下:
- 用
git checkout master
將 HEAD 從游離狀態切換到 master 分支 , 這時候,git 會報 Warning 說有一個提交沒有在 branch 上,記住這個提交的 change-id(假如 change-id 為 aaaa)。
- 用
git cherry-pick aaaa
來將剛剛的提交作用在 master 分支上。
- 用
git push
將更新提交到遠程版本庫中。
3.3、刪除 submodule 的坑:
- 直接刪除子模塊并不能完全刪除,再次添加的時候會報錯
'<submodule子項目名字>' already exists in the index.
- 用以下命令可以完全刪除submodule:
git rm --cached <submodule子項目名字>
rm -rf <submodule子項目名字>
參考:http://blog.devtang.com/2013/05/08/git-submodule-issues/