git submodule 使用小結
原文鏈接 http://blog.gezhiqiang.com/2017/03/08/git-submodule/######
Git Submodule 允許一個git倉庫,作為另一個git倉庫的子目錄,並且保持父項目和子項目相互獨立。
添加子倉庫
$ git submodule add <倉庫地址> <本地路徑>
新建一個父倉庫main,一個子倉庫sub。將父倉庫克隆到本地。
$ git clone ssh://git@10.2.237.56:23/dennis/main.git
進入父倉庫,並添加子倉庫。
$ git submodule add ssh://git@10.2.237.56:23/dennis/sub.git lib
添加成功后,在父倉庫根目錄增加了.gitmodule文件。
[submodule "sub"] path = lib url = ssh://git@10.2.237.56:23/dennis/sub.git
並且在父倉庫的git 配置文件中加入了submodule段。
$ cat .git/config // 加了submodule段 [submodule "sub"] url = ssh://git@10.2.237.56:23/dennis/sub.git
注意:添加子倉庫之后,主倉庫的對應目錄下(這里為lib),並不是sub倉庫的文件,而是對應的commit id。如圖所示:

添加子倉庫
檢出(checkout)
克隆一個包含子倉庫的倉庫目錄,並不會clone下子倉庫的文件,只是會克隆下.gitmodule描述文件,需要進一步克隆子倉庫文件。
// 初始化本地配置文件 $ git submodule init // 檢出父倉庫列出的commit $ git submodule update
或者使用組合指令。
$ git submodule update --init --recursive
此時子目錄在一個未命名分支,此時子倉庫有改動並沒有檢測到。
$ git branch
* (HEAD detached at 46a27af) master
在子倉庫,切換到master分支,並git pull最新代碼之后,回到主倉庫目錄,會顯示子倉庫修改,需要在主倉庫提交修改,即修改指定的commit id。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: lib (new commits) no changes added to commit (use "git add" and/or "git commit -a")
更新
如果在本地修改子倉庫,在主倉庫 git status會顯示子倉庫有修改。
$git status
On branch master
Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) (commit or discard the untracked or modified content in submodules) modified: lib (modified content) no changes added to commit (use "git add" and/or "git commit -a")
需要現在子倉庫提交,然后再到主倉庫提交代碼。
刪除子倉庫
- 刪除.gitsubmodule里相關部分
- 刪除.git/config 文件里相關字段
- 刪除子倉庫目錄。
$ git rm --cached <本地路徑>
如果未按照上述步驟刪除,可能殘留在.git/modudles文件夾內。
參考
[1] Git submodule實戰