X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=rev-list.c;h=846aa2f79e3c90cf69eadec276b1b56165bc4601;hb=fee8825613001931daaa30d038521ae2a85d5234;hp=fdb531caf6db4944f0612258697670eb00bc55ce;hpb=07ee0d77c66d6f356cd3f82435e67510779aa53c;p=git.git diff --git a/rev-list.c b/rev-list.c index fdb531ca..846aa2f7 100644 --- a/rev-list.c +++ b/rev-list.c @@ -11,7 +11,7 @@ #define SHOWN (1u << 3) static const char rev_list_usage[] = - "usage: git-rev-list [OPTION] commit-id \n" + "git-rev-list [OPTION] commit-id \n" " --max-count=nr\n" " --max-age=epoch\n" " --min-age=epoch\n" @@ -228,6 +228,17 @@ static void mark_parents_uninteresting(struct commit *commit) commit->object.flags |= UNINTERESTING; /* + * Normally we haven't parsed the parent + * yet, so we won't have a parent of a parent + * here. However, it may turn out that we've + * reached this commit some other way (where it + * wasn't uninteresting), in which case we need + * to mark its parents recursively too.. + */ + if (commit->parents) + mark_parents_uninteresting(commit); + + /* * A missing commit is ok iff its parent is marked * uninteresting. * @@ -241,8 +252,9 @@ static void mark_parents_uninteresting(struct commit *commit) } } -static int everybody_uninteresting(struct commit_list *list) +static int everybody_uninteresting(struct commit_list *orig) { + struct commit_list *list = orig; while (list) { struct commit *commit = list->item; list = list->next; @@ -250,6 +262,29 @@ static int everybody_uninteresting(struct commit_list *list) continue; return 0; } + + /* + * Ok, go back and mark all the edge trees uninteresting, + * since otherwise we can have situations where a parent + * that was marked uninteresting (and we never even had + * to look at) had lots of objects that we don't want to + * include. + * + * NOTE! This still doesn't mean that the object list is + * "correct", since we may end up listing objects that + * even older commits (that we don't list) do actually + * reference, but it gets us to a minimal list (or very + * close) in practice. + */ + if (!tree_objects) + return 1; + + while (orig) { + struct commit *commit = orig->item; + if (!parse_commit(commit) && commit->tree) + mark_tree_uninteresting(commit->tree); + orig = orig->next; + } return 1; }