歡迎任何形式的轉載,轉載請保留原文連接:juejin.cn/post/694825…java
爲啥要用 git submodule,以及爲啥不使用 git 倉庫直接嵌套的形式 ?git
本文主要講解 git submodule 使用與教程,目的有如下幾點:github
注:爲了方便查閱經常使用操做以及對應命令,文章章節順序非友好的學習順序,其中教程巨長放到最後了,若是教程以前的內容看不明白,建議過一遍教程shell
# 查看 submodules
# 結果的 hash 前不帶符號說明該 module 正常且提交版本同步(提交版本同步指主項目記錄提交版本與子模塊當前提交版本一致)
# 結果的 hash 前帶 - 號說明該 module 未初始化
# 結果的 hash 前帶 + 號說明該 module 版本未同步
git submodule
git submodule status
# 初始化 modules,重複初始化無影響,例子中後跟 rxjava 爲指定初始化某個 module 的名稱(下同)
git submodule init
git submodule init rxjava
# 版本未同步時,檢出 modules,保證檢出的版本與主項目匹配,但子 module 會建立臨時分支
git submodule update
git submodule update rxjava
# 添加 submodule,例子中後跟 rxjava 爲該 module 名稱與目錄名
git submodule add https://github.com/ReactiveX/RxJava.git
git submodule add https://github.com/ReactiveX/RxJava.git rxjava
# 強制添加 submodule(僅用於 git submodule 沒有正確的顯示某個 module)
git submodule add --force --name rxjava https://github.com/ReactiveX/RxJava.git
# 從新 clone 項目(含 clone 全部子項目)方式一
git clone --recursive https://github.com/ReactiveX/RxJava.git
# 從新 clone 項目(含 clone 全部子項目)方式二,依次執行如下命令
git clone https://github.com/ReactiveX/RxJava.git
git submodule init
git submodule update
# 遍歷全部 submodule
# git submodule foreach 其餘命令,如:
git submodule foreach git pull
git submodule foreach ls -l
複製代碼
主項目拉取,且有新的 submodule(就是存在未初始化的)瀏覽器
git pull
git submodule init
git submodule update [新 module 名稱]
複製代碼
其餘說明:緩存
git pull
便可。若是想讓提交版本同步,主項目使用 git submodule update rxjava
git clone
(方式二)要先初始化,再檢出,這樣才能正常使用本地倉庫不廢棄的狀況下,對某個 submodule 進行刪除、修更名稱、修改倉庫地址操做,但除了修改倉庫地址,其餘人的遠程倉庫是基本完蛋了,須要從新 clonebash
刪除 submodulemarkdown
git reset --hard HEAD
命令,再次強調全部修改都已提交再操做git submodule
的結果沒有要刪除的# 假設 submodule 名稱爲 subA
# 1. 必須,git rm -r --cached subA
# 2. 必須,rm -rf subA/,或手動刪除對應目錄
# 3. 必須,修改【.gitmodules】文件內容:去除被刪除的 submodule 內容
# 4. 非必須,修改【.git/config】文件內容:去除被刪除的 submodule 內容
# 5. 非必須,刪除【.git/modules】目錄下對應 submodule 目錄
複製代碼
重命名 submodule 目錄工具
git rm -r --cached subA
命令,以及 git submodule add
命令更改 submodule 遠程倉庫地址oop
# 1. 修改【.gitmodules】文件對應倉庫地址:隻影響遠程倉庫
# 2. 修改【.git/config】文件對應倉庫地址:額,改不改無所謂
# 3. 進入子模塊,使用 `git remote` 命令,更新遠程倉庫地址
複製代碼
關於遠程倉庫
關於本地倉庫
git submodule update
檢出時,保證檢出的版本與主項目匹配,但子 module 會建立臨時分支最主要的是主項目的【.gitmodules】文件,內容以下,覺得比較簡單就不解釋了
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
path = subB
url = /cygdrive/e/submodule/repo/subB.git
複製代碼
關於本地倉庫,對比添加 submodule 先後:
git submodule init
後更新git submodule update
後出現# 【子模塊/.git】文件
gitdir: ../.git/modules/subA
複製代碼
# 【.git/config】文件,下列[submodule "subA"]塊是多出來的
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[submodule "subA"]
active = true
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
active = true
url = /cygdrive/e/submodule/repo/subB.git
複製代碼
$ ll .git/modules/
總用量 8
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:41 subA/
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:41 subB/
複製代碼
如下是 git submodule 詳細使用教程
爲方便驗證與測試,這裏提供測試環境搭建過程
建立(本地性質的)遠程倉庫
# 建立(本地性質的)遠程倉庫與本地倉庫目錄
$ mkdir repo
$ mkdir project
# 進入遠程倉庫目錄,創建主項目遠程倉庫(main.git)以及,若干個子模塊遠程倉庫(subA.git)
$ cd repo
$ git --git-dir=main.git init --bare
$ git --git-dir=subA.git init --bare
$ git --git-dir=subB.git init --bare
$ ll
總用量 16
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 main.git/
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 subA.git/
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 subB.git/
# 獲取遠程倉庫地址,用來 clone 項目
$ cd main.git
$ pwd
/cygdrive/e/submodule/repo/main.git
# 同理其餘子模塊遠程倉庫地址
/cygdrive/e/submodule/repo/subA.git
/cygdrive/e/submodule/repo/subB.git
複製代碼
遠程倉庫初始提交,目的爲了讓每一個遠程倉庫都有分支,以及提交記錄
# 在 repo 目錄下 clone 代碼
$ cd ../
$ pwd
/cygdrive/e/submodule/repo
$ git clone main.git
$ ll
總用量 16
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:21 main/
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 main.git/
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 subA.git/
drwxrwxr-x+ 1 Administrator None 0 4月 2 14:53 subB.git/
# 建立任意文件,並作初始化提交,並推送到遠程
$ cd main
$ touch init
$ git add .
$ git commit -m "main init"
$ git push
$ git branch
* master
$ git log --oneline
468894f (HEAD -> master, origin/master) main init
# 到這裏上述 main.git 遠程倉庫就有一個 master 分支,以及一個提交記錄了
# 既然已近作好推送了,就能夠刪除這個用來作初始化的臨時本地倉庫了
$ cd ..
$ rm -rf main
# 其餘遠程倉庫,按上述同操做便可,如下爲各個遠程倉庫首次提交
468894f (HEAD -> master, origin/master) main init
5ae8df5 (HEAD -> master, origin/master) subA init
6bf24b8 (HEAD -> master, origin/master) subB init
複製代碼
複製主項目遠程倉庫,用來對比添加 submodule 先後,遠程倉庫的變化
從遠程倉庫 clone 到項目目錄下的本地倉庫
# 主項目 clone,多 clone 一個是爲了對比
$ cd ../project
$ git clone /cygdrive/e/submodule/repo/main.git
$ git clone /cygdrive/e/submodule/repo/main.git main_copy
複製代碼
添加子 module(如下簡稱子模塊)
# 往主項目裏添加 submodule,注:一個一個來,以便分開 commit,方便後續演示
$ cd main
$ git submodule add /cygdrive/e/submodule/repo/subA.git
正克隆到 '/cygdrive/e/submodule/project/main/subA'...
完成。
warning: .gitmodules 中的 LF 將被 CRLF 替換。
在工做區中該文件仍保持原有的換行符
# 添加後結果
$ ll
總用量 0
-rw-rw-r--+ 1 Administrator None 0 4月 2 15:37 init
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:37 subA/
$ git status
位於分支 master
您的分支與上游分支 'origin/master' 一致。
要提交的變動:
(使用 "git reset HEAD <文件>..." 以取消暫存)
新文件: .gitmodules
新文件: subA
$ ll -a subA/
總用量 1
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:37 ./
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:38 ../
-rw-rw-r--+ 1 Administrator None 29 4月 2 15:37 .git
-rw-rw-r--+ 1 Administrator None 0 4月 2 15:37 init
# 主項目提交本次添加 submodule 的結果
$ git add .
$ git commit -m "添加 submodule:subA"
[master 7ada136] 添加 submodule:subA
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 subA
# 同理添加另外一個 submodule,最後提交記錄與 submodule 記錄以下
$ git log --oneline
31287e4 (HEAD -> master) 添加 submodule:subB
7ada136 添加 submodule:subA
468894f (origin/master, origin/HEAD) main init
$ git submodule
5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
複製代碼
對比 main 和 main_copy(沒有 submodule)可知
git submodule init
後更新git submodule update
後出現$ cat .gitmodules
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
path = subB
url = /cygdrive/e/submodule/repo/subB.git
$ cat subA/.git
gitdir: ../.git/modules/subA
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[submodule "subA"]
url = /cygdrive/e/submodule/repo/subA.git
active = true
[submodule "subB"]
url = /cygdrive/e/submodule/repo/subB.git
active = true
$ ll .git/modules/
總用量 8
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:41 subA/
drwxrwxr-x+ 1 Administrator None 0 4月 2 15:41 subB/
複製代碼
若是遠程倉庫使用的是真實的遠程倉庫,則使用瀏覽器訪問主項目時,就能夠發現主項目存在 submodule 目錄,並點擊該目錄能夠跳轉到 submodule 對應的遠程倉庫
到此對比遠程倉庫添加 submodule 先後,能夠發現除了提交記錄與 HEAD 指證外,其餘文件並未發生變化,因此主項目的 submodule 記錄僅取決於主項目下的【.gitmodules】文件內容
刪除 submodule 的方式有兩種
方式一:只修改【.gitmodules】文件,而後推送遠程倉庫,再從新 clone,本來地倉庫不要了
git clone
新開一個本地倉庫# 原【.gitmodules】內容
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
path = subB
url = /cygdrive/e/submodule/repo/subB.git
# 刪除後【.gitmodules】內容
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
複製代碼
方式二:本地倉庫正常刪除 submodule,而後推送遠程倉庫,本來地倉庫依然可使用
必須,清除 submodule 緩存記錄
git reset --hard HEAD
命令,再次強調全部修改都已提交再操做git submodule
結果沒有要刪除的$ git rm -r --cached subA
rm 'subA'
# 上述命令結果驗證
$ git submodule
5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA (heads/master)
複製代碼
必須,刪除 submodule 文件夾,即 subA 文件夾,對應命令以下,不過建議手動刪除
$ rm -rf subA/
複製代碼
必須,修改【.gitmodules】文件內容:去除被刪除的 submodule 內容
# 原內容
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
path = subB
url = /cygdrive/e/submodule/repo/subB.git
# 刪除後內容
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
複製代碼
非必須,修改【.git/config】文件內容:去除被刪除的 submodule 內容
# 原內容
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[submodule]
active = .
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[submodule "subA"]
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
url = /cygdrive/e/submodule/repo/subB.git
# 刪除後內容
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[submodule]
active = .
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[submodule "subA"]
url = /cygdrive/e/submodule/repo/subA.git
複製代碼
非必須,刪除【.git/modules】目錄下對應 submodule 目錄
沒有好辦法,全部的方法,本質都是先刪除,再從新添加
git rm -r --cached subA
命令,以及 git submodule add
命令如下操做是錯誤的:
這裏說的是修改只修改遠程倉庫地址,不修改子模塊名稱的狀況
背景:原來的 /cygdrive/e/submodule/repo/subA.git
遠程倉庫遷移到 /cygdrive/e/submodule/subA.git
更改步驟說明
# 1. 修改【.gitmodules】文件對應倉庫地址:隻影響遠程倉庫
# 2. 修改【.git/config】文件對應倉庫地址:額,改不改無所謂
# 3. 進入子模塊,使用 `git remote` 命令,更新遠程倉庫地址
複製代碼
這裏演示多人共同開發主項目時,其中一人添加了 submodule
pull 主項目,並查看日誌
$ cd main_copy
$ git pull
$ git log --oneline
31287e4 (HEAD -> master, origin/master, origin/HEAD) 添加 submodule:subB
7ada136 添加 submodule:subA
468894f main init
複製代碼
查看 submodule 記錄、子模塊內容、【.gitmodules】文件、【.git/config】文件、【.git/modules】目錄、子模塊日誌
$ git submodule
-5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA
-6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB
$ ll -a subA subB
subA:
總用量 0
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:36 ./
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:36 ../
subB:
總用量 0
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:36 ./
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:36 ../
$ cat .gitmodules
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
[submodule "subB"]
path = subB
url = /cygdrive/e/submodule/repo/subB.git
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
$ ll .git/modules
/bin/ls: 沒法訪問'.git/modules': No such file or directory
$ cd subA
$ git log --oneline
31287e4 (HEAD -> master, origin/master, origin/HEAD) 添加 submodule:subB
7ada136 添加 submodule:subA
468894f main init
$ cd ..
複製代碼
如上,發現如下幾個問題
git submodule
的結果前面帶[-]號這些問題都是由於子模塊並無初始化、檢出致使的
git submodule
的結果前面帶[-]號就是表示該 submodule 未初始化# 初始化所有 submodule,重複初始化無反應
$ git submodule init
子模組 'subA'(/cygdrive/e/submodule/repo/subA.git)已對路徑 'subA' 註冊
子模組 'subB'(/cygdrive/e/submodule/repo/subB.git)已對路徑 'subB' 註冊
$ git submodule init
$ git submodule init subA
$ git submodule
5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB
# 檢出全部 submodule,重複檢出無反應
$ git submodule update
正克隆到 '/cygdrive/e/submodule/project/main_copy/subA'...
完成。
正克隆到 '/cygdrive/e/submodule/project/main_copy/subB'...
完成。
Submodule path 'subA': checked out '5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd'
Submodule path 'subB': checked out '6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638'
$ git submodule update
$ git submodule update subA
$ git submodule
5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB
$ cd subA
$ git log --oneline
5ae8df5 (HEAD, origin/master, origin/HEAD, master) subA init
cd ..
複製代碼
通過初始化和檢出,子模塊就能夠正常使用了
git submodule
的結果前面就不帶任何符號了兩種方式,一種是是直接 clone 項目,而後初始化、檢出
$ git clone /cygdrive/e/submodule/repo/main.git main_new
正克隆到 'main_new'...
完成。
$ git submodule init
子模組 'subA'(/cygdrive/e/submodule/repo/subA.git)已對路徑 'subA' 註冊
子模組 'subB'(/cygdrive/e/submodule/repo/subB.git)已對路徑 'subB' 註冊
$ git submodule update
正克隆到 '/cygdrive/e/submodule/project/main_new/subA'...
完成。
正克隆到 '/cygdrive/e/submodule/project/main_new/subB'...
完成。
Submodule path 'subA': checked out '5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd'
Submodule path 'subB': checked out '6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638'
複製代碼
另一種是 clone 時添加 --recursive
選項直接一步到位
$ git clone --recursive /cygdrive/e/submodule/repo/main.git main_new_02
正克隆到 'main_new'...
完成。
子模組 'subA'(/cygdrive/e/submodule/repo/subA.git)已對路徑 'subA' 註冊
子模組 'subB'(/cygdrive/e/submodule/repo/subB.git)已對路徑 'subB' 註冊
正克隆到 '/cygdrive/e/submodule/project/main_new/subA'...
完成。
正克隆到 '/cygdrive/e/submodule/project/main_new/subB'...
完成。
Submodule path 'subA': checked out '5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd'
Submodule path 'subB': checked out '6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638'
複製代碼
初始化,以及檢出以後,誤把子模塊刪除。這裏先說下結論
git submodule update
,但這種檢出會建立一個臨時分支# 缺失子模塊,不影響主項目 diff
$ rm -rf subB/
$ git status
位於分支 master
您的分支與上游分支 'origin/master' 一致。
無文件要提交,乾淨的工做區
# 缺失子模塊,一樣不影響主項目 submodule 記錄
$ git submodule
d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB
# 缺失子模塊,重複初始化不起做用
$ git submodule init
$ ll
總用量 0
-rw-rw-r--+ 1 Administrator None 0 4月 2 17:04 init
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:26 subA/
# 缺失子模塊,無效且錯誤作法:新建對應文件夾,而後在對應文件夾裏 pull,從結果能夠看出日誌並非子模塊的日誌
$ mkdir subB
$ cd subB/
$ gitlog
* 0e3354b 2021-04-02 18:42:00 | (HEAD -> other, origin/master, origin/HEAD, master)submodule subA 提交記錄更更新 <jefshi>
* 31287e4 2021-04-02 17:10:54 | 添加 submodule:subB <jefshi>
* 7ada136 2021-04-02 17:05:20 | 添加 submodule:subA <jefshi>
* 468894f 2021-04-02 15:24:36 | main init <jefshi>
# 缺失子模塊,從新檢出,但子模塊是建立一個臨時分支
$ git submodule update
Submodule path 'subB': checked out '6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638'
$ ll
總用量 0
-rw-rw-r--+ 1 Administrator None 0 4月 2 17:04 init
drwxrwxr-x+ 1 Administrator None 0 4月 2 17:26 subA/
drwxrwxr-x+ 1 Administrator None 0 4月 2 20:50 subB/
$ cd subB
$ git branch
master
* (頭指針分離於 6bf24b8)
$ cd ..
複製代碼
進入子模塊目錄進行修改並提交
$ cd main/subA
$ touch first
$ git add .
$ git commit -m "subA:第一次修改"
$ git push
$ git log --oneline
d8346a8 (HEAD -> master) subA:第一次修改
5ae8df5 (origin/master, origin/HEAD) subA init
複製代碼
主項目查看差別,提交併查看 submodule。這裏先說下結論
git submodule
的結果前面帶[+]號,表示主項目記錄的提交版本與對應 submodule 的提交記錄不一致# 子模塊提交記錄同步前
$ git submodule
+d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
$ cd ..
$ git status
位於分支 master
您的分支與上游分支 'origin/master' 一致。
還沒有暫存以備提交的變動:
(使用 "git add <文件>..." 更新要提交的內容)
(使用 "git checkout -- <文件>..." 丟棄工做區的改動)
修改: subA (新提交)
$ git add .
$ git commit -m "submodule subA 提交記錄更更新"
[master 0e3354b] submodule subA 提交記錄更更新
1 file changed, 1 insertion(+), 1 deletion(-)
$ git submodule
d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
$ git push
複製代碼
另外一個主項目(main_copy)從遠程倉庫更新上述操做。這裏先說下結論
git pull
只會更新主項目,不會更新子模塊,反過來也是如此git submodule update
git submodule foreach git pull
git pull
操做# 更新前,主項目是無感知的
cd ../main_copy
$ git submodule
5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
# 更新後,能夠看到提交版本不一致
$ git pull
$ git log --oneline
0e3354b (HEAD -> master, origin/master, origin/HEAD) submodule subA 提交記錄更更新
31287e4 添加 submodule:subB
7ada136 添加 submodule:subA
468894f main init
$ git submodule
+5ae8df5a1fd55d31b0fc7e8bdf7d02fb7591f4bd subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
# 更新子模塊方式一
$ git submodule update
Submodule path 'subA': checked out 'd8346a82a2ba13077d7f25124239ac0d3db5920c'
$ cd subA
$ git branch
master
* (頭指針分離於 d8346a8)
# 子模塊還原
$ git checkout master
$ git reset --hard HEAD
$ cd ..
# 更新子模塊方式二
$ git submodule foreach git pull
進入 'subA'
更新 5ae8df5..d8346a8
Fast-forward
first | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 first
進入 'subB'
來自 /cygdrive/e/submodule/repo/subB
+ 4f6ad1c...6bf24b8 master -> origin/master (強制更新)
已是最新的。
$ cd subA
$ git log --oneline
d8346a8 (HEAD -> master, origin/master, origin/HEAD) subA:第一次修改
5ae8df5 subA init
cd ..
複製代碼
關於主項目記錄的提交版本與子模塊不一致討論,不一致有如下幾種
新建一個分支,使 master 分支含有兩個 submodule,另外一個分支只含有一個
$ git branch
* master
$ git log --oneline
0e3354b (HEAD -> master, origin/master, origin/HEAD) submodule subA 提交記錄更更新
31287e4 添加 submodule:subB
7ada136 (onlySubA) 添加 submodule:subA
468894f main init
$ git submodule
d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
$ git checkout -b onlySubA 7ada136
$ git log --oneline
7ada136 (HEAD -> onlySubA) 添加 submodule:subA
468894f main init
$ git branch
master
* onlySubA
$ git submodule
+d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
複製代碼
這裏 master 有兩個 submodule,onlySubA 分支只有一個 submodule。接下來看下 onlySubA 分支的提交差別,以及一些相關文件。
這裏先說下結論,能夠看出在 onlySubA 分支上
$ git branch
master
* onlySubA
$ git status
位於分支 onlySubA
還沒有暫存以備提交的變動:
(使用 "git add <文件>..." 更新要提交的內容)
(使用 "git checkout -- <文件>..." 丟棄工做區的改動)
修改: subA (新提交)
未跟蹤的文件:
(使用 "git add <文件>..." 以包含要提交的內容)
subB/
$ cat .gitmodules
[submodule "subA"]
path = subA
url = /cygdrive/e/submodule/repo/subA.git
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = /cygdrive/e/submodule/repo/main.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[submodule "subA"]
url = /cygdrive/e/submodule/repo/subA.git
active = true
[submodule "subB"]
url = /cygdrive/e/submodule/repo/subB.git
active = true
$ ll .git/modules/
總用量 8
drwxrwxr-x+ 1 Administrator None 0 4月 2 20:35 subA/
drwxrwxr-x+ 1 Administrator None 0 4月 2 20:33 subB/
複製代碼
因爲切分支時多餘的子模塊文件夾並不會被刪除。若是此時誤操做把多餘的子模塊文件夾給提交了,分析下以後從新添加相同子模塊的 submodule 的結果。這裏先說下結論
# 背景
$ git status
位於分支 onlySubA
未跟蹤的文件:
(使用 "git add <文件>..." 以包含要提交的內容)
subB/
# 誤操做
$ git add .
$ git commit -m "誤把不須要的子模塊提交"
$ git status
位於分支 onlySubA
無文件要提交,乾淨的工做區
# 添加相同的子模塊失敗
$ git submodule add /cygdrive/e/submodule/repo/subB.git
'subB' already exists in the index
複製代碼
背景:
# 背景:主項目兩個分支,以及分支指向的提交記錄(other 指向 31287e4)
$ git branch
* master
other
$ git log --oneline
0e3354b (HEAD -> master, origin/master, origin/HEAD) submodule subA 提交記錄更更新
31287e4 (other) 添加 submodule:subB
7ada136 添加 submodule:subA
468894f main init
# 背景:子模塊 subA 兩個分支,以及分支指向的提交記錄
$ cd subA
$ git branch
* master
subOther
$ git log --oneline
d8346a8 (HEAD -> master, origin/master, origin/HEAD) subA:第一次修改
5ae8df5 (subOther) subA init
$ cd ..
複製代碼
上述主項目和子模塊都是 master 分支,如今主項目切換到 other 分支,觀察子模塊分支狀況,這裏先說下結論
# 主項目切分支
$ git branch
* master
other
$ git checkout other
M subA
切換到分支 'other'
$ git submodule
+d8346a82a2ba13077d7f25124239ac0d3db5920c subA (heads/master)
6bf24b87a83ee2621e9b9aaf93b6d0f4f2b81638 subB (heads/master)
# 主項目切分支後,子模塊分支狀況
$ cd subA/
$ git branch
* master
subOther
複製代碼
參考文獻:
博客同步版本: