Skip to content

Commit bdd42e3

Browse files
committed
Merge branch 'es/mark-gc-cruft-as-experimental'
Enable gc.cruftpacks by default for those who opt into feature.experimental setting. * es/mark-gc-cruft-as-experimental: config: let feature.experimental imply gc.cruftPacks=true gc: add tests for --cruft and friends
2 parents 098b1d0 + c695592 commit bdd42e3

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

Documentation/config/feature.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ feature.experimental::
1414
+
1515
* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by
1616
skipping more commits at a time, reducing the number of round trips.
17+
+
18+
* `gc.cruftPacks=true` reduces disk space used by unreachable objects during
19+
garbage collection, preventing loose object explosions.
1720

1821
feature.manyFiles::
1922
Enable config options that optimize for repos with many files in the

builtin/gc.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static const char * const builtin_gc_usage[] = {
4242

4343
static int pack_refs = 1;
4444
static int prune_reflogs = 1;
45-
static int cruft_packs = 0;
45+
static int cruft_packs = -1;
4646
static int aggressive_depth = 50;
4747
static int aggressive_window = 250;
4848
static int gc_auto_threshold = 6700;
@@ -593,6 +593,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
593593
if (prune_expire && parse_expiry_date(prune_expire, &dummy))
594594
die(_("failed to parse prune expiry value %s"), prune_expire);
595595

596+
prepare_repo_settings(the_repository);
597+
if (cruft_packs < 0)
598+
cruft_packs = the_repository->settings.gc_cruft_packs;
599+
596600
if (aggressive) {
597601
strvec_push(&repack, "-f");
598602
if (aggressive_depth > 0)
@@ -704,7 +708,6 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
704708
clean_pack_garbage();
705709
}
706710

707-
prepare_repo_settings(the_repository);
708711
if (the_repository->settings.gc_write_commit_graph == 1)
709712
write_commit_graph_reachable(the_repository->objects->odb,
710713
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,

repo-settings.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void prepare_repo_settings(struct repository *r)
4343
/* Defaults modified by feature.* */
4444
if (experimental) {
4545
r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;
46+
r->settings.gc_cruft_packs = 1;
4647
}
4748
if (manyfiles) {
4849
r->settings.index_version = 4;

repository.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct repo_settings {
3434
int commit_graph_generation_version;
3535
int commit_graph_read_changed_paths;
3636
int gc_write_commit_graph;
37+
int gc_cruft_packs;
3738
int fetch_write_commit_graph;
3839
int command_requires_full_index;
3940
int sparse_index;

t/t6500-gc.sh

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,102 @@ test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "e
202202
grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out
203203
'
204204

205+
prepare_cruft_history () {
206+
test_commit base &&
207+
208+
test_commit --no-tag foo &&
209+
test_commit --no-tag bar &&
210+
git reset HEAD^^
211+
}
212+
213+
assert_cruft_packs () {
214+
find .git/objects/pack -name "*.mtimes" >mtimes &&
215+
sed -e 's/\.mtimes$/\.pack/g' mtimes >packs &&
216+
217+
test_file_not_empty packs &&
218+
while read pack
219+
do
220+
test_path_is_file "$pack" || return 1
221+
done <packs
222+
}
223+
224+
assert_no_cruft_packs () {
225+
find .git/objects/pack -name "*.mtimes" >mtimes &&
226+
test_must_be_empty mtimes
227+
}
228+
229+
test_expect_success 'gc --cruft generates a cruft pack' '
230+
test_when_finished "rm -fr crufts" &&
231+
git init crufts &&
232+
(
233+
cd crufts &&
234+
235+
prepare_cruft_history &&
236+
git gc --cruft &&
237+
assert_cruft_packs
238+
)
239+
'
240+
241+
test_expect_success 'gc.cruftPacks=true generates a cruft pack' '
242+
test_when_finished "rm -fr crufts" &&
243+
git init crufts &&
244+
(
245+
cd crufts &&
246+
247+
prepare_cruft_history &&
248+
git -c gc.cruftPacks=true gc &&
249+
assert_cruft_packs
250+
)
251+
'
252+
253+
test_expect_success 'feature.experimental=true generates a cruft pack' '
254+
git init crufts &&
255+
test_when_finished "rm -fr crufts" &&
256+
(
257+
cd crufts &&
258+
259+
prepare_cruft_history &&
260+
git -c feature.experimental=true gc &&
261+
assert_cruft_packs
262+
)
263+
'
264+
265+
test_expect_success 'feature.experimental=false allows explicit cruft packs' '
266+
git init crufts &&
267+
test_when_finished "rm -fr crufts" &&
268+
(
269+
cd crufts &&
270+
271+
prepare_cruft_history &&
272+
git -c gc.cruftPacks=true -c feature.experimental=false gc &&
273+
assert_cruft_packs
274+
)
275+
'
276+
277+
test_expect_success 'feature.experimental=true can be overridden' '
278+
git init crufts &&
279+
test_when_finished "rm -fr crufts" &&
280+
(
281+
cd crufts &&
282+
283+
prepare_cruft_history &&
284+
git -c feature.expiremental=true -c gc.cruftPacks=false gc &&
285+
assert_no_cruft_packs
286+
)
287+
'
288+
289+
test_expect_success 'feature.experimental=false avoids cruft packs by default' '
290+
git init crufts &&
291+
test_when_finished "rm -fr crufts" &&
292+
(
293+
cd crufts &&
294+
295+
prepare_cruft_history &&
296+
git -c feature.experimental=false gc &&
297+
assert_no_cruft_packs
298+
)
299+
'
300+
205301
run_and_wait_for_auto_gc () {
206302
# We read stdout from gc for the side effect of waiting until the
207303
# background gc process exits, closing its fd 9. Furthermore, the

0 commit comments

Comments
 (0)