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