1. 5

Git does not do garbage collection by default. So garbage keeps piling up in git repos. I use this script to delete obsolete objects in all my repos.

  1. 9

    Alternative: parallel --verbose git -C {} gc ::: ~/*/.git/.. ~/dev/*/.git/..

    Pros compared to the linked script:

    • Single command
    • Parallel execution using GNU Parallel
    • Actual GC rather than prune, which does something else entirely
    • Handles special characters in repo names
    • Faster initialisation because it doesn’t have to traverse a big tree (probably not noticeable on reasonable filesystems)
    • Doesn’t mess with submodules


    • You need to know & list directories which contain repos.
    • Unusual syntax
    1. 1

      My script messes up submodules?

      1. 1

        Sorry, fixed!

      2. 1

        This also adds a dependency

        1. 3

          It also drops two, Bash and GNU find.

      3. 7

        Git does not do garbage collection by default.

        This statement is false. From https://git-scm.com/docs/git-gc:

        When common porcelain operations that create objects are run, they will check whether the repository has grown substantially since the last maintenance, and if so run git gc automatically. See gc.auto below for how to disable this behavior.

        I used to do this, but once you garbage collect you can’t use git reflog and this option is too valuable vs saving disk space.

        1. 2

          I use a similar snippet for Fish called gitamin because I view it as vitamins for git.

          set -l git_dirs (fd -H --type d '.git' $_flag_d)
          for git_dir in $git_dirs
              set repo_path $git_dir/..
              echo "--> Now optimizing $repo_path"
              git -C $repo_path gc --aggressive