1. 程式人生 > 程式設計 >詳解git submodule使用以及注意事項

詳解git submodule使用以及注意事項

一、背景

在平時的軟體開發過程中常常會有這樣的場景,自己負責的某個模組會依賴其他模組或者第三方的library。這時你自己的模組是一個獨立的程式碼倉庫,你想要實現這樣一種功能,當你從你的模組的程式碼倉庫裡把程式碼拉到本地來的時候,能自動的將你依賴的模組或第三方庫都拉到指定的目錄當中去。

當然要實現這個功能的方法有很多,比如使用repo之類的工具,又比如如果你使用的是svn作為版本管理工具,那麼你可以使用svn的external機制來引用第三方的project。

這裡要說的是使用git作為版本管理工具的情況。

二、git submodule

其它的細枝末節就不再贅述了,咱直奔主題。

先來看具體用例:

目前有一個模組A,其程式碼倉庫的地址為:projectA.git, 它需要引用另一個模組B,其程式碼倉庫的地址為:projectB.git。

假設模組A的本地目錄為:projectA

希望引用模組B為模組A的子模組,其在模組A目錄下的路徑為: projectA/projectB

這裡我們通過git 的submodule機制來實現。

比如在命令列裡可以直接使用如下命令:

cd projectA
git submodule add projectB.git projectB

注: 這個submodule的 子目錄指定時不能以 “/”結尾, 比如上面的命令,就不能寫成 projectB/ 這個樣子。

就這麼簡單的一句git命令就可以搞定了,當然這還沒完,執行完這個命令之後,在projectA目錄執行git status命令,可以看到如下的結果:

詳解git submodule使用以及注意事項

這時需要使用git commit命令和git push命令,將新增模組B為模組A的子模組的結果push到模組A的程式碼倉庫裡面去。

三、git clone包含子模組的程式碼倉庫

此時,就可以使用git clone命令來抓取模組A的程式碼倉庫,但要同時抓取到子模組的倉庫的話,還需要一些方法:

正常的使用git clone命令,然後再使用 git submodule init 和git submodule update來獲取子模組

git clone projectA.git
cd projectA
git submodule init
git submodule update

其執行結果如下:

詳解git submodule使用以及注意事項

在使用git clone命令時,加上–recurse-submodules或–recursive 這樣的遞迴引數

git clone --recursive projectA.git

其執行結果如下:

詳解git submodule使用以及注意事項

四、tortoisegit操作submodule

如果是使用tortoisegit的話,也可以使用圖形化介面進行submodule的相關操作,如新增submodule就選擇如下圖所示的選單:

詳解git submodule使用以及注意事項

新增子模組的介面大概就是下面這個樣子:

詳解git submodule使用以及注意事項

這裡和上面一樣“path”一欄不能以”/”結尾。 填寫之後,點選OK,就會在主模組的目錄下新增對應的子模組。

在clone時也是一樣的,它既可以只是clone,然後用上面選單中,Submodule Update 選項來抓取子模組的內容,也可以在clone時選擇遞迴引數,如下所示:

詳解git submodule使用以及注意事項

五、忽略submodule中的修改或新增檔案

我們引用第三方的project,大多數情況都是想以“只讀”的方式引用,不關心第三方project抓取下來之後是不是被修改,或者是在其目錄中添加了untracked的file, 因為我們只是拉取第三方的project,而不會(往往時不能或不允許)對第三方project進行提交。

以上面的模組A和模組B的例子來說,如果模組A和模組B中都有進行修改,其結果可能就是如下這個樣子:

詳解git submodule使用以及注意事項

這並不是我們想要的結果。一開始的時候我的想法是使用 .gitignore 來忽略submodule的修改,但是無法做到,後來經過一番搜尋,終於找到了解決良藥。在添加了submodule之後,project的目錄下回生成一個.gitmodules檔案,這個檔案記錄了子模組的路徑和倉庫地址等資訊,如下圖所示:

詳解git submodule使用以及注意事項

我們要做的就是在[submodule “projectB”]中新增一個ignore子項,這個ignore子項可以有上個可選的值,untracked,dirty和all,它們的意思分別是:

  • untracked :忽略 在子模組B(也就是projectB目錄)新新增的,未受版本控制內容
  • dirty : 忽略對projectB目錄下受版本控制的內容進行了修改
  • all : 同時忽略untracked和dirty

這裡我們先選擇dirty(至少先保證不提交對子模組B的任何修改),其他的可以根據具體需求來進行選擇。

新增ignore子項之後的.gitmodules檔案的內容如下所示:

詳解git submodule使用以及注意事項

然後我們再使用git status檢視,可以得到圖下結果:

詳解git submodule使用以及注意事項

可以看出,之前 “modified: projectB(modified content)” 已經不見了, 此時對修改後的.gitmodules檔案進行commit和push, 之後在檢視status或做commit時就可以忽略掉對子模組B修改的部分了。

到此這篇關於詳解git submodule使用以及注意事項的文章就介紹到這了,更多相關git submodule使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!