Git 如何處理大倉庫

2021-07-28 01:51:03 字數 2501 閱讀 3396

git 是追蹤**庫演進的最佳選擇,並且它能讓你與你的同事間高效協作。當你想要追蹤的庫非常巨大時會發生什麼?

在這篇文章裡,我會嘗試著給你一些想法和技巧來恰當地處理不同種類的大倉庫。

如果仔細想想,大概會有兩種導致倉庫大規模增長的原因:

因此,倉庫的增長有兩個維度的方向:工作目錄的尺寸——例如:最近一次提交,和整個累積歷史的尺寸。

有時第二種問題會與老的過時的二進位制生成的東西(artifact)混合,它們都被放在倉庫中,不過這類問題是比較容易處理的——如果它們很討厭,就覆蓋它們,見下文。

上述兩種場景需要的技巧和解決方案是不同的——儘管有時候需要互補——讓我們分別來處理它們吧。

將乙個庫視為大規模庫的界線非常高 - 比如 linux 核心的最後乙個版本記錄了超過 1500 萬行**,但人們仍然願意完整閱讀 - 由於監管/規定方面的原因,某些很老的專案仍然需要保持完整,轉殖它們是件痛苦的事情(現在通過拆分 linux 庫的方式使其結構清晰,它被拆分為歷史庫和最近時期的庫,需要通過嫁接設定來訪問完整的歷史記錄)。

為了更快、更節省開發者和系統時間也更節約磁碟空間,第乙個解決辦法是使用 git 進行淺轉殖。通過淺轉殖可以只轉殖某個庫最後的歷史記錄。

怎麼做到?只需要使用 --depth 選項,比如:

git clone --depth depth remote-url

想像一下,如果你的專案庫中積累了 10 年甚至更長時間的歷史記錄 - 比如 jira 是我們往 git 遷移的乙個 11 年的老庫 - 累積節約的時間非常顯著。

完整的轉殖 jira 有 677 mb,如果包含工作目錄還有另外的 320+ mb,總共超過 47,000 多次提交。通過淺轉殖的方式檢出 jire 需要 29.5 秒,而檢出完整的歷史記錄則需要 4 分 24 秒。隨著時間地推移及專案二進位制資產的增長,這個差距也會成比例的增長。任何情況下,構建系統都會大大受益於這種技術(指淺轉殖)。

最近 git 改善了對淺轉殖的支援

過去淺轉殖就像 git 世界裡的殘障人士一樣,某些操作並未得到支援。不過最近的版本 (1.9+) 對此有著顯著的改善,現在甚至可以適當的對淺轉殖庫使用 pull 和 push 操作。

巨大的庫往往存在著大量錯誤的提交或無用的資源,對此,使用 filter-branch 是個很好的解決辦法。這個命令可以根據預先定義的模式對專案歷史進行過濾、整理、修改,甚至跳過一些檔案。它是 git 工具集中的乙個非常強大的工具。目前已經有指令碼可以用於識別 git 庫中的大型物件,所以它使用起來非常容易。

使用 filter-branch 的示例:

git filter-branch --tree-filter 'rm -rf /path/to/spurious/asset/folder' head

filter-branch 有乙個小小的缺點:一旦使用了 filter-branch,實際上已經重寫了整個專案歷史,因此每次提交的 id 都會發生變化。這要求每個開發者都要重新轉殖更新後的庫。

所以,如果你打算使用 filter-branch 來進行一次清理行動,應該警告你的團隊,計畫乙個短期的凍結來進行操作,然後通知大家重新轉殖庫。

從 2012 年 4 月發布的 git 1.7.10 開始,你可以通過只轉殖某乙個分支來限制歷史記錄的數量,就像這樣:

git clone url --branch branch_name --single-branch [folder]

對於長期執行分發的分支,或者你在有很多分支的情況下,這個特殊的技巧都非常有用。如果你只有極少數分支,那這個辦法不會帶來顯著的效果。

第二類大型倉庫中的**含有巨大的二進位制資產。遊戲團隊要處理巨大的 3d 模型,web 開發團隊需要跟蹤影象資產,cad 團隊可能需要操作和跟蹤二進位制交付物的狀態。所以有各種不同的軟體團隊在使用 git 的過程中會遇到這樣的問題。

涉及到哪些命令呢? 示例如下(credit):

echo src/ ? .git/info/sparse-checkout

之後,你可以使用正常的 git 命令了,但你的工作目錄將只包含你指定的資料夾。

還有另一種處理二進位制資產目錄的的方法,就是把它們拆分到乙個單獨的庫,然後在主專案是通過把它拉取為子模組。使用這種方法你可以控制資產的更新。需要了解子模組,可以看看:核心概念與技巧和另乙個選擇。

如果你想繼續使用子模組的方法,你可能需要檢查專案依賴的複雜性。我提到的方法對解決大型二進位制檔案問題會有所幫助。

git 中處理二進位制資產的第3個選擇依靠第三方擴充套件。

我要說的第乙個擴充套件是 git-annex,它可以使用 git 管理二進位制檔案,但不需要把檔案內容檢入庫中。git-annex 使用乙個特殊的鍵值庫來儲存檔案,然後將符號鏈結像普通檔案一樣檢入 git 庫中進行版本管理。這種用法非常直接,還有一看就能明白的例子。

第二個擴充套件是 git-bigfiles,乙個 git 分支,適合於使用 git 分享專案大檔案的人。

不要因為你的庫有著巨大的歷史記錄或巨大的資產就放棄 git。這兩個問題都可以得到解決。

git 同步超大倉庫失敗的解決辦法

git 同步超大倉庫的時候,會報如下錯誤 git fetch error git upload pack git pack objects died with error.ib s fatal git upload pack aborting due to possible repository c...

git 如何處理換行符? CRLF LF

carriage return 回車符 r line feed 換行符 n 在windows環境中,換行符是crlf,也就是 r n,但是在linux環境中,換行符是lf,也就是 n。git在維護版本庫的時候統一使用的是lf,這樣就可以保證檔案跨平台的時候保持一致。在linux下預設的換行符也是lf...

如何處理DDoS

ddos 簡述 ddos是分布式拒絕服務 distributed denial of service 的英文縮寫,其 方式通常是利用很多受 者控制的 殭屍主機 向目標主機傳送大量看似合法的資料報,從而造成主機資源被耗盡或網路被堵塞,導致主機無法繼續正常提供服務。ddos通常可以分為兩類,即資源耗費式...