Skip to content

Commit d690c44

Browse files
committed
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
2 parents 7b7fe0a + 6540560 commit d690c44

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

Documentation/config/maintenance.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ maintenance.loose-objects.auto::
6161
loose objects is at least the value of `maintenance.loose-objects.auto`.
6262
The default value is 100.
6363

64+
maintenance.loose-objects.batchSize::
65+
This integer config option controls the maximum number of loose objects
66+
written into a packfile during the `loose-objects` task. The default is
67+
fifty thousand. Use value `0` to indicate no limit.
68+
6469
maintenance.incremental-repack.auto::
6570
This integer config option controls how often the `incremental-repack`
6671
task should be run as part of `git maintenance run --auto`. If zero,

Documentation/git-maintenance.adoc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,17 @@ loose-objects::
126126
objects that already exist in a pack-file; concurrent Git processes
127127
will examine the pack-file for the object data instead of the loose
128128
object. Second, it creates a new pack-file (starting with "loose-")
129-
containing a batch of loose objects. The batch size is limited to 50
130-
thousand objects to prevent the job from taking too long on a
131-
repository with many loose objects. The `gc` task writes unreachable
132-
objects as loose objects to be cleaned up by a later step only if
133-
they are not re-added to a pack-file; for this reason it is not
134-
advisable to enable both the `loose-objects` and `gc` tasks at the
135-
same time.
129+
containing a batch of loose objects.
130+
+
131+
The batch size defaults to fifty thousand objects to prevent the job from
132+
taking too long on a repository with many loose objects. Use the
133+
`maintenance.loose-objects.batchSize` config option to adjust this size,
134+
including a value of `0` to remove the limit.
135+
+
136+
The `gc` task writes unreachable objects as loose objects to be cleaned up
137+
by a later step only if they are not re-added to a pack-file; for this
138+
reason it is not advisable to enable both the `loose-objects` and `gc`
139+
tasks at the same time.
136140

137141
incremental-repack::
138142
The `incremental-repack` job repacks the object directory

builtin/gc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,8 @@ static int run_write_commit_graph(struct maintenance_run_opts *opts)
10291029

10301030
if (opts->quiet)
10311031
strvec_push(&child.args, "--no-progress");
1032+
else
1033+
strvec_push(&child.args, "--progress");
10321034

10331035
return !!run_command(&child);
10341036
}
@@ -1161,6 +1163,7 @@ static int write_loose_object_to_stdin(const struct object_id *oid,
11611163

11621164
fprintf(d->in, "%s\n", oid_to_hex(oid));
11631165

1166+
/* If batch_size is INT_MAX, then this will return 0 always. */
11641167
return ++(d->count) > d->batch_size;
11651168
}
11661169

@@ -1185,6 +1188,8 @@ static int pack_loose(struct maintenance_run_opts *opts)
11851188
strvec_push(&pack_proc.args, "pack-objects");
11861189
if (opts->quiet)
11871190
strvec_push(&pack_proc.args, "--quiet");
1191+
else
1192+
strvec_push(&pack_proc.args, "--no-quiet");
11881193
strvec_pushf(&pack_proc.args, "%s/pack/loose", r->objects->odb->path);
11891194

11901195
pack_proc.in = -1;
@@ -1204,6 +1209,15 @@ static int pack_loose(struct maintenance_run_opts *opts)
12041209
data.count = 0;
12051210
data.batch_size = 50000;
12061211

1212+
repo_config_get_int(r, "maintenance.loose-objects.batchSize",
1213+
&data.batch_size);
1214+
1215+
/* If configured as 0, then remove limit. */
1216+
if (!data.batch_size)
1217+
data.batch_size = INT_MAX;
1218+
else if (data.batch_size > 0)
1219+
data.batch_size--; /* Decrease for equality on limit. */
1220+
12071221
for_each_loose_file_in_objdir(r->objects->odb->path,
12081222
write_loose_object_to_stdin,
12091223
NULL,
@@ -1263,6 +1277,8 @@ static int multi_pack_index_write(struct maintenance_run_opts *opts)
12631277

12641278
if (opts->quiet)
12651279
strvec_push(&child.args, "--no-progress");
1280+
else
1281+
strvec_push(&child.args, "--progress");
12661282

12671283
if (run_command(&child))
12681284
return error(_("failed to write multi-pack-index"));
@@ -1279,6 +1295,8 @@ static int multi_pack_index_expire(struct maintenance_run_opts *opts)
12791295

12801296
if (opts->quiet)
12811297
strvec_push(&child.args, "--no-progress");
1298+
else
1299+
strvec_push(&child.args, "--progress");
12821300

12831301
if (run_command(&child))
12841302
return error(_("'git multi-pack-index expire' failed"));
@@ -1335,6 +1353,8 @@ static int multi_pack_index_repack(struct maintenance_run_opts *opts)
13351353

13361354
if (opts->quiet)
13371355
strvec_push(&child.args, "--no-progress");
1356+
else
1357+
strvec_push(&child.args, "--progress");
13381358

13391359
strvec_pushf(&child.args, "--batch-size=%"PRIuMAX,
13401360
(uintmax_t)get_auto_pack_size());

t/t7900-maintenance.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,34 @@ test_expect_success 'maintenance.loose-objects.auto' '
306306
test_subcommand git prune-packed --quiet <trace-loC
307307
'
308308

309+
test_expect_success 'maintenance.loose-objects.batchSize' '
310+
git init loose-batch &&
311+
312+
# This creates three objects per commit.
313+
test_commit_bulk -C loose-batch 34 &&
314+
pack=$(ls loose-batch/.git/objects/pack/pack-*.pack) &&
315+
index="${pack%pack}idx" &&
316+
rm "$index" &&
317+
git -C loose-batch unpack-objects <"$pack" &&
318+
git -C loose-batch config maintenance.loose-objects.batchSize 50 &&
319+
320+
GIT_PROGRESS_DELAY=0 \
321+
git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
322+
grep "Enumerating objects: 50, done." err &&
323+
324+
GIT_PROGRESS_DELAY=0 \
325+
git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
326+
grep "Enumerating objects: 50, done." err &&
327+
328+
GIT_PROGRESS_DELAY=0 \
329+
git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
330+
grep "Enumerating objects: 2, done." err &&
331+
332+
GIT_PROGRESS_DELAY=0 \
333+
git -C loose-batch maintenance run --no-quiet --task=loose-objects 2>err &&
334+
test_must_be_empty err
335+
'
336+
309337
test_expect_success 'incremental-repack task' '
310338
packDir=.git/objects/pack &&
311339
for i in $(test_seq 1 5)

0 commit comments

Comments
 (0)