repack: do not rebuild packs on --dry-run
"git repack --drop-filtered --dry-run" is documented to list the
objects that would be dropped "without rebuilding any pack or
deleting anything", but it does both.
This is a bug in cmd_repack(): after printing the candidates, the
--dry-run block falls through into the regular repack code.
repack_promisor_objects() writes a new promisor pack, and with -d,
existing_packs_remove_redundant() deletes the old packs.
The existing guard only skips the implied "delete_redundant = 1", so
it does not stop an explicit -d, and it does not stop the new pack
from being written either.
This has been broken since --dry-run was introduced in 1e746b00aa
(builtin/repack: add --drop-filtered and --dry-run options). The
--dry-run block never returned early, so a dry run has always gone
on to do a regular repack. It was not broken by a later change.
Fix it by returning right after the candidates are listed, and add a
test that checks the pack directory is unchanged with and without -d.
A dry run can no longer get past that point, so the two "!dry_run"
checks that tried to keep it from deleting or dropping anything are
now redundant.
Reported-by: Coy Geek <coygeek@gmail.com>
Helped-by: D. Ben Knoble <ben.knoble@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
1 parent
a018953688
commit
facedc705c
2 files changed
+29
-4
No files matched your search
+10
-4
@@ -351,10 +351,9 @@ int cmd_repack(int argc,
|
||||
/*
|
||||
* Dropping objects means rebuilding the promisor packs
|
||||
* without them and then removing the old packs, so the
|
||||
* redundant packs must be deleted. Imply -d on a real run.
|
||||
* redundant packs must be deleted. Imply -d.
|
||||
*/
|
||||
if (!dry_run)
|
||||
delete_redundant = 1;
|
||||
delete_redundant = 1;
|
||||
|
||||
ret = enumerate_promisor_blobs(repo, &po_args.filter_options, &drop_oids);
|
||||
|
||||
@@ -391,6 +390,13 @@ int cmd_repack(int argc,
|
||||
oidset_iter_init(&drop_oids, &iter);
|
||||
while ((oid = oidset_iter_next(&iter)))
|
||||
printf("%s\n", oid_to_hex(oid));
|
||||
|
||||
/*
|
||||
* Only list the candidates to be dropped; skip
|
||||
* the actual repack
|
||||
*/
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +511,7 @@ int cmd_repack(int argc,
|
||||
|
||||
if (pack_everything & ALL_INTO_ONE) {
|
||||
repack_promisor_objects(repo, &po_args, &names, packtmp,
|
||||
(drop_filtered && !dry_run) ? &drop_oids : NULL);
|
||||
drop_filtered ? &drop_oids : NULL);
|
||||
|
||||
if (existing_packs_has_non_kept(&existing) &&
|
||||
delete_redundant &&
|
||||
|
||||
@@ -135,6 +135,25 @@ test_expect_success '--dry-run does not remove the filtered objects' '
|
||||
git -C repo cat-file -e "$BIG"
|
||||
'
|
||||
|
||||
test_expect_success '--dry-run leaves the pack directory untouched' '
|
||||
BIG=$(cat big_oid) &&
|
||||
packdir=repo/.git/objects/pack &&
|
||||
|
||||
for opt in "" -d
|
||||
do
|
||||
ls $packdir >before &&
|
||||
|
||||
git -C repo -c repack.writeBitmaps=false \
|
||||
repack --drop-filtered --filter=blob:limit=1k \
|
||||
--dry-run -a $opt >out &&
|
||||
|
||||
ls $packdir >after &&
|
||||
test_cmp before after &&
|
||||
test_grep "$BIG" out &&
|
||||
git -C repo cat-file -e "$BIG" || return 1
|
||||
done
|
||||
'
|
||||
|
||||
test_expect_success '--drop-filtered removes the promisor blob locally' '
|
||||
BIG=$(cat big_oid) &&
|
||||
SMALL=$(cat small_oid) &&
|
||||
|
||||
Reference in new issue
Block a user