]> git.ipfire.org Git - thirdparty/git.git/commitdiff
maintenance: add incremental-repack auto condition
authorDerrick Stolee <dstolee@microsoft.com>
Fri, 25 Sep 2020 12:33:38 +0000 (12:33 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 25 Sep 2020 17:53:05 +0000 (10:53 -0700)
The incremental-repack task updates the multi-pack-index by deleting pack-
files that have been replaced with new packs, then repacking a batch of
small pack-files into a larger pack-file. This incremental repack is faster
than rewriting all object data, but is slower than some other
maintenance activities.

The 'maintenance.incremental-repack.auto' config option specifies how many
pack-files should exist outside of the multi-pack-index before running
the step. These pack-files could be created by 'git fetch' commands or
by the loose-objects task. The default value is 10.

Setting the option to zero disables the task with the '--auto' option,
and a negative value makes the task run every time.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/maintenance.txt
builtin/gc.c
t/t7900-maintenance.sh

index c31613be628e0112ced8fa302e8fe765d0c02c51..a0706d8f098becab7b5df71c77f718b03cc9c1a2 100644 (file)
@@ -23,3 +23,12 @@ maintenance.loose-objects.auto::
        positive value implies the command should run when the number of
        loose objects is at least the value of `maintenance.loose-objects.auto`.
        The default value is 100.
+
+maintenance.incremental-repack.auto::
+       This integer config option controls how often the `incremental-repack`
+       task should be run as part of `git maintenance run --auto`. If zero,
+       then the `incremental-repack` task will not run with the `--auto`
+       option. A negative value will force the task to run every time.
+       Otherwise, a positive value implies the command should run when the
+       number of pack-files not in the multi-pack-index is at least the value
+       of `maintenance.incremental-repack.auto`. The default value is 10.
index 8d22361fa9ae800dc28c02c9186ccfb9ce9157ff..2b99596ec850155eb5fa06729a959b4b57c0fe96 100644 (file)
@@ -30,6 +30,7 @@
 #include "promisor-remote.h"
 #include "refs.h"
 #include "remote.h"
+#include "object-store.h"
 
 #define FAILED_RUN "failed to run %s"
 
@@ -1001,6 +1002,35 @@ static int maintenance_task_loose_objects(struct maintenance_run_opts *opts)
        return prune_packed(opts) || pack_loose(opts);
 }
 
+static int incremental_repack_auto_condition(void)
+{
+       struct packed_git *p;
+       int enabled;
+       int incremental_repack_auto_limit = 10;
+       int count = 0;
+
+       if (git_config_get_bool("core.multiPackIndex", &enabled) ||
+           !enabled)
+               return 0;
+
+       git_config_get_int("maintenance.incremental-repack.auto",
+                          &incremental_repack_auto_limit);
+
+       if (!incremental_repack_auto_limit)
+               return 0;
+       if (incremental_repack_auto_limit < 0)
+               return 1;
+
+       for (p = get_packed_git(the_repository);
+            count < incremental_repack_auto_limit && p;
+            p = p->next) {
+               if (!p->multi_pack_index)
+                       count++;
+       }
+
+       return count >= incremental_repack_auto_limit;
+}
+
 static int multi_pack_index_write(struct maintenance_run_opts *opts)
 {
        struct child_process child = CHILD_PROCESS_INIT;
@@ -1156,6 +1186,7 @@ static struct maintenance_task tasks[] = {
        [TASK_INCREMENTAL_REPACK] = {
                "incremental-repack",
                maintenance_task_incremental_repack,
+               incremental_repack_auto_condition,
        },
        [TASK_GC] = {
                "gc",
index 9e6ea23f35666410e181bb9cc236aa17b1e1229e..55116c2f041e31a8d8e219ab9a81cb2b0d44cea7 100755 (executable)
@@ -219,4 +219,32 @@ test_expect_success EXPENSIVE 'incremental-repack 2g limit' '
                 --no-progress --batch-size=2147483647 <run-2g.txt
 '
 
+test_expect_success 'maintenance.incremental-repack.auto' '
+       git repack -adk &&
+       git config core.multiPackIndex true &&
+       git multi-pack-index write &&
+       GIT_TRACE2_EVENT="$(pwd)/midx-init.txt" git \
+               -c maintenance.incremental-repack.auto=1 \
+               maintenance run --auto --task=incremental-repack 2>/dev/null &&
+       test_subcommand ! git multi-pack-index write --no-progress <midx-init.txt &&
+       test_commit A &&
+       git pack-objects --revs .git/objects/pack/pack <<-\EOF &&
+       HEAD
+       ^HEAD~1
+       EOF
+       GIT_TRACE2_EVENT=$(pwd)/trace-A git \
+               -c maintenance.incremental-repack.auto=2 \
+               maintenance run --auto --task=incremental-repack 2>/dev/null &&
+       test_subcommand ! git multi-pack-index write --no-progress <trace-A &&
+       test_commit B &&
+       git pack-objects --revs .git/objects/pack/pack <<-\EOF &&
+       HEAD
+       ^HEAD~1
+       EOF
+       GIT_TRACE2_EVENT=$(pwd)/trace-B git \
+               -c maintenance.incremental-repack.auto=2 \
+               maintenance run --auto --task=incremental-repack 2>/dev/null &&
+       test_subcommand git multi-pack-index write --no-progress <trace-B
+'
+
 test_done