git submodule 使用场景汇总
文章目錄
- 1. 前言
- 2. 基礎命令介紹
- 2.1 場景一:已有倉庫,添加一個子模塊
- 2.2 場景二:已有倉庫,添加一個子模塊的特定分支
- 2.3 場景三:已有倉庫,更新子模塊內容
- 2.4 場景四:已有倉庫,變更子模塊分支
- 2.5 場景五:手動修改.gitmodules不生效問題
- 3. 總結
1. 前言
當我們想要在A項目中使用B項目作為依賴,并且希望和B項目保持同步更新。這個時候git 會將A項目作為B項目的子模塊,為了保證B的更新能夠在A需要的時候同步到A中,git 推出了子命令submodule,能夠非常方便得讓A管理 包括B、C在內的多個子模塊,并且能夠指定具體子模塊的一個分支來給A用。
當然,除了介紹submodule 子命令的基本使用之外,也記錄一下使用過程中遇到的一些比較坑的問題。
2. 基礎命令介紹
2.1 場景一:已有倉庫,添加一個子模塊
> ls -al
total 8
drwxr-xr-x 4 zhanghuigui staff 128 Feb 5 15:21 .
drwx------@ 35 zhanghuigui staff 1120 Feb 5 15:20 ..
drwxr-xr-x 12 zhanghuigui staff 384 Feb 5 15:26 .git
-rw-r--r-- 1 zhanghuigui staff 7 Feb 5 15:21 README.md
如上已有的一個倉庫,現在需要為這個倉庫添加一個submodule, https://github.com/hoytech/vmtouch.git
執行如下命令,其中url 之后的vmtouch是 指定的子模塊存放的目錄,如果不指定,默認是以子模塊的倉庫名稱命名。
> git submodule add https://github.com/hoytech/vmtouch.git vmtouch
正克隆到 '/Users/zhanghuigui/Desktop/submodule_test/vmtouch'...
remote: Enumerating objects: 546, done.
remote: Total 546 (delta 0), reused 0 (delta 0), pack-reused 546
接收對象中: 100% (546/546), 362.03 KiB | 168.00 KiB/s, 完成.
處理 delta 中: 100% (301/301), 完成.
這個時候如果 執行git status 就能看到 當前倉庫下已經有了vmtouch目錄 和一個.gitmodules文件
> git status
位于分支 master
要提交的變更:(使用 "git restore --staged <文件>..." 以取消暫存)新文件: .gitmodules新文件: vmtouch
需要注意的是.gitmodules是submodule的配置文件,當倉庫A 內部有子模塊時,就會為A自動生成一個.gitmodules來保存submodule相關的配置,并且這個文件也會被git追蹤。
可以看到文件內容如下,submodule 之后的"vmtouch" 表示該submodule所在目錄,path后的內容需和submodule保持一致。
> cat .gitmodules
[submodule "vmtouch"]path = vmtouchurl = https://github.com/hoytech/vmtouch.git
想要對比cache的不同內容,可以通過git diff --cached,可以看到盡管vmtouch是一個目錄,但是git 并不會追蹤其內部的數據文件。
> git diff --cached vmtouch
diff --git a/vmtouch b/vmtouch
new file mode 160000
index 0000000..3382336
--- /dev/null
+++ b/vmtouch
@@ -0,0 +1 @@
+Subproject commit 3382336a9be3ab9b3552208a3db4ada7e247b542
最后提交變更即可:
> git commit -m "[feature] add the vmtouch as submodule"
[master f198528] [feature] add the vmtouch as submodule2 files changed, 4 insertions(+)create mode 100644 .gitmodulescreate mode 160000 vmtouch> git push origin master # 提交到遠端倉庫
submodule的子模塊也會被添加到當前倉庫的config文件中:
> cat .git/config [core]repositoryformatversion = 0filemode = truebare = falselogallrefupdates = trueignorecase = trueprecomposeunicode = true [submodule "vmtouch"]active = trueurl = https://github.com/hoytech/vmtouch.git
2.2 場景二:已有倉庫,添加一個子模塊的特定分支
我們想要為一個已經存在的倉庫添加一個子模塊,并且僅僅將這個子模塊的指定分支添加進來,初使目錄還是之前的目錄
> la
total 16
drwxr-xr-x 13 zhanghuigui staff 416B Feb 5 16:06 .git
-rw-r--r-- 1 zhanghuigui staff 84B Feb 5 15:37 .gitmodules
-rw-r--r-- 1 zhanghuigui staff 7B Feb 5 15:21 README.md
drwxr-xr-x 2 zhanghuigui staff 64B Feb 5 15:58 vmtouch
添加一個子模塊到指定目錄,并指定其分支:
> git submodule add -b support-block-devices -- https://github.com/hoytech/vmtouch.git thirdparty/vmtouch
指定了vmtouch的support-block-devices 分支,并 將vmtouch子模塊放在了thirdparty/vmtouch 目錄下。
這個時候文件又發生了變更:
> git status
位于分支 master
要提交的變更:(使用 "git restore --staged <文件>..." 以取消暫存)修改: .gitmodules新文件: thirdparty/vmtouch
可以看到又一個子模塊的entry信息被添加到了.gitmodules之中,并且多了一個模塊的分支信息。
> cat .gitmodules
[submodule "vmtouch"]path = vmtouchurl = https://github.com/hoytech/vmtouch.git
[submodule "thirdparty/vmtouch"] # 第二次添加的子模塊path = thirdparty/vmtouchurl = https://github.com/hoytech/vmtouch.gitbranch = support-block-devices # 模塊分支
需要注意的是,這里指定倉庫的特定分支 不能是tag, tag沒有commit記錄,而submolue需要通過commit id來區分不同的分支。
如果是用了tag 來當作分支使用,會出現如下問題:
> git submodule add -b v1.3.1 -- https://github.com/hoytech/vmtouch.git thirdparty/vmtouch 正克隆到 '/Users/zhanghuigui/Desktop/submodule_test/thirdparty/vmtouch'... remote: Enumerating objects: 546, done. remote: Total 546 (delta 0), reused 0 (delta 0), pack-reused 546 接收對象中: 100% (546/546), 362.03 KiB | 305.00 KiB/s, 完成. 處理 delta 中: 100% (301/301), 完成. fatal: 'origin/v1.3.1' 不是一個提交,不能基于它創建分支 'v1.3.1' Unable to checkout submodule 'thirdparty/vmtouch'
最后繼續執行commit和push ,將結果更新到本地和遠程倉庫即可。
2.3 場景三:已有倉庫,更新子模塊內容
工作過程中,我們同樣會維護一些自己的一些工作目錄,每次重新進入工作目錄的時候會有想要更新子模塊的需求,或者子模塊中有合入了新的feature,我們想要對這個feature做一些測試,這個時候也可能需要變更子模塊的分支,或者將最新的代碼取下來。
-
拉取最新的submodue 代碼方式
cd vmtouch git fetch # 獲取最新的代碼 git merge orgin/master # 合并最新的代碼 -
submodule 外部更新數據
git submodule update --remote vmtouch這個方式,其實也類似于進入submodule ,執行fetch和merge命令
2.4 場景四:已有倉庫,變更子模塊分支
以上僅僅是更新子模塊的當前分支的內容,并不會變更子模塊的分支,也就是變更.git目錄中的config數據。如果這個時候需要變更子模塊的分支,則可以執行如下命令:
# 變更前.gitmodules 配置
> cat .gitmodules
[submodule "vmtouch"]path = vmtouchurl = https://github.com/hoytech/vmtouch.git
[submodule "thirdparty/vmtouch"]path = thirdparty/vmtouchurl = https://github.com/hoytech/vmtouch.gitbranch = support-block-devices# 變更vmtouch 目錄的分支配置,默認是master分支
> git config -f .gitmodules submodule.vmtouch.branch support-block-devices
> cat .gitmodules
[submodule "vmtouch"]path = vmtouchurl = https://github.com/hoytech/vmtouch.gitbranch = support-block-devices
[submodule "thirdparty/vmtouch"]path = thirdparty/vmtouchurl = https://github.com/hoytech/vmtouch.gitbranch = support-block-devices
# 執行.gitmodules 中的更新
> git submodule update --remote
Submodule path 'vmtouch': checked out '3111cb1a51a0a556dd86e4a7d4653e6198eb6a95'
> cd vmtouch
> git branch -av # 對應目錄已經更新到了support-block-devices 分支
* (3111cb1) 3111cb1 support block devicesmaster 3382336 Merge pull request #78 from johnmay/can_do_mincoreremotes/origin/HEAD -> origin/masterremotes/origin/hp-ux-support 86ad976 Note HP-UX supportremotes/origin/master 3382336 Merge pull request #78 from johnmay/can_do_mincoreremotes/origin/support-block-devices 3111cb1 support block devices
(END)
通過修改.gitmodules 來變更對應submodule 的分支,變更之后.gitmodules文件和對應的子模塊目錄都會改動
> git status
位于分支 master
要提交的變更:(使用 "git restore --staged <文件>..." 以取消暫存)修改: .gitmodules新文件: thirdparty/vmtouch尚未暫存以備提交的變更:(使用 "git add <文件>..." 更新要提交的內容)(使用 "git restore <文件>..." 丟棄工作區的改動)修改: .gitmodules修改: vmtouch (新提交)
再次commit和push即可。
如果想要看看關于submodule的改動提交日志,可以通過
> git log -p --submodule
commit f19852812f62bbbdc9e916330d78d1021e816818 (HEAD -> master, 0a)
Author: BaronStack <2689496754@qq.com>
Date: Fri Feb 5 15:53:12 2021 +0800[feature] add the vmtouch as submodulediff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a0e55c0
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vmtouch"]
+ path = vmtouch
+ url = https://github.com/hoytech/vmtouch.git
Submodule vmtouch 0000000...3382336 (new submodule)commit afac2efb7a6807f08ab7b83a72a4b6348a414f0b
Author: BaronStack <2689496754@qq.com>
Date: Fri Feb 5 15:21:39 2021 +0800[feature] first file touch in repdiff --git a/README.md b/README.md
new file mode 100644
index 0000000..2f723b7
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+#FIRST
2.5 場景五:手動修改.gitmodules不生效問題
可以通過修改.gitmodules文件來增加對應的submodules,需要注意每行的符號
如果用普通的換行符是無法擁有這樣的特殊符號的,會導致新添加的submodule 之后無法更新。
建議完整復制之前的submodule entry內容,再在其基礎上修改。
或者使用場景二和場景四 來添加新的submodule git submodule add ...等。
之后再執行git submodule update --remote
3. 總結
關于submodule 的使用基本就是以上幾種場景,如果后續還會碰到其他的場景或者問題,歡迎大家留言補充。
總結
以上是生活随笔為你收集整理的git submodule 使用场景汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字符串匹配算法 -- BM(Boyer-
- 下一篇: 妄想山海岩浆里的蛋怎么捡?