list-objects: check if filter is NULL before using
[gitweb.git] / revision.c
index 613168d397bcce6f2ddb2cf074707f3aff79f8c3..05a7aac063bd4053a1478a0a4b51210af73ded58 100644 (file)
@@ -198,6 +198,8 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
        if (!object) {
                if (revs->ignore_missing)
                        return object;
+               if (revs->exclude_promisor_objects && is_promisor_object(oid))
+                       return NULL;
                die("bad object %s", name);
        }
        object->flags |= flags;
@@ -790,9 +792,17 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
 
        for (parent = commit->parents; parent; parent = parent->next) {
                struct commit *p = parent->item;
-
-               if (parse_commit_gently(p, revs->ignore_missing_links) < 0)
+               int gently = revs->ignore_missing_links ||
+                            revs->exclude_promisor_objects;
+               if (parse_commit_gently(p, gently) < 0) {
+                       if (revs->exclude_promisor_objects &&
+                           is_promisor_object(&p->object.oid)) {
+                               if (revs->first_parent_only)
+                                       break;
+                               continue;
+                       }
                        return -1;
+               }
                if (revs->show_source && !p->util)
                        p->util = commit->util;
                p->object.flags |= left_flag;
@@ -1106,7 +1116,7 @@ static void add_rev_cmdline(struct rev_info *revs,
                            unsigned flags)
 {
        struct rev_cmdline_info *info = &revs->cmdline;
-       int nr = info->nr;
+       unsigned int nr = info->nr;
 
        ALLOC_GROW(info->rev, nr + 1, info->alloc);
        info->rev[nr].item = item;
@@ -2088,6 +2098,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->limited = 1;
        } else if (!strcmp(arg, "--ignore-missing")) {
                revs->ignore_missing = 1;
+       } else if (!strcmp(arg, "--exclude-promisor-objects")) {
+               if (fetch_if_missing)
+                       die("BUG: exclude_promisor_objects can only be used when fetch_if_missing is 0");
+               revs->exclude_promisor_objects = 1;
        } else {
                int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);
                if (!opts)
@@ -2830,6 +2844,16 @@ void reset_revision_walk(void)
        clear_object_flags(SEEN | ADDED | SHOWN);
 }
 
+static int mark_uninteresting(const struct object_id *oid,
+                             struct packed_git *pack,
+                             uint32_t pos,
+                             void *unused)
+{
+       struct object *o = parse_object(oid);
+       o->flags |= UNINTERESTING | SEEN;
+       return 0;
+}
+
 int prepare_revision_walk(struct rev_info *revs)
 {
        int i;
@@ -2858,6 +2882,11 @@ int prepare_revision_walk(struct rev_info *revs)
            (revs->limited && limiting_can_increase_treesame(revs)))
                revs->treesame.name = "treesame";
 
+       if (revs->exclude_promisor_objects) {
+               for_each_packed_object(mark_uninteresting, NULL,
+                                      FOR_EACH_OBJECT_PROMISOR_ONLY);
+       }
+
        if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED)
                commit_list_sort_by_date(&revs->commits);
        if (revs->no_walk)