iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
自我挑戰組

30天 Git 版本控制實戰筆記系列 第 18

Day 18:Git 效能優化 - 讓 Git 飛快運行

  • 分享至 

  • xImage
  •  

今日目標
• 學習診斷 Git 效能問題
• 掌握加速 Git 操作的技巧
• 優化 repository 體積和速度
• 建立高效的 Git 工作環境
為什麼需要效能優化?
職場真實情況:
❌ 效能差的體驗:
git status → 等 30 秒...
git log → 等 20 秒...
git diff → 等 40 秒...
git clone → 等 30 分鐘...
→ 😫 工作效率極差

✅ 優化後的體驗:
git status → 0.5 秒
git log → 1 秒
git diff → 2 秒
git clone → 2 分鐘
→ 😊 工作順暢
常見效能問題:
• 🐌 Repository 太大:歷史檔案太多
• 📁 工作目錄龐大:檔案數量過多
• 🗄️ 物件庫肥大:未優化的儲存
• 🔄 網路速度慢:下載上傳緩慢


操作步驟
步驟1:診斷效能問題
檢查 repository 大小:

進入專案

cd company-website

查看 repository 大小

git count-objects -vH

輸出範例:

count: 150

size: 2.5 MB

in-pack: 5000

packs: 1

size-pack: 50 MB

prune-packable: 0

garbage: 0

size-garbage: 0 bytes

找出大型物件:

找出最大的 10 個物件

git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
sed -n 's/^blob //p' |
sort --numeric-sort --key=2 --reverse |
head -10
測量操作時間:

測試 git status 速度

time git status

測試 git log 速度

time git log --oneline -100

測試 git diff 速度

time git diff HEAD~10
步驟2:優化 Git 設定
基本效能設定:

啟用檔案系統監控(大幅加速 git status)

git config core.fsmonitor true

啟用未追蹤檔案快取

git config core.untrackedcache true

啟用多執行緒操作

git config pack.threads 4

增加壓縮等級

git config core.compression 9

啟用平行處理

git config submodule.fetchJobs 4

設定較大的緩存

git config core.packedGitLimit 512m
git config core.packedGitWindowSize 512m
git config pack.deltaCacheSize 2047m
git config pack.packSizeLimit 2047m
git config pack.windowMemory 2047m
查看目前設定:

查看所有設定

git config --list

查看特定設定

git config core.fsmonitor
git config core.untrackedcache
步驟3:清理和維護 Repository
執行 Git 垃圾回收:

基本清理

git gc

積極清理(更徹底)

git gc --aggressive

自動清理(Git 會決定何時清理)

git gc --auto

檢查完整性

git fsck --full
移除未使用的物件:

清理未引用的物件

git prune

清理未引用的物件(更早期的)

git prune --expire=7.days.ago

移除所有 reflog 記錄

git reflog expire --expire=now --all

執行垃圾回收

git gc --prune=now --aggressive
壓縮 repository:

重新打包物件

git repack -a -d

積極重新打包

git repack -a -d --depth=250 --window=250
步驟4:減少 Repository 體積
移除大型檔案歷史:

先備份!

cp -r .git .git.backup

找出大檔案

git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
awk '/^blob/ {print substr($0,6)}' |
sort --numeric-sort --key=2 --reverse |
head -20

使用 filter-branch 移除大檔案

git filter-branch --force --index-filter
'git rm --cached --ignore-unmatch 大檔案.zip'
--prune-empty --tag-name-filter cat -- --all

清理

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now --aggressive
使用 BFG Repo-Cleaner(更快更安全):

下載 BFG:https://rtyley.github.io/bfg-repo-cleaner/

移除大於 10MB 的檔案

java -jar bfg.jar --strip-blobs-bigger-than 10M

移除特定檔案

java -jar bfg.jar --delete-files 檔案名稱.zip

移除特定資料夾

java -jar bfg.jar --delete-folders 資料夾名稱

清理

git reflog expire --expire=now --all
git gc --prune=now --aggressive
步驟5:使用 Shallow Clone
快速下載專案:

只下載最近 1 次提交

git clone --depth 1 https://github.com/使用者/專案.git

只下載最近 10 次提交

git clone --depth 10 https://github.com/使用者/專案.git

只下載特定分支

git clone --depth 1 --branch main --single-branch https://github.com/使用者/專案.git
效能比較:
完整 clone:
時間:15 分鐘
大小:2.5 GB
歷史:50,000 commits

Shallow clone (--depth 1):
時間:45 秒
大小:80 MB
歷史:1 commit

速度提升:20 倍!
需要更多歷史時:

增加深度

git fetch --deepen=100

轉換為完整 repository

git fetch --unshallow
步驟6:優化大型工作目錄
使用 .gitignore 排除不必要的檔案:
cat > .gitignore << 'EOF'

依賴套件(不要追蹤)

node_modules/
vendor/
bower_components/

建置輸出

dist/
build/
*.min.js
*.min.css

日誌檔案

*.log
logs/

暫存檔案

*.tmp
*.temp
.cache/
.DS_Store
Thumbs.db

IDE 設定

.vscode/
.idea/
*.swp

測試覆蓋率

coverage/
.nyc_output/
EOF
移除已追蹤但應忽略的檔案:

停止追蹤但保留檔案

git rm --cached -r node_modules/
git commit -m "chore: 停止追蹤 node_modules"

停止追蹤特定檔案

git rm --cached 檔案名稱
git commit -m "chore: 停止追蹤不需要的檔案"
步驟7:使用 Git LFS(大型檔案儲存)
設定 Git LFS:

安裝 Git LFS

macOS: brew install git-lfs

Ubuntu: apt-get install git-lfs

初始化

git lfs install

追蹤大型檔案類型

git lfs track ".psd"
git lfs track "
.zip"
git lfs track ".mp4"
git lfs track "
.pdf"
git lfs track "design/**"

查看追蹤的檔案

git lfs track

提交設定

git add .gitattributes
git commit -m "chore: 設定 Git LFS"
遷移現有大檔案到 LFS:

遷移特定類型的檔案

git lfs migrate import --include="*.zip"

遷移特定路徑的檔案

git lfs migrate import --include="design/*"

查看 LFS 檔案

git lfs ls-files

查看 LFS 使用空間

git lfs du


進階優化技巧
技巧1:使用 Partial Clone

不下載所有 blob 物件

git clone --filter=blob:none https://github.com/使用者/專案.git

不下載大於 1MB 的 blob

git clone --filter=blob:limit=1m https://github.com/使用者/專案.git

不下載 tree 物件

git clone --filter=tree:0 https://github.com/使用者/專案.git
技巧2:使用 Git Worktree 避免重複 Clone

建立多個工作目錄共用一個 .git

git worktree add ../project-feature feature/new-function
git worktree add ../project-hotfix hotfix/urgent-fix

節省空間,共用 object database

避免多次 clone 同一個專案

技巧3:定期維護腳本

建立維護腳本

cat > git-maintenance.sh << 'EOF'
#!/bin/bash

echo "🔧 開始 Git 維護..."

清理未引用的物件

echo "📦 清理未引用物件..."
git prune --expire=30.days.ago

執行垃圾回收

echo "🗑️ 執行垃圾回收..."
git gc --auto

檢查完整性

echo "🔍 檢查完整性..."
git fsck --full --no-progress

重新打包

echo "📦 優化儲存..."
git repack -a -d

echo "✅ 維護完成!"

顯示 repository 大小

echo ""
echo "📊 Repository 狀態:"
git count-objects -vH
EOF

chmod +x git-maintenance.sh

定期執行(例如每週)

./git-maintenance.sh
技巧4:優化網路速度

使用 SSH 而不是 HTTPS(通常更快)

git remote set-url origin git@github.com:使用者/專案.git

增加 HTTP 緩衝區大小

git config http.postBuffer 524288000 # 500MB

啟用壓縮

git config core.compression 9

使用多執行緒傳輸

git config pack.threads 4


效能優化檢查清單
✅ Repository 層級:
□ 執行 git gc 定期清理
□ 移除不需要的大檔案
□ 使用 Git LFS 管理大檔案
□ 定期執行 git repack
□ 檢查 .gitignore 是否完整
✅ 設定層級:
□ 啟用 core.fsmonitor
□ 啟用 core.untrackedcache
□ 設定適當的 pack.threads
□ 增加 core.compression
□ 優化網路相關設定
✅ 工作流程層級:
□ 使用 shallow clone 加速下載
□ 使用 sparse checkout 只下載需要的部分
□ 使用 git worktree 避免重複 clone
□ 定期執行維護腳本
□ 避免追蹤不必要的檔案


效能基準測試
優化前 vs 優化後:
操作 優化前 優化後 改善
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
git status 30 秒 0.5 秒 60倍
git log 20 秒 1 秒 20倍
git diff 40 秒 2 秒 20倍
git clone 30 分鐘 2 分鐘 15倍
Repository 2.5 GB 500 MB 5倍縮小


故障排除
問題1:git status 很慢

解決方案

git config core.fsmonitor true
git config core.untrackedcache true
問題2:git clone 很慢

解決方案

git clone --depth 1 --single-branch
問題3:repository 太大

解決方案

1. 找出大檔案

git rev-list --objects --all |
git cat-file --batch-check |
sort -k 3 -n | tail -20

2. 移除大檔案

java -jar bfg.jar --strip-blobs-bigger-than 10M

3. 清理

git gc --aggressive --prune=now
問題4:push/pull 很慢

解決方案

git config http.postBuffer 524288000
git config core.compression 9


今日重點回顧
• ✅ 學會診斷 Git 效能問題
• ✅ 掌握優化 Git 設定的技巧
• ✅ 會清理和維護 repository
• ✅ 能大幅提升 Git 操作速度
核心指令總結

診斷

git count-objects -vH # 查看大小
time git status # 測試速度

優化設定

git config core.fsmonitor true # 加速 status
git config core.untrackedcache true # 快取未追蹤檔案

清理維護

git gc --aggressive # 垃圾回收
git prune # 移除未用物件
git repack -a -d # 重新打包

快速下載

git clone --depth 1 # 淺層複製
git clone --filter=blob:none # 部分複製


上一篇
Day 17:大型專案管理策略 - 管理複雜的程式碼庫
下一篇
Day 19:錯誤修復與資料救援 - 成為 Git 救火隊長
系列文
30天 Git 版本控制實戰筆記19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言