]> git.ipfire.org Git - thirdparty/git.git/commitdiff
gc: handle a corner case in gc.bigPackThreshold
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 15 Apr 2018 15:36:16 +0000 (17:36 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Apr 2018 04:52:29 +0000 (13:52 +0900)
This config allows us to keep <N> packs back if their size is larger
than a limit. But if this N >= gc.autoPackLimit, we may have a
problem. We are supposed to reduce the number of packs after a
threshold because it affects performance.

We could tell the user that they have incompatible gc.bigPackThreshold
and gc.autoPackLimit, but it's kinda hard when 'git gc --auto' runs in
background. Instead let's fall back to the next best stategy: try to
reduce the number of packs anyway, but keep the base pack out. This
reduces the number of packs to two and hopefully won't take up too
much resources to repack (the assumption still is the base pack takes
most resources to handle).

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
builtin/gc.c

index 728ae902e622ec37758a6d35ca6e5f1ba6b56f80..4c3f1d7651c93e1b5d33c50260e17eb389996e46 100644 (file)
@@ -1564,6 +1564,11 @@ gc.bigPackThreshold::
        except that all packs that meet the threshold are kept, not
        just the base pack. Defaults to zero. Common unit suffixes of
        'k', 'm', or 'g' are supported.
++
+Note that if the number of kept packs is more than gc.autoPackLimit,
+this configuration variable is ignored, all packs except the base pack
+will be repacked. After this the number of packs should go below
+gc.autoPackLimit and gc.bigPackThreshold should be respected again.
 
 gc.logExpiry::
        If the file gc.log exists, then `git gc --auto` won't run
index 81ecdc5ffa5006391db7ec9c7585f19a4016d24f..23c17ba7e99bce4e6dabd789a89deddc14abd15d 100644 (file)
@@ -253,8 +253,14 @@ static int need_to_gc(void)
        if (too_many_packs()) {
                struct string_list keep_pack = STRING_LIST_INIT_NODUP;
 
-               if (big_pack_threshold)
+               if (big_pack_threshold) {
                        find_base_packs(&keep_pack, big_pack_threshold);
+                       if (keep_pack.nr >= gc_auto_pack_limit) {
+                               big_pack_threshold = 0;
+                               string_list_clear(&keep_pack, 0);
+                               find_base_packs(&keep_pack, 0);
+                       }
+               }
 
                add_repack_all_option(&keep_pack);
                string_list_clear(&keep_pack, 0);