Many times I have needed to "optimize" my Git repositories, especially after large imports or large history rewrites.
Usually Git knows when it needs to "optimize" its repository (on commit or receive), or you can "provoke" it by running either:
git gc
-- which applies optimizations incrementally;git gc --aggressive
-- which applies optimizations from the ground up;
However the commands above still leave behind "garbage" due to various reasons (see the manual pages for details), therefore I use another "formula".
Please note that the commands below will irrevocably remove "dangling" commits and objects!
Apply optimizations incrementally:
git reflog expire --all --expire=all --expire-unreachable=all
git pack-refs --all
git prune --expire=all --verbose
git repack -d
git prune --expire=all --verbose
Apply optimizations from the ground up:
git reflog expire --all --expire=all --expire-unreachable=all
git pack-refs --all
git prune --expire=all --verbose
git repack -A -d
git prune --expire=all --verbose
Check for any "dangling" commits and objects:
git fsck --root --tags --no-reflogs --full --connectivity-only --unreachable --dangling --name-objects
Observations:
- the
git reflog expire
removes any commits from the "reflog", which in case of history rewrites will keep these obsolete commits "alive"; - the first
git prune
removes any dangling commits and objects not yet packed; (i.e. into the./.git/objects/...
folders;) - the second
git prune
removes any dangling commits and objects that were previously packed, and now by re-packing are dumped into the./.git/objects/...
folders; - it is recommended to use
nice -n 19
forgit repack
andgit fsck
;
Also I have the following configurations in my ~/.config/git/config
(or ./.git/config
):
[pack]
packSizeLimit = 128m
window = 16384
depth = 512
windowMemory = 1073741824
deltaCacheSize = 1073741824
deltaCacheLimit = 65536
threads = 4
compression = 9
[gc]
auto = 0
autoPackLimit = 0
autoDetach = 0
packRefs = true
pruneExpire = 7 days
worktreePruneExpire = 7 days
reflogExpire = 7 days
reflogExpireUnreachable = 7 days
rerereResolved = 7 days
rerereUnresolved = 7 days
logExpiry = 1 day
aggressiveWindow = 16384
aggressiveDepth = 512
bigPackThreshold = 32m
[transfer]
fsckObjects = true
unpackLimit = 2147483647