網(wǎng)站建設(shè)業(yè)務(wù)范圍b2b網(wǎng)站推廣排名
文章目錄
- 前言
- git submodule 相關(guān)命令
- 解決方案
- 怎么保存子模塊的版本呢
- 總結(jié)
前言
這個問題復(fù)雜在既有Git又有子模塊,本身Git的門檻就稍微高一點(diǎn),再加上子模塊的運(yùn)用,一旦出現(xiàn)這種遠(yuǎn)端地址發(fā)生修改的情況會讓人有些懵,不知道怎么處理,通常會亂改一通,有時候好使有時候不好使,并不清楚其中的緣由,退一步講,如果是一個單一的Git庫,如果遠(yuǎn)端地址發(fā)生了變化,使用 git remote set-url origin git@new_xxx
命令就可以就行修改,但是這個命令在子模塊情況下行不通,為了說明子模塊影響哪些配置文件,接下來會簡單羅列下git子模塊相關(guān)命令。
git submodule 相關(guān)命令
向一個項目中添加子模塊:
git submodule add git@github.com:zzz/xxx.git xxx
執(zhí)行之后會 clone 該子模塊對應(yīng)的遠(yuǎn)程項目文件到本地父項目目錄下的同名文件夾中(./xxx/),父項目下也會多一個叫 .gitmodules
的文件,其內(nèi)容大致如下:
[submodule "xxx"]path = xxxurl = git@github.com:zzz/xxx.git
同時父項目下的 .git 目錄中也會新增 modules/xxx/
目錄,里面的內(nèi)容對應(yīng)子模塊倉庫中原有的 .git 目錄中的文件,此時雖然子模塊目錄下的 .git 依然存在,但是已經(jīng)從一個文件夾變成了文件,內(nèi)容如下:
gitdir: ../.git/modules/xxx
即指向了父項目的 .git/modules/xxx
目錄,如果運(yùn)行 git config --list
查看項目的配置選項,會發(fā)現(xiàn)多了類似下面兩行的內(nèi)容:
submodule.xxx.url=git@github.com:zzz/xxx.git
submodule.xxx.active=true
如果修改 submodule.xxx.url
的值,則會覆蓋 .gitmodules
文件中對應(yīng)的 url 值;
這其實(shí)是主(父)工程 .git/config
文件中的內(nèi)容,而在主工程的 .git/modules/xxx/config
文件中會有下面這些內(nèi)容:
[remote "origin"]url = git@github.com:zzz/xxx.gitfetch = +refs/heads/*:refs/remotes/origin/*
總結(jié)來說子模塊的遠(yuǎn)端地址出現(xiàn)在三個文件中 .gitmodules
、.git/config
和 .git/modules/xxx/config
記住這些地方,我們后續(xù)會用到,這就是讓人迷惑的地方。
接下來按照以下命令查看當(dāng)前項目下的子模塊:
git submodule status
結(jié)果格式為:
b01bf0c72235aba2e92e5c5f5173dd4cae9b374c xxx (heads/master)
如果將父項目推送到遠(yuǎn)程倉庫(如gitlab),在網(wǎng)頁瀏覽該項目時子模塊所在的目錄會多一個類似 @b01bf0c 的后綴,即上面查看子模塊命令輸出內(nèi)容的 hash 值的前面部分,點(diǎn)擊這個目錄會跳轉(zhuǎn)到這個子模塊對應(yīng)的倉庫地址。
如果執(zhí)行以下刪除了子模塊的命令:
git submodule deinit
再次查看時輸出會是這樣的:
-b01bf0c72235aba2e92e5c5f5173dd4cae9b374c xxx
在取消初始化子模塊后,子模塊目錄會變?yōu)榭漳夸?#xff0c;避免該子模塊的文件繼續(xù)占用空間。
解決方案
聊了這么多,總要給出一個解決方案:
** 修改主工程下 .gitmodules
文件內(nèi)的遠(yuǎn)端地址 url = git@newdomain.com:zzz/xxx.git
,然后執(zhí)行 git submodule sync
命令即可完成 **
這樣操作之后 .git/config
和 .git/modules/xxx/config
文件中的遠(yuǎn)端的地址會一起被修改掉。
多說一點(diǎn):
在執(zhí)行 git submodule init
或 git submodule sync
命令時,Git 會將 .gitmodules
中的配置同步到 .git/config
中,以確保 .git/config
的信息是最新的。
而在執(zhí)行 git submodule update
進(jìn)行更新時,Git 主要使用 .git/config
中的子模塊配置來操作子模塊。
當(dāng)進(jìn)入子模塊目錄操作git時,Git使用的是 .git/modules/xxx/config
中的遠(yuǎn)端地址來進(jìn)行更新和推送
怎么保存子模塊的版本呢
了解了子模塊的機(jī)制,我們知道主工程只是保存了一個子模塊工程的版本號,但是前面看了這么多配置文件,里面只有子模塊的本地路徑和遠(yuǎn)端地址,沒有看到版本號啊?接下來我們找一下:
首先查看最新的提交commit,得到 5c997695ed383ea52879a17f0ef6944bf99d374f
$ git log -1
commit 5c997695ed383ea52879a17f0ef6944bf99d374f (HEAD -> dev, origin/dev)
Author: demo <demo@gameup.com>
Date: Mon Nov 4 11:42:25 2024 +0800update cmake file
利用 cat-file -p
命令查看指定 commit id
的倉庫狀態(tài)
$ git cat-file -p 5c997695ed383
tree 8499d7cb5c4811918bfc1341bb869d8bb38c40ef
parent b287b7783e1d44a6149de132142b88bf92b95bb3
author demo <demo@gameup.com> 1730691745 +0800
committer demo <demo@gameup.com> 1730691745 +0800update cmake file
從結(jié)果中可以看出提交人的信息,父提交id b287b7783e1d44a6149de132142b88bf92b95bb3
,以及一棵樹tree 8499d7cb5c4811918bfc1341bb869d8bb38c40ef
,怎么理解這棵樹呢?其實(shí)可以類比文件系統(tǒng)中的文件夾,每一個commit id實(shí)際上對應(yīng)著項目文件夾的版本,其中包含子文件夾版本和各個文件的版本,那么tree 8499d7cb5c4811918bfc1341bb869d8bb38c40ef
可以認(rèn)為是項目文件夾內(nèi)所有內(nèi)容的Hash
接下來再利用 cat-file -p
命令來看看這棵tree 8499d7cb5c4811918bfc1341bb869d8bb38c40ef
$ git cat-file -p 8499d7cb5c4811918bfc1341bb869d8bb38c40ef
100644 blob 344bc6e4d42e8fbae98a8d808b177b6773f88d31 .gitattributes
100644 blob c634b5c2da75f0eed128c701530afa5b2b799c69 .gitignore
100644 blob ba0ab2fd274f219c0e007177ad861f77a57581b0 .gitmodules
040000 tree 90317b8c9672803678037d9f006ea6818d90210b .vscode
040000 tree 0706cb16e4c162b194680972ab7605654a1541a1 cmake
160000 commit cec7534dcb171d38d46ba47217694261ad4c7b15 xxx
040000 tree 2c693865de8c02cd87f28fe85ba5e57a73617029 src
這里邊有3類內(nèi)容,分別是 blob
、tree
、commit
,blob就是具體的文件,tree就是代表一個文件夾,而 xxx
的類型是一個commit,從上文我們知道 xxx
是包含了另一個項目的文件夾,如果是一個單純的文件夾這里的類型應(yīng)該是tree,但是因?yàn)槭亲幽K,所以類型是記錄另一個項目commit id,這樣我們就找到了主工程引用子模塊的版本存儲的位置了。
總結(jié)
- 添加子模塊的命令
git submodule add git@github.com:zzz/xxx.git xxx
- 初始子模塊
git submodule init
,查看子模塊git submodule status
- 注銷子模塊
git submodule deinit xxx
,注銷后文件夾清空,但是配置文件需要手動刪除 - 子模塊遠(yuǎn)端地址發(fā)生變化,手動修改
.gitmodules
文件中地址,然后執(zhí)行git submodule sync
再提交修改
放下助人情節(jié),尊重他人命運(yùn),可憐之人必有可恨之處,子非魚,安知魚之經(jīng)歷與內(nèi)心~