git的submodule功能詳解 html
項目的版本庫在某些狀況下須要引用其餘版本庫中的文件,例若有一套公用的代碼庫,能夠被多個項目調用,這個公用代碼庫能直接放在某個項目的代碼中,而是要獨立爲一個代碼庫,那麼其餘要調用公用的代碼庫該如何處理?分別把公用的代碼庫拷貝到各自的項目中會形成冗餘,丟棄了公共代碼庫的維護歷史,這些顯示不是好的辦法,如今要了解的git子模組(git submodule)就解決了這個問題。 git
Git 子模塊功能容許你將一個Git倉庫看成另一個Git倉庫的子目錄。這容許你克隆另一個倉庫到你的項目中而且保持你的提交相對獨立。 gitlab
首先須要兩個版本庫例如: spa
1) 一個公共的版本庫(例如:libA.git) orm
git@gitlab.szreach.com:fengyang/liba.git htm
2) 一個引用公共版本庫的主版本庫(例如:super.git) 索引
git@gitlab.szreach.com:fengyang/super.git get
在須要做添加子模組的Git版本庫中右擊,選擇「TortoiseGit->Submodule Add...」,在「Repository:」裏面輸入須要添加子模組的版本庫路徑,在「Path:」 it
中輸入添加子模組存放的目錄路徑。以下圖所示: io
|
此時查看須要添加子模組的Git工做區的目錄結構。在根目錄下多了一個.gitmodules文件,而且公共代碼庫被克隆到lib/lib_a目錄下。
|
.gitmodules的內容記錄着含子模組存放的目錄路徑及子模組版本庫的路徑
|
注:此時工做區還沒有提交,完成提交後,子模組纔算正式完成在須要做添加子模組的Git版本庫中創立。
注:此主版本庫(super.git)就變成了一個包含子模組的版本庫。
克隆帶子模組的git庫,並不能自動將子模組的版本庫克隆出來,對於只關心項目自己的數據,而不關心項目引用的外部項目數據的用戶,這個功能很是好,數據沒有冗餘並且克隆的速度也很快。
在工做區中克隆主主版本庫後,會發現子模組的版本庫並無克隆,只有將存放子模組版本庫的目錄克隆下來了。
|
----:存放子模組版本庫的目錄路徑 |
若是須要克隆出子模組形式引用的外部庫,首先須要執行Submodule Update操做。
在須要做克隆子模組的Git工做區中右擊,選擇「TortoiseGit->Submodule Update...」,點擊「OK」便可。
|
執行Submodule Update...操做後就會把子模組的版本庫克隆下來。
|
當在主Git庫工做區中變動到達一個適當狀態時,咱們須要將這些變動提交到Git庫,做版本備份和跟蹤。
方法:
在工做區內右擊,選擇「 Commit-> "當前分支名稱" 」,在Commit窗口中,選擇須要提交的變動path,填寫提交說明,點擊「Ok」。
|
結論:在主git工做區做commit操做,只是將主Git工做區的變動歷史提交到主Git本地庫中,對Submodule沒有任何影響。
當在主Git庫工做區中想要切換到其餘某個分支、某個tag、某個commit歷史記錄。
咱們這裏舉個特殊的例子:
切換到某個commit歷史記錄(如在主版本庫中提交子版本庫的歷史記錄)
方法:
在Git工做區內的某目錄上右擊,選擇「Swicht/Checkout...」在Swicht/Checkout...Checkout窗口中,在Switch to Commmit中列出須要切換的commit歷史記錄,在此列表中選擇須要切換到的commit歷史記錄,之後點擊「Ok」按鈕。
|
|
注:因爲切換到的是在主版本庫中提交子版本庫的那條歷史記錄,所以子模組中狀態也會改換,也須要在子模組中執行切換。
執行Submodule Update操做便可。
|
當在主Git庫工做區中此次變動有錯誤時,就可使用revert操做來撤銷此次次操做。
方法:
在工做區內右擊,選擇「Revert」,在Revert窗口中,選擇須要撤銷的變動path,點擊「Ok」。
|
|
結論:在主git工做區做revert操做,只是將主Git工做區某次的變動操做給撤銷,這次操做以前的commit都會被保留,且對Submodule沒有任何影響。
當在主Git庫工做區中將主Git本地庫的數據推送到主Git遠程庫中。
方法:在工做區的目錄上(不要在文件上)右擊,選擇「Git Sync...」
"Local Branch","Remote Branch",「Remote URL」這3欄必須正確才能「推」數據。
|
結論:在主git工做區做push操做,只是將主Git本地庫的變動歷史推送到到主Git遠程庫中,對Submodule沒有任何影響。
當在主Git庫工做區中將主Git遠程庫的拉取到主Git本地庫中。
方法:在工做區的目錄上(不要在文件上)右擊,選擇「Git Sync...」
"Local Branch","Remote Branch",「Remote URL」這3欄必須正確才能「拉」數據。
|
結論:在主git工做區做pull操做,只是將主Git遠程庫的變動歷史拉取到到主Git本地庫中,對Submodule沒有任何影響。
在執行Submodule Update...操做更新出子模組後,都以某個具體的提交版本進行檢出,進入子模組目錄,會發現其處於非跟蹤狀態。
|
顯然這種狀況下,若是修改lib/lib_a下的文件,提交就會丟失。下面介紹如何在檢查的子模組中修改,以及如何更新子模組。
在子模組中切換到master分支(或者其餘想要修改的分支)後在進行修改。
l 切換到master分支,而後在工做區作一些改動。
|
l 執行commit後,而且推送到子模組庫中後。
l 回到主版本庫中。
在主版本庫中查看狀態,在主版本庫中能夠看到子模組已修改,包含了更新的提交。
l 須要將修改提交在主版本庫中進行推送。
|
當子模組版本庫中有新的提交歷史記錄,就須要作pull操做來更新。
|
注:對子模組庫中作了pull操做,同時須要對調用子模組庫的主版本庫中也要作Pull操做。
以下圖所示:
|
注意:進入子模組目錄,會發現其處於非跟蹤狀態。顯然這種狀況下,若是修改lib/lib_a下的文件,提交就會丟失。提示以下:
|
方法:
在工做區內目錄或文件上右擊,選擇「Delete(keep local)」,在Delete窗口中,點擊「Remove」。
Delete(keep local)把目錄lib/從git的索引庫中移除,可是對目錄lib/自己並不進行任何操做。
所以須要完全刪除。
刪除以下圖所示紅框的部門
|
http://www.kafeitu.me/git/2012/03/27/git-submodule.html