Git submodule的使用
最近在做一個上傳的客戶端,上傳的部分由后端同學以 SDK 的方式提供,因此該 SDK 是在一個獨立的倉庫,那么對于客戶端該如何方便的集成該 SDK 呢?每次 SDK 更新把代碼拷貝到客戶端倉庫?把 SDK 發布到 npm?這就可以考慮用 git 的 submodule。
什么是 submodule
submodule 是一個多項目管理工具,它允許將子項目以獨立的 git 項目添加到主項目,而主項目以 submodule 的形式擁有子項目。子項目擁有自己的 commit、push、pull,而與主項目互不干擾。主項目只需要記錄子項目的地址和所需要的 commit id,通過地址和 commit id 就能夠得到對應的子項目。
添加 submodule
通常情況下,我們都有一個主項目(MainProject),在 MainProject 文件夾下執行如下命令,即可添加 submodule。
/*url: 子項目遠程地址或本地地址path: 子項目路徑,可省略 */ $ git submodule add [url] [path] 例: git add submodule git@github.com:fengyueran/UploaderSDK.git ./src/UploaderSDK 復制代碼git status 可以看到如下信息
On branch masterChanges to be committed:new file: .gitmodulesnew file: UploaderSDK 復制代碼可以看到多了兩個文件: .gitmodules 和 UploaderSDK。 cat .gitmodules 看到.gitmodules 儲存了 submodule 的路徑及遠程地址。
[submodule "src/uploaderSDK"]path = src/uploaderSDKurl = git@github.com:fengyueran/UploaderSDK.git 復制代碼UploaderSDK 的內容為 submodule 的 commit id。
Subproject commit 6b53e1840b27ca1587b96c1eb9dd5f4ff0866089 復制代碼不難想象通過.gitmodules 和 UploaderSDK 的信息就可以拿到 submodule 的內容了,因此我們需要提交這個兩個文件。
git add . git commit -m "add submodule" 復制代碼克隆帶有 submodule 的項目
主要有兩個方式
1. 采用先克隆后更新的方式
和想象中的不一樣,直接 clone 主項目,submodule 并不會跟著 clone 下來,而只有包含 submodule 名的空文件夾。
1)$ git clone git@github.com:fengyueran/MainProject.git 復制代碼需再執行如下命令
2)$ git submodule init 復制代碼輸出如下,可以看到該命令給子項目注冊了路徑,即在主項目中的位置。此時,uploaderSDK 文件夾仍未空。
Submodule 'src/uploaderSDK' (git@github.com:fengyueran/UploaderSDK.git) registered for path 'src/uploaderSDK' 復制代碼再執行
//該命令并不是直接更新到最新的submodule commit,而是更新至主項目所存儲存的commit(有可能是較舊的commit)。 3)$ git submodule update 復制代碼輸出如下,可以看到 sumodule 得到更新,更新到主項目存儲的 submodule commit,是一個游離的 git header。
Cloning into '/Work/test/MainProject/tmp/MainProject/src/uploaderSDK'...Submodule path 'src/uploaderSDK': checked out '6b53e1840b27ca1587b96c1eb9dd5f4ff0866089' 復制代碼2. 采用遞歸參數--recursive
git clone git@github.com:fengyueran/MainProject.git --recursive 復制代碼輸出如下,可以看到主項目包括 submodule 都被 clone 下來了。
Cloning into 'MainProject'... remote: Counting objects: 7, done. remote: Compressing objects: 100% (4/4), done. Receiving objects: 100% (7/7), done. remote: Total 7 (delta 0), reused 4 (delta 0), pack-reused 0 Submodule 'src/uploaderSDK' (git@github.com:fengyueran/UploaderSDK.git) registered for path 'src/uploaderSDK' Cloning into '/Work/test/MainProject/tmp/MainProject/tmp/MainProject/src/uploaderSDK'... Submodule path 'src/uploaderSDK': checked out '6b53e1840b27ca1587b96c1eb9dd5f4ff0866089' 復制代碼修改更新 submodule
主要有兩種情況
1. 直接在主項目中的 submodule 下修改
如上例,直接在 MainProject 下的 src/uploaderSDK 中修改,uploaderSDK 切換到工作分支,修改并提交后,可以 checkout 到最新的 commit,也可以不切,反正都在當前最新的 commit 上(如果想測試其他 commit 也可以切換到相應 commit 上),此時 MainProject 中我們可以看到 src/uploaderSDK 的 commit 有如下變化
-Subproject commit 6b53e1840b27ca1587b96c1eb9dd5f4ff0866089 +Subproject commit a4d6dc0457673a275b1f6cbeda6f8ff23293b9de 復制代碼a4d6 為修改的提交,需要注意的地方是此時 submodule 已經在最新的 commit 上了,不要再在 MainProject 中 git submodule update 進行更新了,如果進行此操作 submodule 又會回到原來的 commit(帶有減號的 commit),只需要在 MainProject 提交,并在必要的時候 push 到遠程倉庫。這種方法,非 submodule 的開發人員就不用關心 submodule 是否更新了,只需要在 MainProject 下 pull 代碼發現 submodule 有更改時執行 git submodule update(更新為帶減號 commit)進行更新,前提是其他開發人員提交了正確的 submodule commit。
2. 在 submodule 自己獨立的倉庫進行修改
在工作目錄克隆下 submodule 的倉庫,切換到工作分支進行修改提交并 push 到遠程倉庫。這種方法需要 submodule 開發人員告訴 MainProject 的開發人員 submodule 有更新或主動查看是否有更新,有更新時就在 MainProject 的 src/uploaderSDK 下 pull 遠程代碼(需要知道 submodule 的工作分支),快速合并后,uploaderSDK 的 commit 有如下變化,此時同 1 不要 git submodule update,而只是在 MainProject 下提交這個更改。
-Subproject commit f4573cc1bb50000779202c7f56a640b1ffc075cb +Subproject commit 64ae6d149c0f6e3b06b8cea262c6126a7bc0887f復制代碼刪除 submodule
執行如下命令
總結
以上是生活随笔為你收集整理的Git submodule的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【leetcode】109. Conve
- 下一篇: vim-快捷键一览表