git 子模塊 submodule


文檔

https://git-scm.com/book/zh/v2/Git-工具-子模塊

為什么需要子模塊

觀察項目 https://github.com/develon2015/MultiModule, 它依賴一個子模塊 https://github.com/develon2015/MySpringBoot.
如果主項目在開發過程中需要導入該依賴模塊, 那么直接通過HTTPS協議克隆該子模塊並注冊到配置文件:

git submodule add https://github.com/develon2015/MySpringBoot MySpringBoot

下載完成后, 在根項目下將生成一個.gitmodules文件, 同時在MySpringBoot目錄下沒有.git目錄, 而是被初始化在根目錄下的.git/modules/MySpringBoot目錄下:
取而代之的是一個.git文本文件:

$ cat .gitmodules
[submodule "MySpringBoot"]
        path = MySpringBoot
        url = https://github.com/develon2015/MySpringBoot
$ cat MySpringBoot/.git
gitdir: ../.git/modules/MySpringBoot

這意味着無法提交MySpringBoot項目, 只能在別的目錄下克隆MySpringBoot的git協議版本, 修改並提交, 然后回來拉取MySpringBoot:

git submodule update # 下載或更新子模塊

顯然這只適合大部分模塊使用者, 因為對於這些模塊的完全開發者來說, 這不方便提交同時開發.

怎解?

我們假設兩個項目都是git協議的git項目, 它們都已開發完畢, 正准備提交.
首先按正常流程提交子模塊MySpringBoot, 這不會有任何問題.
接下來, 我們回到根項目, 添加跟蹤文件:

$ git add MySpringBoot
warning: adding embedded git repository: MySpringBoot 警告:添加嵌入式git存儲庫:MySpringBoot
hint: You've added another git repository inside your current repository. 提示:您已在當前存儲庫中添加了另一個git存儲庫。
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it. 提示:外部存儲庫的克隆將不包含嵌入式存儲庫的內容,並且不知道如何獲取它。
hint: If you meant to add a submodule, use: 提示:如果要添加子模塊,請使用以下命令:(大謬, 這根本不是添加, 而是"下載")
hint:
hint:   git submodule add <url> MySpringBoot
hint:
hint: If you added this path by mistake, you can remove it from the 
hint: index with: 提示:如果您錯誤地添加了此路徑,則可以使用以下方法將其從索引中刪除:
hint:
hint:   git rm --cached MySpringBoot
hint:
hint: See "git help submodule" for more information.

git會自動識別, MySpringBoot會被識別為子模塊, 只是尚不知道該git項目的URL, 有證:

$ git submodule init
fatal: No url found for submodule path 'MySpringBoot' in .gitmodules

其實, 我們只需要手動創建一個.gitmodules文件並編輯即可:

echo '[submodule "MySpringBoot"]
        path = MySpringBoot
        url = https://github.com/develon2015/MySpringBoot
' >> .gitmodules

接下來追蹤.gitmodules, 提交即可, 有證:

$ git submodule init
$ git submodule update
Submodule path 'MySpringBoot': checked out 'f51923868b34a546dec942b8b8bfea4065fc2e95'

克隆含有子模塊的git項目

第一種方法, 先直接克隆, 然后初始化本地配置文件后更新子模塊:

$ git clone https://github.com/develon2015/MultiModule
Cloning into 'MultiModule'...
$ git submodule init # 初始化本地配置文件
Submodule 'MySpringBoot' (https://github.com/develon2015/MySpringBoot) registered for path 'MySpringBoot'
$ git submodule update # 下載或更新子模塊
Submodule path 'MySpringBoot': checked out '89e2ef897b61ec077cfafb2da2b116daf1c97e57'

第二種方法, 克隆項目時傳遞--recurse-submodules參數:

git clone --recurse-submodules https://github.com/develon2015/MultiModule

注意!

子模塊是一種快照模式, 應當十分注意, 避免上傳臟快照和沒有提交的快照.
臟快照: 提交后有更改
沒有提交的快照: 提交后沒有push, 最后又--amend之后再提交

$ git diff
diff --git a/MySpringBoot b/MySpringBoot
index d9764bc..f519238 160000
--- a/MySpringBoot
+++ b/MySpringBoot
@@ -1 +1 @@
-Subproject commit d9764bc3955fadae9805dee7e9bf5d96167a4c46 # 沒有提交的快照
+Subproject commit f51923868b34a546dec942b8b8bfea4065fc2e95-dirty # 臟快照, 有未提交同時未忽略的文件
  [22:12:22] Administrator@ /cygdrive/d/Code/Projects/MultiModule

$ cd MySpringBoot && git log
commit f51923868b34a546dec942b8b8bfea4065fc2e95 (HEAD -> master, origin/master, origin/HEAD)
Author: develon_cyg <gitee@foxmail.com>
Date:   Sat Aug 22 19:24:01 2020 +0800

    提交API
    JsonConfig
    Logger
    Shell

commit ba7d42d6817ace449a009041c39d5b9f2a1badc6
Author: develon_cyg <gitee@foxmail.com>
Date:   Sat Aug 22 19:21:42 2020 +0800

    修改README.md
    構建DSL從Kotlin修改為Groovy

commit e74763c2d29622a86afa54338ed6b275afc35444
Author: develon2015 <develon@qq.com>
Date:   Tue Aug 18 17:18:03 2020 +0800

    first commit

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM