遇到 Git 提示大文件無法上傳確實讓人頭疼,但別擔心,我們可以一步步來解決。為了讓你更清晰地了解整個流程,我先用一個表格來概括主要步驟:
步驟 | 核心操作 | 關鍵命令/工具示例 (用于刪除歷史中的大文件) |
---|---|---|
1. 定位大文件 | 使用 Git 命令或工具找出倉庫中的大文件 | git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')" |
2. 刪除大文件 | 從所有歷史記錄中徹底刪除找到的大文件 | git filter-repo --path <文件路徑> --invert-paths |
或 BFG 工具 | ||
3. 清理與推送 | 執行垃圾回收并強制推送到遠程倉庫 | git gc --aggressive --prune=all , git push --force |
4. 預防再次發生 | 使用 .gitignore 和 Git LFS 避免類似問題 | git lfs track "*.psd" |
接下來,我們詳細看看每一步的具體操作。
📍 第一步:定位問題大文件
首先需要找出到底是哪個(些)文件體積過大。Gitee 的錯誤信息有時會直接給出文件名,如果沒有,你可以通過以下命令來查找:
- 查看體積最大的幾個文件:這個命令會列出倉庫中體積最大的5個文件(你可以修改
tail -5
中的數字來查看更多):git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
- 使用圖形化工具(可選):如果你更喜歡圖形界面,一些 Git 客戶端(如 GitKraken、SourceTree)或者 Git LFS 的相關命令(
git lfs ls-files
)也能幫助你直觀地查看大文件。
🗑? 第二步:從歷史中徹底刪除大文件
找到大文件后,就需要將它從 Git 的歷史記錄中徹底移除。請注意,以下操作會重寫 Git 歷史,這意味著會改變提交的哈希值。如果倉庫是多人協作,必須提前通知所有協作者,讓他們在你強制推送后重新克隆倉庫。
這里推薦使用 git filter-repo
,它是一個更現代、更高效且更安全的工具,可以替代老舊的 git filter-branch
。
-
安裝 git-filter-repo:
- Ubuntu/Debian:
sudo apt install git-filter-repo
- macOS:
brew install git-filter-repo
- 也可以通過 Pip 安裝:
pip install git-filter-repo
- Ubuntu/Debian:
-
使用 git-filter-repo 刪除文件(以刪除
src/assets/大文件/mtbg.gif
為例):# 確保你在倉庫的根目錄下 # --path 指定要刪除的文件路徑 # --invert-paths 意味著排除這些路徑,即刪除它們 git filter-repo --path src/assets/大文件/mtbg.gif --invert-paths --force
這條命令會遍歷所有提交,并將指定的文件從歷史中徹底剔除。
-
替代方案:使用 BFG Repo-Cleaner
BFG 是一個專為清理 Git 倉庫中大文件而設計的工具,比filter-branch
更快速簡單。# 安裝 BFG 需要 Java 環境 # 下載 BFG jar 包(例如 wget 方式) wget http://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar # 運行 BFG 刪除特定文件 java -jar bfg-1.14.0.jar --delete-files 'mtbg.gif'
🧹 第三步:清理本地倉庫并強制推送
徹底刪除大文件后,本地倉庫還需要進行一些清理操作,然后再推送到遠程。
-
執行垃圾回收 (GC):這個命令會清理不必要的文件并優化本地倉庫。
git gc --aggressive --prune=all
之后你可以用
git count-objects -vH
查看優化后的倉庫大小,應該會顯著減小。 -
強制推送到遠程倉庫:因為重寫了歷史,必須使用
--force
選項來推送。# 強制推送所有分支 git push origin --force --all # 強制推送所有標簽 git push origin --force --tags
再次強調:強制推送前務必確保團隊其他成員知曉!
🛡? 第四步:預防問題再次發生
為了避免以后再次遇到同樣的問題,最好采取一些預防措施:
-
善用
.gitignore
文件:在倉庫根目錄創建或編輯.gitignore
文件,忽略那些不需要版本控制的文件,如編譯產物、依賴包、日志文件、系統文件等。例如:# 忽略 .zip 壓縮包 *.zip # 忽略 node_modules 目錄 node_modules/ # 忽略 .log 日志文件 *.log
記得將
.gitignore
文件也提交到 Git 中。 -
使用 Git LFS 管理必需的大文件:如果你的項目中確實需要版本控制一些大型文件(如圖片、視頻、模型文件等),Git Large File Storage (LFS) 是一個更好的選擇。它會將大文件存儲在單獨的地方,而在 Git 倉庫中只保留指針,從而避免倉庫體積過快增長。
# 安裝 Git LFS git lfs install # 跟蹤特定類型的文件(例如跟蹤所有 .psd 文件) git lfs track "*.psd" # 確保 .gitattributes 文件被提交(此文件保存 LFS 跟蹤規則) git add .gitattributes git commit -m "開始使用 Git LFS 跟蹤 .psd 文件"
?? 操作前的重要提醒
在進行上述操作,尤其是重寫歷史(git filter-repo
、BFG
)和強制推送(git push --force
)前,請務必注意:
- 備份你的倉庫:最簡單的方法就是直接復制整個倉庫文件夾。
- 通知協作者:重寫歷史后,其他所有開發者必須使用
git clone
重新克隆倉庫,或者使用git fetch origin && git reset --hard origin/master
等命令將其本地分支重置到新的歷史記錄上。否則,他們的提交極有可能引起混亂。
💎 總結
處理 Git 中的大文件問題,關鍵在于徹底將其從歷史記錄中移除,而不僅僅是刪除最新版本的文件。git filter-repo
或 BFG
工具是完成這項工作的利器。之后,通過配置 .gitignore
和 Git LFS
,可以有效地預防此類問題再次發生。
希望這些詳細的步驟能幫助你順利解決問題。如果還有其他疑問,歡迎隨時提出。