Git 大型檔案處理
GitHub 對單一檔案有 100 MB 的大小限制,超過就無法 push。這篇說明如何處理大型檔案的問題。
GitHub 檔案大小限制
當你 push 超過 100 MB 的檔案時,會看到錯誤訊息:
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: File path/to/large-file is 111.98 MB; this exceeds GitHub's file size limit of 100.00 MB
從 Git 歷史中移除大型檔案
如果你已經不小心 commit 了大型檔案,需要從 Git 歷史中完全移除它。
方法一:使用 git filter-branch
# 1. 到 Git 專案根目錄
cd your-repository
# 2. 從 Git 歷史中移除檔案
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch path/to/large-file" \
--prune-empty --tag-name-filter cat -- --all
這個指令會從 Git 歷史中永久移除該檔案,如果是重要的檔案,記得先備份!
方法二:使用 git filter-repo(推薦)
git filter-repo 是比較新的工具,效能更好:
# 安裝
pip install git-filter-repo
# 移除檔案
git filter-repo --path path/to/large-file --invert-paths
方法三:使用 BFG Repo-Cleaner
BFG 是專門用來清理 Git 歷史的工具:
# 下載 BFG
# 移除大於 100M 的檔案
java -jar bfg.jar --strip-blobs-bigger-than 100M your-repo.git
清理完成後
# 1. 加到 .gitignore 避免再次 commit
echo "path/to/large-file" >> .gitignore
# 2. 強制推送到遠端
git push origin --force --all
# 3. 清理本地
git reflog expire --expire=now --all
git gc --prune=now --aggressive
Git LFS(Large File Storage)
如果你確實需要在 Git 追蹤大型檔案(如圖片、影片、資料集),可以使用 Git LFS。
安裝 Git LFS
# macOS
brew install git-lfs
# Ubuntu
sudo apt install git-lfs
# Windows(使用 Git for Windows 已包含)
設定 Git LFS
# 初始化(每個系統只需執行一次)
git lfs install
# 追蹤特定類型的檔案
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "data/*.csv"
# 確保 .gitattributes 被 commit
git add .gitattributes
git commit -m "Configure Git LFS"
使用 Git LFS
設定好之後,正常使用 Git 即可:
git add large-file.psd
git commit -m "Add design file"
git push
Git LFS 會自動把大型檔案存到 LFS 伺服器,Git repository 只儲存指標。
查看 LFS 追蹤的檔案
# 查看追蹤規則
git lfs track
# 查看 LFS 管理的檔案
git lfs ls-files
GitHub LFS 限制
GitHub 免費帳號的 LFS 限制:
- 儲存空間:1 GB
- 每月頻寬:1 GB
超過需要購買額外的 data pack。
預防大型檔案問題
設定 .gitignore
常見應該忽略的大型檔案:
# 壓縮檔
*.zip
*.tar.gz
*.rar
# 影片
*.mp4
*.mov
*.avi
# 資料檔
*.csv
*.sql
*.db
# 依賴套件
node_modules/
vendor/
# 編譯產出
dist/
build/
設定 pre-commit hook
在 commit 前檢查檔案大小:
#!/bin/sh
# .git/hooks/pre-commit
max_size=100000000 # 100MB in bytes
for file in $(git diff --cached --name-only); do
if [ -f "$file" ]; then
size=$(wc -c < "$file")
if [ $size -gt $max_size ]; then
echo "Error: $file is larger than 100MB"
exit 1
fi
fi
done
其他平台的限制
| 平台 | 單檔限制 | Repository 限制 |
|---|---|---|
| GitHub | 100 MB | 建議 < 1 GB |
| GitLab | 無(但建議 < 1 GB) | 10 GB(免費) |
| Bitbucket | 無 | 2 GB(免費) |
常見問題
已經 push 失敗,怎麼修復?
# 1. 移除大型檔案
git rm --cached large-file.zip
# 2. 修改最後一個 commit
git commit --amend --no-edit
# 3. 如果是更早的 commit,用 filter-branch 或 filter-repo
檔案已經在 .gitignore 但還是被追蹤
# 從 Git 移除(保留本地檔案)
git rm --cached large-file.zip
git commit -m "Remove large file from tracking"