X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-rev-list.c;h=bc48a3e23081264d06f2659181a19b31694dd993;hb=3899e7a329aabfc22eca9beb82599e1bb214b3d2;hp=f11dbd65c14a196f92c98d5c16be0cda74a1edf1;hpb=4868f3729acce2aa9512ded7179a895cc50f64c8;p=git.git diff --git a/builtin-rev-list.c b/builtin-rev-list.c index f11dbd65c..bc48a3e23 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -39,9 +39,9 @@ static const char rev_list_usage[] = static struct rev_info revs; -static int bisect_list = 0; -static int show_timestamp = 0; -static int hdr_termination = 0; +static int bisect_list; +static int show_timestamp; +static int hdr_termination; static const char *header_prefix; static void show_commit(struct commit *commit) @@ -89,99 +89,113 @@ static void show_commit(struct commit *commit) printf("%s%c", pretty_header, hdr_termination); } fflush(stdout); + if (commit->parents) { + free_commit_list(commit->parents); + commit->parents = NULL; + } + if (commit->buffer) { + free(commit->buffer); + commit->buffer = NULL; + } } -static struct object_list **process_blob(struct blob *blob, - struct object_list **p, - struct name_path *path, - const char *name) +static void process_blob(struct blob *blob, + struct object_array *p, + struct name_path *path, + const char *name) { struct object *obj = &blob->object; if (!revs.blob_objects) - return p; + return; if (obj->flags & (UNINTERESTING | SEEN)) - return p; + return; obj->flags |= SEEN; - return add_object(obj, p, path, name); + name = strdup(name); + add_object(obj, p, path, name); } -static struct object_list **process_tree(struct tree *tree, - struct object_list **p, - struct name_path *path, - const char *name) +static void process_tree(struct tree *tree, + struct object_array *p, + struct name_path *path, + const char *name) { struct object *obj = &tree->object; - struct tree_entry_list *entry; + struct tree_desc desc; + struct name_entry entry; struct name_path me; if (!revs.tree_objects) - return p; + return; if (obj->flags & (UNINTERESTING | SEEN)) - return p; + return; if (parse_tree(tree) < 0) die("bad tree object %s", sha1_to_hex(obj->sha1)); obj->flags |= SEEN; - p = add_object(obj, p, path, name); + name = strdup(name); + add_object(obj, p, path, name); me.up = path; me.elem = name; me.elem_len = strlen(name); - entry = tree->entries; - tree->entries = NULL; - while (entry) { - struct tree_entry_list *next = entry->next; - if (entry->directory) - p = process_tree(entry->item.tree, p, &me, entry->name); + + desc.buf = tree->buffer; + desc.size = tree->size; + + while (tree_entry(&desc, &entry)) { + if (S_ISDIR(entry.mode)) + process_tree(lookup_tree(entry.sha1), p, &me, entry.path); else - p = process_blob(entry->item.blob, p, &me, entry->name); - free(entry); - entry = next; + process_blob(lookup_blob(entry.sha1), p, &me, entry.path); } - return p; + free(tree->buffer); + tree->buffer = NULL; } static void show_commit_list(struct rev_info *revs) { + int i; struct commit *commit; - struct object_list *objects = NULL, **p = &objects, *pending; + struct object_array objects = { 0, 0, NULL }; while ((commit = get_revision(revs)) != NULL) { - p = process_tree(commit->tree, p, NULL, ""); + process_tree(commit->tree, &objects, NULL, ""); show_commit(commit); } - for (pending = revs->pending_objects; pending; pending = pending->next) { + for (i = 0; i < revs->pending.nr; i++) { + struct object_array_entry *pending = revs->pending.objects + i; struct object *obj = pending->item; const char *name = pending->name; if (obj->flags & (UNINTERESTING | SEEN)) continue; - if (obj->type == tag_type) { + if (obj->type == OBJ_TAG) { obj->flags |= SEEN; - p = add_object(obj, p, NULL, name); + add_object_array(obj, name, &objects); continue; } - if (obj->type == tree_type) { - p = process_tree((struct tree *)obj, p, NULL, name); + if (obj->type == OBJ_TREE) { + process_tree((struct tree *)obj, &objects, NULL, name); continue; } - if (obj->type == blob_type) { - p = process_blob((struct blob *)obj, p, NULL, name); + if (obj->type == OBJ_BLOB) { + process_blob((struct blob *)obj, &objects, NULL, name); continue; } die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name); } - while (objects) { + for (i = 0; i < objects.nr; i++) { + struct object_array_entry *p = objects.objects + i; + /* An object with name "foo\n0000000..." can be used to * confuse downstream git-pack-objects very badly. */ - const char *ep = strchr(objects->name, '\n'); + const char *ep = strchr(p->name, '\n'); if (ep) { - printf("%s %.*s\n", sha1_to_hex(objects->item->sha1), - (int) (ep - objects->name), - objects->name); + printf("%s %.*s\n", sha1_to_hex(p->item->sha1), + (int) (ep - p->name), + p->name); } else - printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name); - objects = objects->next; + printf("%s %s\n", sha1_to_hex(p->item->sha1), p->name); } } @@ -292,12 +306,12 @@ static void mark_edges_uninteresting(struct commit_list *list) } } -int cmd_rev_list(int argc, const char **argv, char **envp) +int cmd_rev_list(int argc, const char **argv, const char *prefix) { struct commit_list *list; int i; - init_revisions(&revs); + init_revisions(&revs, prefix); revs.abbrev = 0; revs.commit_format = CMIT_FMT_UNSPECIFIED; argc = setup_revisions(argc, argv, &revs, NULL); @@ -336,7 +350,7 @@ int cmd_rev_list(int argc, const char **argv, char **envp) if ((!list && (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && - !revs.pending_objects)) || + !revs.pending.nr)) || revs.diff) usage(rev_list_usage);