summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-04-15 13:50:16 -0700
committerJunio C Hamano <gitster@pobox.com>2025-04-15 13:50:16 -0700
commitd690c44846b3e6450a98e09f43f4b40ec73f9762 (patch)
treebce8b495d73337fd1065927482ee7082588b9420
parent7b7fe0a898978618c36432f1f89b29cd412c7a23 (diff)
parent6540560fd6c91091f6cf1eaedd034bc1827e1506 (diff)
Merge branch 'ds/maintenance-loose-objects-batchsize'
The job to coalesce loose objects into packfiles in "git maintenance" now has configurable batch size. * ds/maintenance-loose-objects-batchsize: maintenance: add loose-objects.batchSize config maintenance: force progress/no-quiet to children
-rw-r--r--Documentation/config/maintenance.adoc5
-rw-r--r--Documentation/git-maintenance.adoc18
-rw-r--r--builtin/gc.c20
-rwxr-xr-xt/t7900-maintenance.sh28
4 files changed, 64 insertions, 7 deletions
diff --git a/Documentation/config/maintenance.adoc b/Documentation/config/maintenance.adoc
index 72a9d6cf81..42f9545da0 100644
--- a/Documentation/config/maintenance.adoc
+++ b/Documentation/config/maintenance.adoc
@@ -61,6 +61,11 @@ maintenance.loose-objects.auto::
loose objects is at least the value of `maintenance.loose-objects.auto`.
The default value is 100.
+maintenance.loose-objects.batchSize::
+ This integer config option controls the maximum number of loose objects
+ written into a packfile during the `loose-objects` task. The default is
+ fifty thousand. Use value `0` to indicate no limit.
+
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,
diff --git a/Documentation/git-maintenance.adoc b/Documentation/git-maintenance.adoc
index 0450d74aff..c90b370b1f 100644
--- a/Documentation/git-maintenance.adoc
+++ b/Documentation/git-maintenance.adoc
@@ -126,13 +126,17 @@ loose-objects::
objects that already exist in a pack-file; concurrent Git processes
will examine the pack-file for the object data instead of the loose
object. Second, it creates a new pack-file (starting with "loose-")
- containing a batch of loose objects. The batch size is limited to 50
- thousand objects to prevent the job from taking too long on a
- repository with many loose objects. The `gc` task writes unreachable
- objects as loose objects to be cleaned up by a later step only if
- they are not re-added to a pack-file; for this reason it is not
- advisable to enable both the `loose-objects` and `gc` tasks at the
- same time.
+ containing a batch of loose objects.
++
+The batch size defaults to fifty thousand objects to prevent the job from
+taking too long on a repository with many loose objects. Use the
+`maintenance.loose-objects.batchSize` config option to adjust this size,
+including a value of `0` to remove the limit.
++
+The `gc` task writes unreachable objects as loose objects to be cleaned up
+by a later step only if they are not re-added to a pack-file; for this
+reason it is not advisable to enable both the `loose-objects` and `gc`
+tasks at the same time.
incremental-repack::
The `incremental-repack` job repacks the object directory
diff --git a/builtin/gc.c b/builtin/gc.c
index 99431fd467..817081e1a5 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1029,6 +1029,8 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts)
if (opts->quiet)
strvec_push(&child.args, "--no-progress");
+ else
+ strvec_push(&child.args, "--progress");
return !!run_command(&child);
}
@@ -1161,6 +1163,7 @@ static int write_loose_object_to_stdin(const struct object_id *oid,
fprintf(d->in, "%s\n", oid_to_hex(oid));
+ /* If batch_size is INT_MAX, then this will return 0 always. */
return ++(d->count) > d->batch_size;
}
@@ -1185,6 +1188,8 @@ static int pack_loose(struct maintenance_run_opts *opts)
strvec_push(&pack_proc.args, "pack-objects");
if (opts->quiet)
strvec_push(&pack_proc.args, "--quiet");
+ else
+ strvec_push(&pack_proc.args, "--no-quiet");
strvec_pushf(&pack_proc.args, "%s/pack/loose", r->objects->odb->path);
pack_proc.in = -1;
@@ -1204,6 +1209,15 @@ static int pack_loose(struct maintenance_run_opts *opts)
data.count = 0;
data.batch_size = 50000;
+ repo_config_get_int(r, "maintenance.loose-objects.batchSize",
+ &data.batch_size);
+
+ /* If configured as 0, then remove limit. */
+ if (!data.batch_size)
+ data.batch_size = INT_MAX;
+ else if (data.batch_size > 0)
+ data.batch_size--; /* Decrease for equality on limit. */
+
for_each_loose_file_in_objdir(r->objects->odb->path,
write_loose_object_to_stdin,
NULL,
@@ -1263,6 +1277,8 @@ static int multi_pack_index_write(struct maintenance_run_opts *opts)
if (opts->quiet)
strvec_push(&child.args, "--no-progress");
+ else
+ strvec_push(&child.args, "--progress");
if (run_command(&child))
return error(_("failed to write multi-pack-index"));
@@ -1279,6 +1295,8 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts)
if (opts->quiet)
strvec_push(&child.args, "--no-progress");
+ else
+ strvec_push(&child.args, "--progress");
if (run_command(&child))
return error(_("'git multi-pack-index expire' failed"));
@@ -1335,6 +1353,8 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)
if (opts->quiet)
strvec_push(&child.args, "--no-progress");
+ else
+ strvec_push(&child.args, "--progress");
strvec_pushf(&child.args, "--batch-size=%"PRIuMAX,
(uintmax_t)get_auto_pack_size());
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 1909aed95e..834ddb5ad6 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -306,6 +306,34 @@ test_expect_success 'maintenance.loose-objects.auto' '
test_subcommand git prune-packed --quiet <trace-loC
'
+test_expect_success 'maintenance.loose-objects.batchSize' '
+ git init loose-batch &&
+
+ # This creates three objects per commit.
+ test_commit_bulk -C loose-batch 34 &&
+ pack=$(ls loose-batch/.git/objects/pack/pack-*.pack) &&
+ index="${pack%pack}idx" &&
+ rm "$index" &&
+ git -C loose-batch unpack-objects <"$pack" &&
+ git -C loose-batch config maintenance.loose-objects.batchSize 50 &&
+
+ GIT_PROGRESS_DELAY=0 \
+ git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
+ grep "Enumerating objects: 50, done." err &&
+
+ GIT_PROGRESS_DELAY=0 \
+ git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
+ grep "Enumerating objects: 50, done." err &&
+
+ GIT_PROGRESS_DELAY=0 \
+ git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
+ grep "Enumerating objects: 2, done." err &&
+
+ GIT_PROGRESS_DELAY=0 \
+ git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
+ test_must_be_empty err
+'
+
test_expect_success 'incremental-repack task' '
packDir=.git/objects/pack &&
for i in $(test_seq 1 5)