大型Git倉庫的部分克隆

隨著Git倉庫變得越來越大,由於性能導致的可用性問題會越來越突出。比如git clone一個大型倉庫會下載整個倉庫對象和每次迭代的副本,下載過程會非常耗時,耗帶寬,而且常常會導致中斷。為了解決這個問題通常有兩個方法:

第一個是方法是對倉庫從新規劃,把大的文件提取出來使用Git LFS保存。

大型Git倉庫的部分克隆

還有一個方法是Git shallow clone 淺克隆(--depth):這是git內置的唯一減少Git克隆傳輸數據量的方法。但是,Git淺克隆個缺點就是不允許對子項目進行過濾(這對於包含許多項目的整體倉庫很重要),也不允許按對象大小進行過濾,以防止不必要的大對象被下載。

Partial Clone部分克隆

大型Git倉庫的部分克隆

為了解決上述的淺克隆的限制,Git引入了部分克隆的功能。它是對現有Git克隆的性能優化,允許Git在沒有倉庫的完整副本的情況可以工作。它的目標是讓Git更好地處理超大型倉庫。部分克隆的功能在最近發佈的版本中已經Gitlab 12.4.0以beta版本形式發佈,具體可以參考蟲蟲關於Gitlab 12.4.0版本發佈介紹。

Git在克隆和獲取時候默認是全克隆,即會下載完整的git對象庫和倉庫庫的歷史記錄(包括所有副本)。這包括所有commits對象,tree對象和blob對象。對於超大存儲庫,克隆可能需要數小時(或數天)的時間,需要100 + GiB的磁盤空間。在這些倉庫中,有很多blob(文件)和three(目錄)對象不是必須的,是考慮以下場景:

1.在tree對象的文件包含了很多非用戶工作區域文件。例如,一個倉庫在每次commits中都會包含500K的目錄和3.5M的文件。如果用戶只需要一個對象,我們不需要下載很多的tree對象的。

2.對的二進制文件。例如,在大型倉庫的構建中生成了一個巨大的二進制文件,我們需要忽略下載二進制大文件的的迭代歷史版本,只下載實際引用的版本。

部分克隆

使我們在克隆和獲取操作時候避免下載不需要的對象,從而減少下載時間和磁盤使用率。忽略掉的對象以後可以在需要時"按需獲取"。

我們把可以稍後提供缺少對象的遠程服務器叫Promisor Remote,它承諾在以下情況下發送對象要求。最初的Git僅支持一個Promisor Remote,即用戶克隆並在"extensions.partialClone"配置選項。

簡而言之,部分克隆的工作方式如下:

使用新的--filter標誌在clone或pull倉庫時將對象從傳輸中排除;

按需下載丟失的對象;

部分克隆配置

在GitLab 12.4中,如果依賴的Git版本為2.21.0,當使用功能標記來啟用uploadpack.allowFilter和uploadpack.allowAnySHA1InWant。

按大小排除對象

大型Git倉庫的部分克隆

部分克隆允許將大型對象直接存儲在Git倉庫中,並根據用戶的需要將其從克隆中排除。這減少了判斷需要哪些對象應該存儲在LFS中或那些不需要存儲在LFS的過程。使用部分克隆,對所有文件一視同仁,都可以直接存在倉庫中。

當Git服務器啟用uploadpack.allowFilter

和uploadpack.allowAnySHA1InWant兩個選項時候我們就可以按一下操作:

克隆倉庫,但是Blob對象大小不得大於1M(排除大小大於1M的blob對象):

git clone --filter=blob:limit=1m 

在克隆的checkout和之後的所有操作中,所需的任何blob將需要按需下載,比如:

git checkout feature-branch

按路徑排除對象

大型Git倉庫的部分克隆

部分克隆允許使用與倉庫文件忽略配置.gitignore類似的格式按路徑過濾克隆。

服務器啟用uploadpack.allowFilter和uploadpack.allowAnySHA1InWant後:

1.創建一個過濾器配置。例如,考慮一個包含許多應用程序的整體倉庫,每個應用程序都位於根目錄的不同子目錄中。使用GitLab Web界面創建文件

cc-app/.filterspec:
# App
cc-app/
#Dependencies
chongchong-app/
shared-component-a/

2、創建一個新的Git倉庫並用git fetch獲取。由於clone命令對"--filter=sparse:oid"的支持不完整,因此需要使用git init和git fetch來模擬clone命令:

為Git倉庫創建一個新目錄:

mkdir CCrebo && cd CCrepo

初始化一個新的Git倉庫:

git init

添加遠程倉地址

git remote add origin 

啟用對遠程服務器的部分克隆支持

git config --local extensions.partialClone origin

使用服務器的filterspec過濾對象的獲取:

git fetch --filter=sparse:oid=master:cc-app/.gitfilterspec origin

查看獲取的文件,缺少的一些我們尚未提取的對象

git rev-list --all --quiet --objects --missing=print | wc -l

IDE和Shell集成:與bash,zsh等的tit集成以及自動顯示狀態信息的編輯器通常運行git fetch獲取整個倉庫。需要手動禁用或重新配置。

稀疏檢出

必須啟用並配置稀疏簽出,以防止在checkout分支時自動下載來自其他路徑的對象。

啟用稀疏檢出:

git config --local core.sparsecheckout true

配置稀疏檢出:

git show master:snazzy-app/.gitfilterspec >> .git/info/sparse-checkout

檢出主分支

git checkout master 

總結

本文蟲蟲給大家介紹了一個git提高克隆性能的新技術部分克隆。目前該技術尚屬於技術探索階段,gitlab 12.4中也是beta版本,只供大家學習和嘗試,請不要再生產環境中使用。


分享到:


相關文章: