Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux Git 倉庫清理無效對象:從 git filter-branch 到 BFG Repo-Cleaner

編輯:關於 Linux

Git 倉庫隨時間增長,會積累大文件、敏感信息、廢棄分支等無效對象,導致克隆緩慢、磁盤佔用大。本文對比 git filter-branch、git filter-repo、BFG Repo-Cleaner 三種清理方案,推薦 BFG 多線程高性能清理大型倉庫。

Git 倉庫清理前後大小對比

問題現象

  • .git/objects 目錄佔用數 GB,包含歷史誤提交的 .zip、.log、node_modules、*.out 等。
  • 包含敏感信息(密鑰、密碼)需從歷史徹底抹除。
  • 團隊成員克隆耗時過長,CI/CD 構建緩慢。

方案一:git filter-branch(官方原生,但慢、易錯)

# 1. 備份倉庫
git clone --mirror git@github.com:org/repo.git
cd repo.git

# 2. 刪除歷史中所有名為 nohup.out 的文件
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch **/nohup.out' \
  --prune-empty --tag-name-filter cat -- --all

# 3. 清理引用、垃圾回收
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# 4. 強制推送(需團隊協調)
git push --force --all
git push --force --tags

缺點:單線程、處理 2GB 倉庫需數小時、路徑匹配不精確(同名文件誤刪/漏刪)、官方已標記為不推薦。

方案二:git filter-repo(官方推薦替代者,Python 實現,較快)

# 安裝
pip install git-filter-repo

# 刪除所有 .zip .log .out 文件
git filter-repo --path-glob '*.zip' --path-glob '*.log' --path-glob '*.out' --invert-paths

# 刪除大於 1MB 的 blob
git filter-repo --strip-blobs-bigger-than 1M

# 強制推送
git push --force --all
git push --force --tags

優點:多線程、路徑匹配精確、支持複雜重寫邏輯。缺點:需 Python 環境、學習曲線稍陡。

方案三:BFG Repo-Cleaner(Java 多線程,專為大文件清理設計,最快最簡單)

安裝

# 下載 jar 包
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar

# 或包管理器
# apt install bfg
# brew install bfg

核心命令(在裸倉庫上操作)

# 1. 裸克隆
git clone --mirror git@github.com:org/repo.git
cd repo.git

# 2. 刪除歷史中所有 .zip 文件
java -jar bfg-1.14.0.jar --delete-files '*.zip' repo.git

# 3. 刪除所有 .log 文件
java -jar bfg-1.14.0.jar --delete-files '*.log' repo.git

# 4. 刪除所有 .out 文件
java -jar bfg-1.14.0.jar --delete-files '*.out' repo.git

# 5. 刪除所有大於 1MB 的 blob
java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 1M repo.git

# 6. 清理並壓縮
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# 7. 強制推送
git push --force --all
git push --force --tags

BFG 關鍵優勢

  • 極速:多線程並行,處理 2GB 倉庫只需幾分鐘(filter-branch 需數小時)。
  • 語義化:按文件名模式、大小閾值清理,不關心路徑,避免同名誤刪。
  • 保護最新提交:默認不修改最近一次提交(HEAD),防止破壞當前工作樹。
  • 簡單:單 jar 包,無依賴,命令極簡潔。

清理後團隊協作指南

  1. 通知所有成員:倉庫歷史已重寫,舊克隆失效。
  2. 成員重新克隆(最簡單):git clone git@github.com:org/repo.git。
  3. 或本地修復(高級用戶):
    git fetch --all
    git reset --hard origin/main
    git clean -fd
    
  4. CI/CD 更新:重新配置構建代理的倉庫鏡像。

常用 Git 小技巧速查

場景命令
裸克隆(鏡像)git clone --bare /path/to/repo
修改最後一次提交 (amend)git add . && git commit --amend && git push -f
放棄本地未提交修改git checkout . 或 git restore .
撤銷最後一次提交 (保留修改)git reset --soft HEAD^
銷毀最後一次提交 (丟棄修改)git reset --hard HEAD^ && git push -f
嵌入版本號到構建產物git rev-parse HEAD > version.txt
查找大文件git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print $3, $4}' | sort -rn | head -20

最佳實踐建議

  1. 預防大於治療:.gitignore 覆蓋 *.log、*.zip、node_modules/、target/、.idea/、*.pem。
  2. 預提交鉤子:pre-commit 檢測大文件(>1MB)、敏感信息(gitleaks、truffleHog)。
  3. 定期清理:每季度運行 BFG 清理歷史垃圾。
  4. 大文件外置:Git LFS 管理二進制大文件(設計圖、模型權重、視頻)。
  5. 單一職責倉庫:避免單倉庫過大,拆分微服務/前端/文檔獨立倉庫。

選對工具(BFG)、建立規範、定期清理,讓 Git 倉庫保持輕量、安全、高效,是工程化團隊的基本功。

Copyright © Windows教程網 All Rights Reserved