之前大概知道git 很早以前就有這個功能了,但直到最近在公司上才開始比較有在使用它,也趁這個機會好好的做個筆記,這樣之後就可以直接參考這個筆記就好了。
簡介
Submodule
主要的用途是用來把專案中,會需要共用的程式碼獨立出去成單獨的一個git repo,然後,目前的repo就只是使用其submodule的某一個版本(commit) 而已。
目前專案上碰到的一個需求,就是有多個服務可能會同時需要連接同一個資料庫(SOA 架構);在這樣的情況下,如果我們需要修改DB Migration Schema時,就很有可能需要在每個repo中增加對應的SQL檔案了,這樣其實蠻容易出錯的,也違反了DRY原則。
Git submodule 就很適合用來解決這個問題,我們可以直接把這些DB Migration SQL獨立出來成一個git repo,而任何有需要用到這個資料庫的服務,都可以把這個DB Migration SQL Repo 新增至目前服務下的submodule,這樣,我們只需要讓每個服務Migration SQL Repo 都一直在最新的版號(commit)就好了。
常用的Git submodule 指令
在這邊順便記錄一下,目前常常會用到的一些submodule 指令。
新增submodule 至目前的repo
下面這個指令,可以把github上的repo git@github.com:github-account/github-project.git
新增到目前git repo下成為一個submodule。
git submodule add git@github.com:github-account/github-project.git the-submodule-name-in-the-repo
在用上面的指令新增完submodule以後,我們目前的git repo 下就會多了2個unstashed的檔案: .gitmodules
與 the-submodule-name-in-the-repo
,為了完成新增這個submodule,我們還必須git add
與 git commit
這2個檔案。
Clone 一個有submodule的git repo
當如果要clone 一個有submodule的repo時,會需要在clone時帶--recurse-submodules
的flag,不然那些submodule 就不會順便被clone 下來,而會呈現是空資料夾。
git clone git@github.com:github-account/git-parent-repo.git --recurse-submodules
Clone 目前repo裡面的submodule
假設我們在最初clone repo時,就沒有帶 --recurse-submodule
時,這樣我們如果要在另外clone 那些submodule時,就會需要用下面的指令去做
git submodule update --init
更新目前repo下所有submodule 的版本
當目前repo下的submodule被更新時,我們會需要透過下面的指令去把所有submodules 都更新,在更新完了以後,我們還會需要在做git add
與 git commit
來綁定目前repo所對應的submodule 版本。
git submodule update --recursive --remote
更新特定submodule的版本
若只是要更新某一個submodule的版本的話,我們可以透過下面的指令來更新
cd submodule-folder/
git checkout branch-name
git pull
移除特定的submodule
移除submodule 比較麻煩點,需要依序執行下面的幾個步驟:
從目前的git version,新增一個移除submodule 的變動
git rm --cached /submodule_folder
rm -rf /submodule_folder
從.gitmodules中移除剛剛已移除的submodule
vim .gitmodules
# then remove the related contents
最後要再移除.git/config中的那個submodule的相關資訊
vim .git/config
# then remove the related contents