X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=rev-list.c;h=bf61b74db84f5befafaad2d0c70de0e5da22d218;hb=1cd3674add10d1e511446f3034a1d233a3da7eab;hp=16920ef69e844697628ca3775403f86cc1c13945;hpb=5e749e259b39a74b31f6c768588b4e628e3802cb;p=git.git diff --git a/rev-list.c b/rev-list.c index 16920ef6..bf61b74d 100644 --- a/rev-list.c +++ b/rev-list.c @@ -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;