Git子模組使用

2022-09-19 11:00:15 字數 4840 閱讀 3947

在工作中我們經常遇到乙個情況,在乙個專案中需要包含並使用到另乙個專案,比如開發部落格時使用到的主題專案,或者是公司業務中需要在多個專案中使用的庫。那該如何獨立管理這兩個專案,並在乙個專案中使用另乙個專案呢?

git 通過子模組來解決這個問題。 子模組允許你將乙個 git 倉庫作為另乙個 git 倉庫的子目錄。 它能讓你將另乙個倉庫轉殖到自己的專案中,同時還保持提交的獨立。

注:如果以下有命令報錯或無法生效,請檢查 git 的版本。

$ git submodule add [-b 

] [-f|--force] [--name ] [--reference ] [--depth ] [--]

首先,在主專案中執行以下命令:

$ git submodule add --name matery [email protected]:xiamu33/hexo-theme-matery.git themes/xiamu-matery

cloning into 'blog/themes/xiamu-matery'...

...resolving deltas: 100% (8/8), done.

此時,在指定的themes目錄下會生成乙個名為xiamu-matery子模組。

並且在根目錄生成了新的.gitmodules檔案,該配置檔案儲存了專案 url 取的本地目錄之間的對映:

[submodule "matery"]

path = themes/xiamu-matery

url = [email protected]:xiamu33/hexo-theme-matery.git

如果有多個子模組,該檔案中就會有多條記錄。注意該檔案也需要納入 git 的版本管理並推送至倉庫,這樣轉殖該項目的人才知道去哪獲得子模組。

當我們轉殖乙個包含子模組的專案時,專案中會預設包含該子模組目錄,但其中沒有任何檔案:

$ git clone [email protected]:xiamu33/blog.git

cloning into 'blog'...

...resolving deltas: 100% (90/90), done.

$ ls blog/themes/xiamu-matery/

$

你必須執行git submodule update --init來初始化本地配置並拉取子模組資料(該命令實際上把git submodule initgit submodule update合併成了一步)。

專案中有許多子模組的話這樣操作未免有些繁瑣,如果給git clone命令傳遞--recurse-submodules選項,它就會自動初始化並更新倉庫中的每乙個子模組, 包括可能存在的巢狀子模組。

$ git clone --recurse-submodules [email protected]:xiamu33/blog.git

cloning into 'blog'...

...resolving deltas: 100% (90/90), done.

submodule 'themes/hexo-theme-matery' ([email protected]:xiamu33/hexo-theme-matery.git) registered for path 'themes/xiamu-matery'

cloning into 'blog/themes/xiamu-matery'...

submodule path 'themes/xiamu-matery': checked out '8017ee19d9f040607b4ca58286eb46596f773e61'

轉殖失敗

but,由於國內神奇的網路問題或者其他詭異的現象,「偶爾」會轉殖失敗(如出現openssl ssl_read: ssl_error_syscall, errno 10054錯誤時)。可以嘗試以下方法:

如果只成功轉殖了主專案,可執行git submodule update --init --recursive初始化並拉取專案中巢狀的所有子模組。

如何淺轉殖子模組

當我們的子模組專案十分龐大且只需要其最近的提交歷史時,可以選擇淺轉殖子模組。只需給git submodule update傳遞--depth選項:

$ git submodule add --name matery --depth 1 [email protected]:xiamu33/hexo-theme-matery.git themes/xiamu-matery
已有子模組的專案中則執行:

$ git submodule update --init --depth 1
此時,你本地專案的子模組的轉殖將作為淺轉殖執行(歷史深度為1)。如果你想始終淺轉殖該子模組,可執行以下命令:

$ git config -f .gitmodules submodule..shallow true
git submodule add命令中的--name選項,預設為子模組路徑

這將修改.gitmodules檔案:

[submodule "matery"]

path = themes/xiamu-matery

url = [email protected]:xiamu33/hexo-theme-matery.git

shallow = true

$ git submodule update --remote
git 缺省會嘗試更新所有子模組, 可以傳遞更新指定的子模組。

預設情況下,git pull命令會遞迴抓取子模組的更改,但並不會更新子模組,需要再執行:

$ git submodule update --init --recursive
如果想自動化次過程,可以給git pull命令傳遞--recurse-submodules選項:

$ git pull --recurse-submodules
如果總是想以--recurse-submodules拉取,可將submodule.recurse設定為true。這會讓 git 為除clone外所有支援--recurse-submodules的命令使用該選項。

子模組的url變動

如果子模組的 url 發生變動,即與.gitmodules檔案中的 url 不同。此時拉取子模組會失敗,需執行git submodule sync

$ git submodule sync --recursive

$ git submodule update --init --recursive

如果我們同時在主專案和子模組中提交了更改,但忘記了推送子模組的改動,會導致其他開發人員無法更新子模組。為了確保不發生這種情況,可以讓 git 在推送主項目前檢查所有子模組是否已推送。

git push命令可以傳遞--recurse-submodules=check|on-demand|only|no選項,你也可以執行git config push.recursesubmodules check|on-demand|only|no設定預設行為。

子模組遍歷

子模組有個foreach命令,它可以在所有子模組中執行任意命令。如果專案中包含大量子模組,這將會非常有用。

$ git submodule foreach "git pull"

entering 'themes/xiamu-matery'

already up to date.

一些有用的別名

當你不想輸入十分冗長的命令又不想設定預設選項時,可以設定一些有用的 git 別名:

$ git config alias.sdiff "!git diff && git submodule foreach 'git diff'"

$ git config alias.spush "push --recurse-submodules=on-demand"

$ git config alias.supdate "submodule update --remote --merge"

當你遇到諸如以下報錯時,也可嘗試刪除並重新初始化子模組。

fatal: '***' already exists in the index

fatal: '***' already exists and is not a valid git repo

fatal: could not get a repository handle for submodule '***'

git子模組使用

如下專案有多個標紅的子模組 1 首先進入每個子模組目錄,init初始化子模組倉庫,然後提交遠端。2 在每個子目錄都初始化好倉庫後,進入lv qggz主目錄,只初始化該倉庫,然後依次新增子模組的倉庫位址,命令如下 git submodule add 最後將主倉庫提交到遠端 3 轉殖主倉庫 將主倉庫cl...

Git工具 子模組

在專案上工作時,如果需要在其中引用另外乙個專案 第三方庫或者其他 可以通過子模組來處理這個問題。子模組允許將乙個git倉庫作為另外乙個git倉庫的子目錄.拉取 git submodule add git web path filename 會生成乙個.gitmodules配置檔案,這個檔案記錄了子專...

Git操作 子模組

在專案開發中,我們會整理出一些通用的邏輯,也可能是一下底層的工具包,這些邏輯一般情況下會用在多個專案中,那麼我們如何保證這些通用邏輯在多個專案中保持一致呢,git提供了子模組的方式來實現這個功能。首先我們要做的把通用邏輯放到git版本庫中進行管理,其他專案只要把這個專案當做子模組給管理起來,你就可以...