]> git.ipfire.org Git - thirdparty/git.git/blobdiff - rev-list.c
Typofix: usage strings fix.
[thirdparty/git.git] / rev-list.c
index 0dd45129e6678415f6578b4fc4a1234c6035fc77..309070fedd74b5aae204694fd40ebd48827e03f2 100644 (file)
@@ -11,7 +11,7 @@
 #define SHOWN          (1u << 3)
 
 static const char rev_list_usage[] =
-       "usage: git-rev-list [OPTION] commit-id <commit-id>\n"
+       "git-rev-list [OPTION] commit-id <commit-id>\n"
                      "  --max-count=nr\n"
                      "  --max-age=epoch\n"
                      "  --min-age=epoch\n"
@@ -203,6 +203,8 @@ static void mark_tree_uninteresting(struct tree *tree)
        if (obj->flags & UNINTERESTING)
                return;
        obj->flags |= UNINTERESTING;
+       if (!has_sha1_file(obj->sha1))
+               return;
        if (parse_tree(tree) < 0)
                die("bad tree %s", sha1_to_hex(obj->sha1));
        entry = tree->entries;
@@ -224,12 +226,24 @@ static void mark_parents_uninteresting(struct commit *commit)
        while (parents) {
                struct commit *commit = parents->item;
                commit->object.flags |= UNINTERESTING;
+
+               /*
+                * A missing commit is ok iff its parent is marked 
+                * uninteresting.
+                *
+                * We just mark such a thing parsed, so that when
+                * it is popped next time around, we won't be trying
+                * to parse it and get an error.
+                */
+               if (!has_sha1_file(commit->object.sha1))
+                       commit->object.parsed = 1;
                parents = parents->next;
        }
 }
 
-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;
@@ -237,6 +251,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;
 }
 
@@ -354,12 +391,12 @@ static struct commit *get_commit_reference(const char *name, unsigned int flags)
        /*
         * Tag object? Look what it points to..
         */
-       if (object->type == tag_type) {
+       while (object->type == tag_type) {
                struct tag *tag = (struct tag *) object;
                object->flags |= flags;
                if (tag_objects && !(object->flags & UNINTERESTING))
                        add_pending_object(object, tag->tag);
-               object = tag->tagged;
+               object = parse_object(tag->tagged->sha1);
        }
 
        /*
@@ -371,6 +408,8 @@ static struct commit *get_commit_reference(const char *name, unsigned int flags)
                object->flags |= flags;
                if (parse_commit(commit) < 0)
                        die("unable to parse commit %s", name);
+               if (flags & UNINTERESTING)
+                       mark_parents_uninteresting(commit);
                return commit;
        }
 
@@ -410,10 +449,8 @@ static struct commit *get_commit_reference(const char *name, unsigned int flags)
 int main(int argc, char **argv)
 {
        struct commit_list *list = NULL;
-       struct commit_list *(*insert)(struct commit *, struct commit_list **);
        int i, limited = 0;
 
-       insert = insert_by_date;
        for (i = 1 ; i < argc; i++) {
                int flags;
                char *arg = argv[i];
@@ -463,7 +500,6 @@ int main(int argc, char **argv)
                }
                if (!strcmp(arg, "--merge-order")) {
                        merge_order = 1;
-                       insert = commit_list_insert;
                        continue;
                }
                if (!strcmp(arg, "--show-breaks")) {
@@ -490,10 +526,11 @@ int main(int argc, char **argv)
                if (commit->object.flags & SEEN)
                        continue;
                commit->object.flags |= SEEN;
-               insert(commit, &list);
+               commit_list_insert(commit, &list);
        }
 
        if (!merge_order) {             
+               sort_by_date(&list);
                if (limited)
                        list = limit_list(list);
                if (topo_order)