Junio C Hamano writes: > The output from rev-list is not surprising. --unpacked=$this.pack implies > the usual --unpacked behaviour (i.e. only show unpacked objects by not > traversing into commits that are packed) The problem is unconditional traversing into commits that are unpacked. This behavior is immediately obvious if the packed blob in the .keep pack is large. I've been using the following since the large object discussion with Dana, but it might be completely broken (though the test case is probably correct). -- Previously --unpacked would filter on the commit level, ignoring whether the objects comprising the commit actually were packed or unpacked. This makes it impossible to store e.g. excessively large blobs in different packs from the commits referencing them, since the next repack of such a commit will suck all referenced blobs into the same pack. This change moves the unpacked check to the output stage and no longer checks the flag during commit traversal and adds a trivial test demonstrating the problem. --- Note that t6009 is already taken, so it might be better to merge the test into one of the other rev-list tests. list-objects.c | 6 ++++-- revision.c | 2 -- t/t6009-rev-list-unpacked.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 t/t6009-rev-list-unpacked.sh diff --git a/list-objects.c b/list-objects.c index c8b8375..b378c0f 100644 --- a/list-objects.c +++ b/list-objects.c @@ -146,7 +146,8 @@ void traverse_commit_list(struct rev_info *revs, while ((commit = get_revision(revs)) != NULL) { process_tree(revs, commit->tree, &objects, NULL, ""); - show_commit(commit); + if (!revs->unpacked || !has_sha1_pack(commit->object.sha1, revs->ignore_packed)) + show_commit(commit); } for (i = 0; i < revs->pending.nr; i++) { struct object_array_entry *pending = revs->pending.objects + i; @@ -173,7 +174,8 @@ void traverse_commit_list(struct rev_info *revs, sha1_to_hex(obj->sha1), name); } for (i = 0; i < objects.nr; i++) - show_object(&objects.objects[i]); + if (!revs->unpacked || !has_sha1_pack(objects.objects[i].item->sha1, revs->ignore_packed)) + show_object(&objects.objects[i]); free(objects.objects); if (revs->pending.nr) { free(revs->pending.objects); diff --git a/revision.c b/revision.c index 4231ea2..0e90d3b 100644 --- a/revision.c +++ b/revision.c @@ -1508,8 +1508,6 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit) { if (commit->object.flags & SHOWN) return commit_ignore; - if (revs->unpacked && has_sha1_pack(commit->object.sha1, revs->ignore_packed)) - return commit_ignore; if (revs->show_all) return commit_show; if (commit->object.flags & UNINTERESTING) diff --git a/t/t6009-rev-list-unpacked.sh b/t/t6009-rev-list-unpacked.sh new file mode 100644 index 0000000..6b65e83 --- /dev/null +++ b/t/t6009-rev-list-unpacked.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description='test git rev-list --unpacked --objects' + +. ./test-lib.sh + +# Create an unpacked commit that references a packed object. + +test_expect_success setup ' + echo Hallo > foo && + git add foo && + test_tick && + git commit -m "A" && + git gc && + echo Cello > bar && + git add bar && + test_tick && + git commit -m "B" +' + +test_expect_success \ + 'object list should contain foo' ' + git rev-list --all --objects | grep -q "foo" +' + +test_expect_success \ + 'unpacked object list should not contain foo' ' + test_must_fail "git rev-list --all --unpacked --objects | grep -q \"foo\"" +' + + +test_done -- 1.5.5.1.382.g7d84c -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html