Seiring waktu, repository Git bisa menjadi sangat besar — ribuan commit, ratusan branch, dan file-file besar yang pernah di-commit. Hasilnya: clone lambat, fetch lama, dan operasi Git yang sluggish.
Artikel ini membahas teknik optimization untuk menjaga performa Git tetap cepat, bahkan untuk repository besar dengan histori panjang.
Problem: Kenapa Git Menjadi Lambat?
1. File Besar di Histori
Meskipun file sudah dihapus, Git tetap menyimpan histori-nya. File binary besar (video, gambar, build artifacts) membuat .git folder membengkak.
Contoh:
# File video 500MB pernah di-commit
git add video.mp4
git commit -m "Add demo video"
# Kemudian dihapus
git rm video.mp4
git commit -m "Remove video"
File video.mp4 tetap ada di histori dan memperbesar ukuran repository.
2. Terlalu Banyak Branch dan Tag
Branch dan tag yang tidak dipakai tetap disimpan di .git/refs, memperlambat operasi seperti git fetch dan git gc.
3. Loose Objects Tidak Di-pack
Git menyimpan object dalam dua format:
- Loose objects: File individual di
.git/objects - Pack files: Object yang di-compress dan di-bundle
Jika loose objects terlalu banyak, operasi Git menjadi lambat.
Teknik Optimization
1. Git Garbage Collection (git gc)
Git GC (Garbage Collection) membersihkan object yang tidak terpakai dan mem-pack loose objects.
Run garbage collection:
git gc --aggressive --prune=now
Penjelasan:
--aggressive: Optimization lebih ketat (lebih lama, tapi hasil lebih kecil)--prune=now: Hapus loose objects yang unreachable
Kapan run git gc?
- Setelah rebase atau reset yang menghasilkan banyak dangling commits
- Repository terasa lambat
- Disk space hampir penuh
Cek ukuran repository sebelum dan sesudah:
du -sh .git
git gc --aggressive --prune=now
du -sh .git
2. Shallow Clone untuk Clone Cepat
Shallow clone hanya clone commit terbaru tanpa full histori.
git clone --depth 1 https://github.com/username/repo.git
Benefit:
- Clone jauh lebih cepat
- Disk space lebih kecil
Tradeoff:
- Tidak bisa checkout commit lama
- Tidak bisa push (kecuali unshallow)
Unshallow untuk convert ke full clone:
git fetch --unshallow
3. Partial Clone (Git 2.19+)
Partial clone memungkinkan clone tanpa mengunduh semua object (blob) sekaligus.
git clone --filter=blob:none https://github.com/username/repo.git
Penjelasan:
--filter=blob:none: Clone tanpa download file contents- File contents di-download on-demand saat checkout
Benefit:
- Clone sangat cepat
- Disk space minimal
- Tetap bisa access full histori
Use case: Monorepo besar, CI/CD yang hanya perlu checkout specific files.
4. Sparse Checkout untuk Clone Partial
Sparse checkout memungkinkan checkout hanya folder tertentu.
git clone --filter=blob:none --sparse https://github.com/username/monorepo.git
cd monorepo
git sparse-checkout init --cone
git sparse-checkout set apps/web packages/ui
Hasil:
Hanya folder apps/web dan packages/ui yang di-checkout.
Benefit:
- Working directory lebih kecil
- Operasi seperti
git statuslebih cepat
5. Menghapus File Besar dari Histori
Jika file besar pernah di-commit dan memperbesar .git, gunakan git filter-repo untuk menghapusnya.
Install git filter-repo:
pip install git-filter-repo
Hapus file dari seluruh histori:
git filter-repo --path-glob '**/video.mp4' --invert-paths
Atau hapus folder:
git filter-repo --path-glob 'build/' --invert-paths
Push ulang (force push):
git push origin --force --all
git push origin --force --tags
⚠️ Warning:
- Ini rewrite histori dan mengubah commit SHA
- Semua developer harus re-clone repository
- Hanya lakukan jika yakin dan sudah backup
6. Use Git LFS untuk File Besar
Git LFS (Large File Storage) menyimpan file besar di server terpisah, hanya pointer yang disimpan di Git.
Install Git LFS:
git lfs install
Track file type tertentu:
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "*.zip"
Commit .gitattributes:
git add .gitattributes
git commit -m "Track large files with LFS"
Add dan commit file:
git add video.mp4
git commit -m "Add video with LFS"
git push
Benefit:
- Repository tetap kecil
- Clone lebih cepat
- File besar di-download on-demand
7. Menghapus Branch dan Tag yang Tidak Dipakai
Branch dan tag lama memperbesar repository. Hapus yang tidak dipakai:
Hapus branch lokal:
git branch -d old-feature
Hapus branch remote:
git push origin --delete old-feature
Hapus tag lokal:
git tag -d v1.0.0
Hapus tag remote:
git push origin --delete v1.0.0
Prune remote branches yang sudah dihapus:
git fetch --prune
8. Compress Reflog
Reflog menyimpan histori gerakan HEAD. Secara default expire dalam 90 hari, tapi bisa di-expire manual:
git reflog expire --expire=30.days --all
git gc --prune=now
9. Use .gitignore untuk Prevent Commit Files Tidak Perlu
Pastikan file yang tidak perlu tidak ter-commit:
File .gitignore:
node_modules/
dist/
build/
*.log
*.mp4
*.zip
.env
Cek file yang ter-track tapi seharusnya di-ignore:
git ls-files --others --ignored --exclude-standard
Remove dari Git (keep di working directory):
git rm --cached node_modules/ -r
git commit -m "Remove node_modules from Git"
10. Use Worktrees untuk Avoid Repeated Clones
Jika sering switch branch, gunakan worktrees daripada clone berulang kali:
git worktree add ../repo-feature feature-branch
Benefit:
- Share satu
.gitfolder - Tidak perlu clone ulang
- Bisa kerja di dua branch sekaligus
Monitoring Performance
Cek Ukuran Repository:
du -sh .git
Cek Object Count:
git count-objects -vH
Output:
count: 1234
size: 5.67 MiB
in-pack: 45678
packs: 2
size-pack: 123.45 MiB
prune-packable: 0
garbage: 0
Cek File Terbesar di Repository:
git rev-list --objects --all | \
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
sed -n 's/^blob //p' | \
sort --numeric-sort --key=2 | \
tail -10
Best Practices
✅ Run git gc secara periodik:
git gc --auto
✅ Gunakan Git LFS untuk file besar:
git lfs track "*.psd"
✅ Shallow clone untuk CI/CD:
git clone --depth 1 <repo-url>
✅ Partial clone untuk monorepo:
git clone --filter=blob:none <repo-url>
✅ Hapus branch dan tag yang tidak dipakai:
git fetch --prune
✅ Prevent commit file besar via pre-commit hook:
# .husky/pre-commit
#!/bin/sh
git diff --cached --name-only | xargs -I {} sh -c 'test $(stat -f%z {}) -lt 10485760 || (echo "File {} too large"; exit 1)'
Kesimpulan
Git performance bisa dijaga dengan:
- Git GC untuk cleanup dan compression
- Shallow clone dan partial clone untuk clone cepat
- Git LFS untuk file besar
- Filter-repo untuk hapus file dari histori
- Sparse checkout untuk checkout partial
- Worktrees untuk avoid repeated clones
Key Takeaway:
- Repository besar bisa di-optimize tanpa kehilangan histori
- Gunakan Git LFS sejak awal untuk file besar
- Run
git gcsecara periodik - Setup .gitignore dengan benar untuk prevent commit file tidak perlu
Di artikel terakhir, kita akan membahas Git Best Practices: Cheat Sheet dan Workflow Summary. Stay tuned!
Kiki/🎮🍉⌨️🍩💻