From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> The pack-files 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.pack-files.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@xxxxxxxxxxxxx> --- Documentation/config/maintenance.txt | 9 ++++++++ builtin/gc.c | 31 ++++++++++++++++++++++++++++ t/t7900-maintenance.sh | 30 +++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/Documentation/config/maintenance.txt b/Documentation/config/maintenance.txt index a9442dd260..77b255318c 100644 --- a/Documentation/config/maintenance.txt +++ b/Documentation/config/maintenance.txt @@ -21,3 +21,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.pack-files.auto:: + This integer config option controls how often the `pack-files` task + should be run as part of `git maintenance run --auto`. If zero, then + the `pack-files` 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.pack-files.auto`. The default value is 10. diff --git a/builtin/gc.c b/builtin/gc.c index 391e1e2121..c3531561c2 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -31,6 +31,7 @@ #include "remote.h" #include "midx.h" #include "refs.h" +#include "object-store.h" #define FAILED_RUN "failed to run %s" @@ -1072,6 +1073,35 @@ static int maintenance_task_loose_objects(struct repository *r) return prune_packed(r) || pack_loose(r); } +static int pack_files_auto_condition(struct repository *r) +{ + struct packed_git *p; + int enabled; + int pack_files_auto_limit = 10; + int count = 0; + + if (repo_config_get_bool(r, "core.multiPackIndex", &enabled) || + !enabled) + return 0; + + repo_config_get_int(r, "maintenance.pack-files.auto", + &pack_files_auto_limit); + + if (!pack_files_auto_limit) + return 0; + if (pack_files_auto_limit < 0) + return 1; + + for (p = get_packed_git(r); + count < pack_files_auto_limit && p; + p = p->next) { + if (!p->multi_pack_index) + count++; + } + + return count >= pack_files_auto_limit; +} + static int multi_pack_index_write(struct repository *r) { int result; @@ -1345,6 +1375,7 @@ static void initialize_tasks(struct repository *r) tasks[num_tasks]->name = "pack-files"; tasks[num_tasks]->fn = maintenance_task_pack_files; + tasks[num_tasks]->auto_condition = pack_files_auto_condition; num_tasks++; tasks[num_tasks]->name = "gc"; diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index a55c36d249..1714d11bd9 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -178,4 +178,34 @@ test_expect_success 'pack-files task' ' test_line_count = 2 packs-after ' +test_expect_success 'maintenance.pack-files.auto' ' + git repack -adk && + git config core.multiPackIndex true && + git multi-pack-index write && + GIT_TRACE2_EVENT=1 git -c maintenance.pack-files.auto=1 maintenance \ + run --auto --task=pack-files >out && + ! grep "\"multi-pack-index\"" out && + for i in 1 2 + do + test_commit A-$i && + git pack-objects --revs .git/objects/pack/pack <<-\EOF && + HEAD + ^HEAD~1 + EOF + GIT_TRACE2_EVENT=$(pwd)/trace-A-$i git \ + -c maintenance.pack-files.auto=2 \ + maintenance run --auto --task=pack-files && + ! grep "\"multi-pack-index\"" trace-A-$i && + test_commit B-$i && + git pack-objects --revs .git/objects/pack/pack <<-\EOF && + HEAD + ^HEAD~1 + EOF + GIT_TRACE2_EVENT=$(pwd)/trace-B-$i git \ + -c maintenance.pack-files.auto=2 \ + maintenance run --auto --task=pack-files >out && + grep "\"multi-pack-index\"" trace-B-$i >/dev/null || return 1 + done +' + test_done -- gitgitgadget