[snippet] Cleaning and compacting Git repositories

by Ciprian Dorin Craciun (⁠ciprian.craciun@gmail.com⁠) on 

How to compact and clean Git repositories of "dangling" commits and objects.

// permanent-link // hacker-news // index // RSS

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:

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 bellow 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


Also I have the following configurations in my ~/.config/git/config (or ./.git/config):

    packSizeLimit = 128m
    window = 16384
    depth = 512
    windowMemory = 1073741824
    deltaCacheSize = 1073741824
    deltaCacheLimit = 65536
    threads = 4
    compression = 9

    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

    fsckObjects = true
    unpackLimit = 2147483647