git-cvsimport-script: provide direct support for cvsps -z option
[git.git] / rev-list.c
index 16920ef..bf61b74 100644 (file)
@@ -1,5 +1,7 @@
 #include "cache.h"
 #include "commit.h"
+#include "tree.h"
+#include "blob.h"
 #include "epoch.h"
 
 #define SEEN           (1u << 0)
@@ -17,6 +19,8 @@ static const char rev_list_usage[] =
                      "  --merge-order [ --show-breaks ]";
 
 static int bisect_list = 0;
+static int tree_objects = 0;
+static int blob_objects = 0;
 static int verbose_header = 0;
 static int show_parents = 0;
 static int hdr_termination = 0;
@@ -94,20 +98,103 @@ static int process_commit(struct commit * commit)
        return CONTINUE;
 }
 
+static struct object_list **add_object(struct object *obj, struct object_list **p, const char *name)
+{
+       struct object_list *entry = xmalloc(sizeof(*entry));
+       entry->item = obj;
+       entry->next = NULL;
+       entry->name = name;
+       *p = entry;
+       return &entry->next;
+}
+
+static struct object_list **process_blob(struct blob *blob, struct object_list **p, const char *name)
+{
+       struct object *obj = &blob->object;
+
+       if (!blob_objects)
+               return p;
+       if (obj->flags & (UNINTERESTING | SEEN))
+               return p;
+       obj->flags |= SEEN;
+       return add_object(obj, p, name);
+}
+
+static struct object_list **process_tree(struct tree *tree, struct object_list **p, const char *name)
+{
+       struct object *obj = &tree->object;
+       struct tree_entry_list *entry;
+
+       if (!tree_objects)
+               return p;
+       if (obj->flags & (UNINTERESTING | SEEN))
+               return p;
+       if (parse_tree(tree) < 0)
+               die("bad tree object %s", sha1_to_hex(obj->sha1));
+       obj->flags |= SEEN;
+       p = add_object(obj, p, name);
+       for (entry = tree->entries ; entry ; entry = entry->next) {
+               if (entry->directory)
+                       p = process_tree(entry->item.tree, p, entry->name);
+               else
+                       p = process_blob(entry->item.blob, p, entry->name);
+       }
+       return p;
+}
+
 static void show_commit_list(struct commit_list *list)
 {
+       struct object_list *objects = NULL, **p = &objects;
        while (list) {
                struct commit *commit = pop_most_recent_commit(&list, SEEN);
 
+               p = process_tree(commit->tree, p, "");
                if (process_commit(commit) == STOP)
                        break;
        }
+       while (objects) {
+               printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name);
+               objects = objects->next;
+       }
+}
+
+static void mark_blob_uninteresting(struct blob *blob)
+{
+       if (!blob_objects)
+               return;
+       if (blob->object.flags & UNINTERESTING)
+               return;
+       blob->object.flags |= UNINTERESTING;
+}
+
+static void mark_tree_uninteresting(struct tree *tree)
+{
+       struct object *obj = &tree->object;
+       struct tree_entry_list *entry;
+
+       if (!tree_objects)
+               return;
+       if (obj->flags & UNINTERESTING)
+               return;
+       obj->flags |= UNINTERESTING;
+       if (parse_tree(tree) < 0)
+               die("bad tree %s", sha1_to_hex(obj->sha1));
+       entry = tree->entries;
+       while (entry) {
+               if (entry->directory)
+                       mark_tree_uninteresting(entry->item.tree);
+               else
+                       mark_blob_uninteresting(entry->item.blob);
+               entry = entry->next;
+       }
 }
 
 static void mark_parents_uninteresting(struct commit *commit)
 {
        struct commit_list *parents = commit->parents;
 
+       if (tree_objects)
+               mark_tree_uninteresting(commit->tree);
        while (parents) {
                struct commit *commit = parents->item;
                commit->object.flags |= UNINTERESTING;
@@ -220,20 +307,6 @@ struct commit_list *limit_list(struct commit_list *list)
        return newlist;
 }
 
-static enum cmit_fmt get_commit_format(const char *arg)
-{
-       if (!*arg)
-               return CMIT_FMT_DEFAULT;
-       if (!strcmp(arg, "=raw"))
-               return CMIT_FMT_RAW;
-       if (!strcmp(arg, "=medium"))
-               return CMIT_FMT_MEDIUM;
-       if (!strcmp(arg, "=short"))
-               return CMIT_FMT_SHORT;
-       usage(rev_list_usage);  
-}                      
-
-
 int main(int argc, char **argv)
 {
        struct commit_list *list = NULL;
@@ -276,6 +349,11 @@ int main(int argc, char **argv)
                        bisect_list = 1;
                        continue;
                }
+               if (!strcmp(arg, "--objects")) {
+                       tree_objects = 1;
+                       blob_objects = 1;
+                       continue;
+               }
                if (!strncmp(arg, "--merge-order", 13)) {
                        merge_order = 1;
                        continue;