Skip to content

Commit 0cd306e

Browse files
pks-tgitster
authored andcommitted
builtin/pack-objects: exclude promisor objects with "--stdin-packs"
It is currently not possible to combine "--exclude-promisor-objects" with "--stdin-packs" because both flags want to set up a revision walk to enumerate the objects to pack. In a subsequent commit though we want to extend geometric repacks to support promisor objects, and for that we need to handle the combination of both flags. There are two cases we have to think about here: - "--stdin-packs" asks us to pack exactly the objects part of the specified packfiles. It is somewhat questionable what to do in the case where the user asks us to exclude promisor objects, but at the same time explicitly passes a promisor pack to us. For now, we simply abort the request as it is self-contradicting. As we have also been dying before this commit there is no regression here. - "--stdin-packs=follow" does the same as the first flag, but it also asks us to include all objects transitively reachable from any object in the packs we are about to repack. This is done by doing the revision walk mentioned further up. Luckily, fixing this case is trivial: we only need to modify the revision walk to also set the `exclude_promisor_objects` field. Note that we do not support the "--exclude-promisor-objects-best-effort" flag for now as we don't need it to support geometric repacking with promisor objects. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 8745eae commit 0cd306e

2 files changed

Lines changed: 50 additions & 3 deletions

File tree

builtin/pack-objects.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3857,8 +3857,11 @@ static void read_packs_list_from_stdin(struct rev_info *revs)
38573857
repo_for_each_pack(the_repository, p) {
38583858
const char *pack_name = pack_basename(p);
38593859

3860-
if ((item = string_list_lookup(&include_packs, pack_name)))
3860+
if ((item = string_list_lookup(&include_packs, pack_name))) {
3861+
if (exclude_promisor_objects && p->pack_promisor)
3862+
die(_("packfile %s is a promisor but --exclude-promisor-objects was given"), p->pack_name);
38613863
item->util = p;
3864+
}
38623865
if ((item = string_list_lookup(&exclude_packs, pack_name)))
38633866
item->util = p;
38643867
}
@@ -3936,6 +3939,7 @@ static void read_stdin_packs(enum stdin_packs_mode mode, int rev_list_unpacked)
39363939
revs.tree_objects = 1;
39373940
revs.tag_objects = 1;
39383941
revs.ignore_missing_links = 1;
3942+
revs.exclude_promisor_objects = exclude_promisor_objects;
39393943

39403944
/* avoids adding objects in excluded packs */
39413945
ignore_packed_keep_in_core = 1;
@@ -5092,9 +5096,13 @@ int cmd_pack_objects(int argc,
50925096
exclude_promisor_objects_best_effort,
50935097
"--exclude-promisor-objects-best-effort");
50945098
if (exclude_promisor_objects) {
5095-
use_internal_rev_list = 1;
50965099
fetch_if_missing = 0;
5097-
strvec_push(&rp, "--exclude-promisor-objects");
5100+
5101+
/* --stdin-packs handles promisor objects separately. */
5102+
if (!stdin_packs) {
5103+
use_internal_rev_list = 1;
5104+
strvec_push(&rp, "--exclude-promisor-objects");
5105+
}
50985106
} else if (exclude_promisor_objects_best_effort) {
50995107
use_internal_rev_list = 1;
51005108
fetch_if_missing = 0;

t/t5331-pack-objects-stdin.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,45 @@ test_expect_success '--stdin-packs=follow walks into unknown packs' '
319319
)
320320
'
321321

322+
test_expect_success '--stdin-packs with promisors' '
323+
test_when_finished "rm -fr repo" &&
324+
git init repo &&
325+
(
326+
cd repo &&
327+
git config set maintenance.auto false &&
328+
git remote add promisor garbage &&
329+
git config set remote.promisor.promisor true &&
330+
331+
for c in A B C D
332+
do
333+
echo "$c" >file &&
334+
git add file &&
335+
git commit --message "$c" &&
336+
git tag "$c" || return 1
337+
done &&
338+
339+
A="$(echo A | git pack-objects --revs $packdir/pack)" &&
340+
B="$(echo A..B | git pack-objects --revs $packdir/pack --filter=blob:none)" &&
341+
C="$(echo B..C | git pack-objects --revs $packdir/pack)" &&
342+
D="$(echo C..D | git pack-objects --revs $packdir/pack)" &&
343+
touch $packdir/pack-$B.promisor &&
344+
345+
test_must_fail git pack-objects --stdin-packs --exclude-promisor-objects pack- 2>err <<-EOF &&
346+
pack-$B.pack
347+
EOF
348+
test_grep "is a promisor but --exclude-promisor-objects was given" err &&
349+
350+
PACK=$(git pack-objects --stdin-packs=follow --exclude-promisor-objects $packdir/pack <<-EOF
351+
pack-$D.pack
352+
EOF
353+
) &&
354+
objects_in_packs $C $D >expect &&
355+
objects_in_packs $PACK >actual &&
356+
test_cmp expect actual &&
357+
rm -f $packdir/pack-$PACK.*
358+
)
359+
'
360+
322361
stdin_packs__follow_with_only () {
323362
rm -fr stdin_packs__follow_with_only &&
324363
git init stdin_packs__follow_with_only &&

0 commit comments

Comments
 (0)