Git Submodule的使用
前言
在公司的專案使用Git進行管理,不過因為還使用了其他submodule,有時候在版本或branch之間切換後,沒有同步更新submodule就可能導致build fail,這邊紀錄一下相關指令與使用時機。
測試環境
在我的環境中建立三個目錄,分別代表遠端repository(remoteRepo)、專案目錄(Project),以及Submodule目錄。
要在local端建立空的repository,可以使用bare參數:
1 |
|
接著我們先在submodule目錄下進行git初始化,並且新增一個檔案:file_ver_1,代表submodule的第一版,最後將這個變更進行提交。
1 |
|
然後在Project目錄中,將git初始化後,加入一個檔案:main_ver_1,並且使用submodule add將submodule加入專案中,最後當然也要將變更進行提交。
這邊我們也將完成的專案push到我們建立的repository中。
1 |
|
可以留意在我們加入submodule之後,git會自動幫我們產生一個隱藏檔:.gitmodules,裡面記錄的就是submodule的位置資訊,實務上這個url內容應該為其他遠端的repository,這邊只是為了方便,先用local的位置進行說明。
此時我們再回到submodule的目錄中,將檔案更新為:file_ver_2並提交,如此可以營造出”專案目錄中的submodule並非最新版”的情況。
1 |
|
到這邊我們的測試環境已經準備好,整理一下內容如下圖,我們有一個專案(Project),包含一個版本1的submodule,而實際來源的submodule最新的版本為2。
flowchart TB
subgraph Submodule
file_ver_2
end
subgraph Project
main_ver_1
subgraph submodule
file_ver_1
end
end
專案的clone
在clone專案的時候,若要連同submodule一起clone的話,可以加上recurse-submodules參數。
1 |
|
可以看到clone下來的project會包含submodule,且內容為第1版。
更新所有submodule
此時,若想要將submodule更新到最新版,若單純在專案中執行git pull並不會更新submodule,需要自行進入submodule執行git pull。
不過可以透過foreach搭配recursive來自動完成這個工作。
1 |
|
這個指令會遞迴走訪所有submodule,並執行git pull。
可以看到執行完畢後,專案中的submodulde內容已經更新為版本2。
與專案同步所有submodule
若不幸發生將submodule更新到最新版之後,反而因為相容性之類的問題導致build fail的情況,可能會想要將專案中的submodule全部還原到原先clone下來的狀態。
更精準的來說,就是還原到主專案原先搭配的submodule版本,此時可以透過submodule update來達成。
1 |
|
可以看到submodule已經還原回原先的版本1。
值得注意的是訊息中顯示checked out的hash值,實際上可以對應到submodule commit ID,意思就是當你在專案中加入submodule時,其實git是紀錄了submodule對應的commit ID。
除了還原的狀況外,在專案管理者更新了submodule後,你想要同步自己local端的submodule時也可以使用這個指令進行submodule的更新。
專案更新submodule時
前面提到加入submodule時,其實是紀錄了commit ID,因此要留意的是,若你是專案管理者,當更新submodule之後也要重新進行commit/push,如此才能確保專案紀錄的是對的submodule版本。
1 |
|
更新後的submodule內容為版本2。
此時,其他clone專案的使用者,可以透過submodule update來同步更新submodule。
1 |
|
同步submodule位置
最後一種狀況是如果submodule更改了repository位置,此時可以透過submodule sync來更新git的config檔內容。
例如將submodule更改位置為Submodule_new_location:
1 |
|
更新project中的submodule path:
1 |
|
此時若其他原先clone下來的project要進行submodule的git pull會找不到路徑:
透過git submodule sync指令可以自動更新config檔內的路徑。
1 |
|
可以看到config檔內的路徑已經更新,此時再進行submodule的git pull就不會有問題。
1 |
|