git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: gc --aggressive

From
Jay Soffian <jaysoffian@gmail.com>
Date
Apr 17, 2012, 17:53 UTC
Message-ID
<CAG+J_DyqvCxwd6+gzixQEk6SxMZF0qsXKcJPaU6imsJdFQ-64g@mail.gmail.com>
In-Reply-To
<CAG+J_DzO=UZ56PjnSCRaTdj8pBSYc5PFofw1QHy42c5pHMK_HQ@mail.gmail.com>
On Tue, Apr 17, 2012 at 12:16 PM, Jay Soffian <jaysoffian@gmail.com> wrote:
Show 5 quoted lines
> This has worked fine on repos large and small. However, starting a
> couple days ago git started running out of memory on a relatively
> modest repo[*] while repacking on a Linux box with 12GB memory (+ 12GB
> swap). I am able to gc the repo by either removing --aggressive or
> .keep'ing the oldest pack.

Experimentally, setting pack.windowMemory = 256m keeps git memory usage < 4.5 GB during an aggressive repack.

Ironically I end up with a slightly worse pack (63115590 bytes vs 61518628 bytes) than not using --aggressive. I assume this is because pack-objects found a better delta chain during the previous aggressive repack when windowMemory was not set.

> 1) If --aggressive does not generally provide a benefit, should it be
> made a no-op?

I guess I'll revise this question: perhaps --aggressive should be better explained/discouraged. I found a message from Jeff last month and stole his words for this patch:

<snip>
diff --git i/Documentation/git-gc.txt w/Documentation/git-gc.txt
index 815afcb922..ca5bf8b51e 100644
--- i/Documentation/git-gc.txt
+++ w/Documentation/git-gc.txt
@@ -37,9 +37,8 @@ OPTIONS
 	Usually 'git gc' runs very quickly while providing good disk
 	space utilization and performance.  This option will cause
 	'git gc' to more aggressively optimize the repository at the expense
-	of taking much more time.  The effects of this optimization are
-	persistent, so this option only needs to be used occasionally; every
-	few hundred changesets or so.
+	of taking much more time and potentially using greater memory. This
+	option is rarely needed. See Repacking below.

 --auto::
 	With this option, 'git gc' checks whether any housekeeping is
@@ -138,6 +137,39 @@ If you are expecting some objects to be collected
and they aren't, check
 all of those locations and decide whether it makes sense in your case to
 remove those references.

+Repacking
+---------
+
+Under the covers 'git gc' calls several commands to optimize the repository.
+The most significant of these with respect to repository size and general
+performance is linkgit:git-repack[1]. There are basically three levels of
+'gc' with respect to repacking:
+
+ 1. `git gc --auto`; if there are too many loose objects (`gc.auto`), they
+    all go into a new incremental pack. If there are already too many
+    packs (`gc.autopacklimit`), all of the existing packs are re-packed
+    together.
+
+    Making an incremental pack is by far the fastest because the speed is
+    independent of the existing repository history. If git packs
+    everything together, it should be more or less the same as (2).
+
+ 2. `git gc`; this packs everything into a single pack. It uses default
+    window and depth parameters, but importantly, it reuses existing
+    deltas. Doing so makes the delta compression phase much faster, and it
+    often makes the writing phase faster (because for older objects, git
+    is primarily streaming them right out of the existing pack). On a big
+    repository though, this does do a lot of I/O, because git has to
+    rewrite the whole pack.
+
+ 3. `git gc --aggressive`; this is often much slower than (2) because git
+    throws out all of the existing deltas and recomputes them from
+    scratch. It uses a higher window parameter meaning it will spend
+    more time computing, and it may end up with a smaller pack. However,
+    unless the repository is known to have initially been poorly packed,
+    this option is not needed and will just cause git to perform
+    extra work.
+
 HOOKS
 -----

@@ -147,6 +179,7 @@ linkgit:githooks[5] for more information.

 SEE ALSO
 --------
+linkgit:git-pack-refs[1]
 linkgit:git-prune[1]
 linkgit:git-reflog[1]
 linkgit:git-repack[1]
</snip>

Thoughts?
Previous: Jay SoffianNext: Matthieu Moy
Message 2 of 26 in “gc --aggressive”
  1. Jay SoffianApr 17, 2012
  2. Jay SoffianApr 17, 2012
  3. Matthieu MoyApr 17, 2012
  4. Jeff KingApr 17, 2012
  5. Jeff KingApr 28, 2012
  6. Nicolas PitreApr 28, 2012
  7. Jeff KingApr 29, 2012
  8. Nicolas PitreApr 29, 2012
  9. Jeff KingMay 1, 2012
  10. Jeff KingMay 1, 2012
  11. Nicolas PitreMay 1, 2012
  12. Junio C HamanoMay 1, 2012
  13. Nicolas PitreMay 1, 2012
  14. Jeff KingMay 1, 2012
  15. Jeff KingMay 1, 2012
  16. Nicolas PitreMay 1, 2012
  17. Nicolas PitreMay 1, 2012
  18. Jeff KingMay 1, 2012
  19. Nicolas PitreMay 1, 2012
  20. Nicolas PitreApr 28, 2012
  21. Jeff KingApr 17, 2012
  22. Junio C HamanoApr 17, 2012
  23. Jeff KingApr 17, 2012
  24. Junio C HamanoApr 17, 2012
  25. Nicolas PitreApr 28, 2012
  26. Andreas EricssonApr 18, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.