Git代碼庫(kù)大文件歷史記錄的清理方法
引言
在日常開發(fā)中,我們可能會(huì)不小心將一些大文件(如二進(jìn)制文件、大型資源文件等)提交到 Git 倉(cāng)庫(kù)中。即使后來刪除了這些文件,它們依然存在于 Git 的歷史記錄中,導(dǎo)致 .git 目錄變得非常龐大,嚴(yán)重影響 git clone 和 git pull 的速度。
本文將介紹如何分析 Git 倉(cāng)庫(kù)的占用情況,并使用工具清理歷史記錄中的大文件。
問題分析
Git 倉(cāng)庫(kù)體積過大的主要原因通常是 .git/objects/pack/*.pack 文件過大。Git 將文件歷史記錄存儲(chǔ)在本地的 "database" 中,如果歷史記錄中包含了大量的二進(jìn)制文件變動(dòng),pack 文件就會(huì)迅速膨脹。
[!info] Git Internals - Packfiles Git 使用 packfile 來優(yōu)化存儲(chǔ)。詳情可參考:Git - Internals - Packfiles
第一步:找出大文件
在清理之前,我們需要先找出是哪些文件占用了大量空間。
1. 查看倉(cāng)庫(kù)大小
使用 git count-objects 命令可以查看倉(cāng)庫(kù)的打包對(duì)象數(shù)量和磁盤占用情況:
# -v: verbose, 顯示詳細(xì)信息 # -H: human-readable, 以人類可讀的格式顯示大小 git count-objects -v -H
2. 查找 Packfile 中最大的對(duì)象
我們可以通過 git verify-pack 命令查看 packfile 中的對(duì)象詳情,并按大小排序找出最大的幾個(gè) blob 對(duì)象:
# 查看 .git/objects/pack/ 下的 .idx 文件 # sort -rn -k 3: 按第3列(size)倒序排列 # head -10: 取前10個(gè) git verify-pack -v .git/objects/pack/*.idx | sort -rn -k 3 | head -10
輸出結(jié)果格式如下:
# SHA-1 (Blob ID) | type | size | size-in-packfile | offset-in-packfile 9704d6e7c732b07418ffe2c0dd2c2030d0cd5a2e blob 2621847 2622645 235218 2bdb752d86091c343f2f4d3af88f038f6b4c2846 blob 2212925 868876 2918139 ...
3. 定位具體文件路徑
拿到 Blob ID 后,我們需要知道它對(duì)應(yīng)的是哪個(gè)文件。使用 git rev-list 配合 grep 可以查找對(duì)應(yīng)的文件名:
# 替換 <blob id> 為上面查到的 SHA-1 git rev-list --objects --all | grep 2bdb752d86091c343f2f4d3af88f038f6b4c2846
輸出示例:
2bdb752d86091c343f2f4d3af88f038f6b4c2846 .yarn/cache/playwright-core-npm-1.55.0-1c6d3fab0f-843376a8e2.zip
這樣我們就找到了罪魁禍?zhǔn)?,例如上面?yarn/cache/playwright-core-npm-1.55.0-1c6d3fab0f-843376a8e2.zip。
第二步:分析問題
通過上面的步驟,我們發(fā)現(xiàn) .yarn/cache/ 目錄下的 zip 文件占用了大量空間。
原因分析: 在使用 Yarn 2+ (Berry) 版本時(shí),默認(rèn)會(huì)將依賴以 zip 形式存儲(chǔ)。如果項(xiàng)目沒有正確配置 .gitignore,或者開發(fā)者誤操作,就容易將 .yarn/cache 目錄提交到 Git 倉(cāng)庫(kù)中。這些二進(jìn)制緩存文件不僅體積大,而且變動(dòng)頻繁,是導(dǎo)致 Git 倉(cāng)庫(kù)膨脹的常見原因。
Yarn 2+ 的 .gitignore 最佳實(shí)踐:
根據(jù) Yarn 官方文檔,對(duì)于大多數(shù)非 Zero-Installs 的項(xiàng)目,我們應(yīng)該忽略以下目錄:
# Yarn 2+ .yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/sdks !.yarn/versions # 關(guān)鍵:忽略緩存目錄 .yarn/cache # 忽略構(gòu)建狀態(tài)和安裝狀態(tài) .yarn/build-state.yml .yarn/install-state.gz # PnP 相關(guān) .pnp.*
既然找到了問題根源是誤提交了 .yarn/cache,接下來的目標(biāo)就是將其從歷史記錄中徹底清除。
第三步:清理大文件
找到大文件后,我們需要將其從所有歷史記錄中徹底移除。這里推薦使用 BFG Repo-Cleaner,它比原生的 git filter-branch 更快、更簡(jiǎn)單。
使用 BFG Repo-Cleaner
[!info] BFG Repo-Cleaner BFG 是一個(gè)用 Scala 編寫的工具,專門用于快速清理 Git 倉(cāng)庫(kù)中的大文件或隱私信息。 官網(wǎng):https://rtyley.github.io/bfg-repo-cleaner/
1. 下載并運(yùn)行
BFG 提供了一個(gè) .jar 包,需要安裝 Java 環(huán)境運(yùn)行。
# 下載 bfg-1.14.0.jar 后,在倉(cāng)庫(kù)目錄的上一級(jí)運(yùn)行
# my-repo 為你的倉(cāng)庫(kù)目錄名稱
# 方式一:移除超過指定大小的文件 (例如 1M)
java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 1M my-repo
# 方式二:移除指定名稱的文件 (支持 glob 模式)
java -jar bfg-1.14.0.jar --delete-files '*.{zip,jar,exe}' my-repo
# 方式三:移除指定文件夾
java -jar bfg-1.14.0.jar --delete-folders '.svn' my-repo
常用參數(shù)說明:
-b, --strip-blobs-bigger-than <size>: 移除超過指定大小的 blob。-B, --strip-biggest-blobs NUM: 移除最大的前 NUM 個(gè) blob。-D, --delete-files <glob>: 按文件名移除文件。--delete-folders <glob>: 按文件夾名移除文件夾。--no-blob-protection: 允許修改最新提交(默認(rèn)情況下 BFG 會(huì)保護(hù)最新的一次 commit 不被修改,以防誤刪)。
這里我們使用命令刪除 .yarn/cache 目錄下的所有文件:
java -jar bfg-1.14.0.jar --delete-folders '.yarn/cache' my-repo
2. 物理刪除與垃圾回收
BFG 只是更新了 Git 的引用(refs)和歷史記錄,并沒有真正物理刪除磁盤上的對(duì)象。我們需要運(yùn)行 Git 的垃圾回收命令來徹底釋放空間:
# 強(qiáng)制過期所有 reflog,并執(zhí)行垃圾回收 git reflog expire --expire=now --all && git gc --prune=now --aggressive
執(zhí)行完上述步驟后,再次檢查倉(cāng)庫(kù)大小,應(yīng)該會(huì)發(fā)現(xiàn)體積明顯減小。最后,需要強(qiáng)制推送到遠(yuǎn)程倉(cāng)庫(kù):
git push origin --force --all
[!warning] 警告 這是一個(gè)破壞性操作,會(huì)重寫 Git 歷史。在執(zhí)行之前,請(qǐng)務(wù)必備份你的倉(cāng)庫(kù)! 此外,強(qiáng)制推送后,其他協(xié)作者需要重新 clone 倉(cāng)庫(kù)或進(jìn)行 rebase 操作。
到此這篇關(guān)于Git代碼庫(kù)大文件歷史記錄的清理方法的文章就介紹到這了,更多相關(guān)Git大文件歷史記錄清理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于IE11修改User-agent不再支持document.all等
這篇文章主要介紹了關(guān)于IE11修改User-agent不再支持document.all等,需要的朋友可以參考下2015-12-12
提高github下載速度的方法可達(dá)到2MB/s(100%有效)
這篇文章主要介紹了提高github下載速度的方法可達(dá)到2MB/s(100%有效),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Web 設(shè)計(jì)與開發(fā)者必須知道的 15 個(gè)站點(diǎn)
今天讀到一篇文章,介紹了15個(gè)對(duì) Web 設(shè)計(jì)與開發(fā)師極端有用的站點(diǎn),里面有不少也是我們一直在使用的,也許對(duì)很多人都有用,翻譯出來以餉同仁。2009-08-08

