Git Submodule 允許一個(gè)git倉(cāng)庫(kù),作為另一個(gè)git倉(cāng)庫(kù)的子目錄,并且保持父項(xiàng)目和子項(xiàng)目相互獨(dú)立。
添加子倉(cāng)庫(kù)
$ git submodule add <倉(cāng)庫(kù)地址> <本地路徑>
新建一個(gè)父?jìng)}庫(kù)main,一個(gè)子倉(cāng)庫(kù)sub。將父?jìng)}庫(kù)克隆到本地。
$ git clone ssh://git@10.2.237.56:23/dennis/main.git
進(jìn)入父?jìng)}庫(kù),并添加子倉(cāng)庫(kù)。
$ git submodule add ssh://git@10.2.237.56:23/dennis/sub.git lib
添加成功后,在父?jìng)}庫(kù)根目錄增加了.gitmodule文件。
[submodule "sub"]
path = lib
url = ssh://git@10.2.237.56:23/dennis/sub.git
并且在父?jìng)}庫(kù)的git 配置文件中加入了submodule段。
$ cat .git/config
// 加了submodule段
[submodule "sub"]
url = ssh://git@10.2.237.56:23/dennis/sub.git
注意:添加子倉(cāng)庫(kù)之后,主倉(cāng)庫(kù)的對(duì)應(yīng)目錄下(這里為lib),并不是sub倉(cāng)庫(kù)的文件,而是對(duì)應(yīng)的commit id。如圖所示:

檢出(checkout)
克隆一個(gè)包含子倉(cāng)庫(kù)的倉(cāng)庫(kù)目錄,并不會(huì)clone下子倉(cāng)庫(kù)的文件,只是會(huì)克隆下.gitmodule描述文件,需要進(jìn)一步克隆子倉(cāng)庫(kù)文件。
// 初始化本地配置文件
$ git submodule init
// 檢出父?jìng)}庫(kù)列出的commit
$ git submodule update
或者使用組合指令。
$ git submodule update --init --recursive
此時(shí)子目錄在一個(gè)未命名分支,此時(shí)子倉(cāng)庫(kù)有改動(dòng)并沒(méi)有檢測(cè)到。
$ git branch
* (HEAD detached at 46a27af)
master
在子倉(cāng)庫(kù),切換到master分支,并git pull最新代碼之后,回到主倉(cāng)庫(kù)目錄,會(huì)顯示子倉(cāng)庫(kù)修改,需要在主倉(cāng)庫(kù)提交修改,即修改指定的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")
更新
如果在本地修改子倉(cāng)庫(kù),在主倉(cāng)庫(kù) git status會(huì)顯示子倉(cāng)庫(kù)有修改。
$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")
需要現(xiàn)在子倉(cāng)庫(kù)提交,然后再到主倉(cāng)庫(kù)提交代碼。
刪除子倉(cāng)庫(kù)
- 刪除.gitsubmodule里相關(guān)部分
- 刪除.git/config 文件里相關(guān)字段
- 刪除子倉(cāng)庫(kù)目錄。
$ git rm --cached <本地路徑>
如果未按照上述步驟刪除,可能殘留在.git/modudles文件夾內(nèi)。