在 Git 中管理和儲存大型檔案

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Git 有助於保持原始程式碼的使用量很小,因為很容易挑選版本之間的差異,而且程式代碼很容易壓縮。 大型檔案無法妥善壓縮,而且在儲存在 Git 存放庫中時,會在版本之間完全變更(例如二進位檔)存在問題。 Git 的快速效能來自於其處理和切換至本機記憶體中檔案的所有版本的能力。

如果您的存放庫中有大型且無法變動的檔案(例如二進位檔),則每次認可變更時,都會在存放庫中保留這些檔案的完整複本。 如果存放庫中有許多版本的這些檔案存在,它們會大幅增加簽出、分支、擷取和複製程式代碼的時間。

您應該在 Git 中儲存哪些類型的檔案?

認可原始程式碼,而非相依性

當小組使用編輯器和工具來建立和更新檔案時,您應該將這些檔案放入 Git 中,讓您的小組享有 Git 工作流程的優點。 請勿將其他類型的檔案認可至存放庫:例如,DLL、連結庫檔案,以及小組未建立的其他相依性,但您的程式代碼相依於。 透過 套件管理 將這些檔案傳遞給您的系統。

套件管理會組合您的相依性,並在部署套件時在您的系統上安裝檔案。 套件已設定版本,以確保在某個環境中測試的程式代碼會在另一個環境中執行相同,只要環境已安裝相同的套件。

不要認可輸出

請勿認可來自組建和測試的二進位檔、記錄、追蹤輸出或診斷數據。 這些是來自程式代碼的輸出,而不是原始程式碼本身。 透過 工作項目追蹤 工具或小組檔案共用,與小組共享記錄和追蹤資訊。

在 Git 中儲存小型、不常更新的二進位來源

不常更新的二進位來源檔案有相對較少的認可版本。 如果檔案大小很小,則不會佔用太多空間。 Web、圖示和其他較小藝術資產的影像可能屬於此類別。 最好將這些檔案與其餘來源儲存在 Git 中,讓小組可以使用一致的工作流程。

重要

即使小型二進位檔經常更新,也會造成問題。 例如,對 100 KB 二進位檔所做的 100 個變更會使用 10 個變更至 1 MB 二進位檔的記憶體。 由於更新的頻率,較小的二進位檔會比大型二進位檔更慢的分支效能。

請勿認可大型且經常更新的二進位資產

Git 會管理檔案的一個主要版本,然後只儲存與該版本的差異,這在稱為 「委派」的程式中。 委派和檔案壓縮可讓 Git 將整個程式代碼歷程記錄儲存在本機存放庫中。 大型二進位檔通常會在版本之間完全變更,而且通常已經壓縮。 由於版本之間的差異很大,因此 Git 難以管理這些檔案。

Git 必須儲存每個檔案版本的整個內容,並難以透過委派和壓縮來節省空間。 儲存這些檔案的完整版本會導致存放庫大小隨著時間增加。 增加的存放庫大小可減少分支效能、增加複製時間,以及擴充記憶體需求。

使用大型二進位原始程序檔的策略

  • 請勿認可壓縮的數據封存。 最好取消壓縮檔案,並認可可變動的來源。 讓 Git 處理壓縮存放庫中的數據。
  • 避免認可編譯的程式代碼和其他二進位相依性。 認可來源並建置相依性,或使用套件管理解決方案來設定版本,並將這些檔案提供給您的系統。
  • 以可變動的純文本格式儲存組態和其他結構化數據,例如 JSON。

什麼是 Git LFS?

當您有版本與頻繁更新之間有較大差異的來源檔案時,您可以使用 Git 大型檔案 儲存體 (LFS) 來管理這些檔案類型。 Git LFS 是 Git 的延伸模組,可提供數據來描述認可存放庫中的大型檔案。 它會將二進位檔內容儲存在個別的遠端記憶體中。

當您複製並切換存放庫中的分支時,Git LFS 會從該遠端儲存體下載正確的版本。 您的本機開發工具會以透明方式處理檔案,就像是直接認可至存放庫一樣。

福利

Git LFS 的優點是,不論小組建立的檔案為何,您的小組都可以使用熟悉的端對端 Git 工作流程。 LFS 會處理大型檔案,以防止它們對整體存放庫造成負面影響。 此外,從 2.0 版開始,Git LFS 可支援檔案鎖定,以協助小組處理大型、無法差異的資產,例如影片、音效和遊戲地圖。

Azure DevOps Services 中完全支援 Git LFS 且免費。 若要搭配 Visual Studio 使用 LFS,您需要 Visual Studio 2015 Update 2 或更新版本。 只要遵循 指示來安裝客戶端、設定本機存放庫上檔案的 LFS 追蹤,然後將變更推送至 Azure Repos。

限制

Git LFS 有一些缺點,您應該先考慮再採用它:

  • 您的小組所使用的每個 Git 用戶端都必須安裝 Git LFS 用戶端,並瞭解其 追蹤設定
  • 如果未正確安裝並設定 Git LFS 用戶端,當您複製存放庫時,將不會看到透過 Git LFS 認可的二進位檔。 Git 會下載描述大型檔案的數據(這是 Git LFS 對存放庫的認可),而不是二進位檔。 認可未安裝 Git LFS 用戶端的大型二進位檔會將二進位檔推送至存放庫。
  • Git 無法合併兩個不同版本的二進位檔變更,即使這兩個版本的父系是同一個也不行。 如果有兩個人同時處理相同的檔案,他們必須合作協調自己的變更,以免覆寫其他人的工作。 對此,Git LFS 提供了檔案鎖定。 在開始工作之前,使用者仍必須小心地一律提取二進位資產的最新複本。
  • Azure Repos 目前不支援在存放庫中搭配 Git LFS 追蹤的檔案中使用安全殼層 (SSH)。
  • 如果使用者透過 Web 介面將二進位檔拖曳至針對 Git LFS 設定的存放庫,則二進位檔會認可至存放庫,而不是透過 Git LFS 用戶端認可的指標。
  • 雖然沒有嚴格的檔案大小限制,但伺服器的可用可用空間和目前的工作負載可能會限制效能和功能。
  • 一個檔案上傳的時間限制為一小時。

File format

寫入 Git LFS 追蹤檔案存放庫的檔案,每一行都有幾行索引鍵/值組:

version https://git-lfs.github.com/spec/v1
oid a747cfbbef63fc0a3f5ffca332ae486ee7bf77c1d1b9b2de02e261ef97d085fe
size 4923023

注意

針對版本值所包含的 GitHub URL 只會定義 LFS 指標檔案類型。 這不是二進位文件的連結。

已知問題

如果您使用 2.4.0 之前的 LFS 版本搭配 Azure DevOps Server,則需要額外的設定步驟,才能 透過 NTLM 進行驗證,而不是 Kerberos。 從 LFS 2.4.0 起,此步驟已不再需要,強烈建議您升級。