diff options
Diffstat (limited to 'revision.c')
-rw-r--r-- | revision.c | 202 |
1 files changed, 81 insertions, 121 deletions
diff --git a/revision.c b/revision.c index 0b322b4fdc..224ed1961a 100644 --- a/revision.c +++ b/revision.c @@ -18,72 +18,20 @@ #include "commit-slab.h" #include "dir.h" #include "cache-tree.h" +#include "bisect.h" volatile show_early_output_fn_t show_early_output; -char *path_name(const struct name_path *path, const char *name) -{ - const struct name_path *p; - char *n, *m; - int nlen = strlen(name); - int len = nlen + 1; - - for (p = path; p; p = p->up) { - if (p->elem_len) - len += p->elem_len + 1; - } - n = xmalloc(len); - m = n + len - (nlen + 1); - strcpy(m, name); - for (p = path; p; p = p->up) { - if (p->elem_len) { - m -= p->elem_len + 1; - memcpy(m, p->elem, p->elem_len); - m[p->elem_len] = '/'; - } - } - return n; -} +static const char *term_bad; +static const char *term_good; -static int show_path_component_truncated(FILE *out, const char *name, int len) +void show_object_with_name(FILE *out, struct object *obj, const char *name) { - int cnt; - for (cnt = 0; cnt < len; cnt++) { - int ch = name[cnt]; - if (!ch || ch == '\n') - return -1; - fputc(ch, out); - } - return len; -} + const char *p; -static int show_path_truncated(FILE *out, const struct name_path *path) -{ - int emitted, ours; - - if (!path) - return 0; - emitted = show_path_truncated(out, path->up); - if (emitted < 0) - return emitted; - if (emitted) - fputc('/', out); - ours = show_path_component_truncated(out, path->elem, path->elem_len); - if (ours < 0) - return ours; - return ours || emitted; -} - -void show_object_with_name(FILE *out, struct object *obj, - const struct name_path *path, const char *component) -{ - struct name_path leaf; - leaf.up = (struct name_path *)path; - leaf.elem = component; - leaf.elem_len = strlen(component); - - fprintf(out, "%s ", sha1_to_hex(obj->sha1)); - show_path_truncated(out, &leaf); + fprintf(out, "%s ", oid_to_hex(&obj->oid)); + for (p = name; *p && *p != '\n'; p++) + fputc(*p, out); fputc('\n', out); } @@ -102,10 +50,10 @@ static void mark_tree_contents_uninteresting(struct tree *tree) struct name_entry entry; struct object *obj = &tree->object; - if (!has_sha1_file(obj->sha1)) + if (!has_object_file(&obj->oid)) return; if (parse_tree(tree) < 0) - die("bad tree %s", sha1_to_hex(obj->sha1)); + die("bad tree %s", oid_to_hex(&obj->oid)); init_tree_desc(&desc, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { @@ -131,10 +79,12 @@ static void mark_tree_contents_uninteresting(struct tree *tree) void mark_tree_uninteresting(struct tree *tree) { - struct object *obj = &tree->object; + struct object *obj; if (!tree) return; + + obj = &tree->object; if (obj->flags & UNINTERESTING) return; obj->flags |= UNINTERESTING; @@ -149,10 +99,7 @@ void mark_parents_uninteresting(struct commit *commit) commit_list_insert(l->item, &parents); while (parents) { - struct commit *commit = parents->item; - l = parents; - parents = parents->next; - free(l); + struct commit *commit = pop_commit(&parents); while (commit) { /* @@ -163,7 +110,7 @@ void mark_parents_uninteresting(struct commit *commit) * 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)) + if (!has_object_file(&commit->object.oid)) commit->object.parsed = 1; if (commit->object.flags & UNINTERESTING) @@ -281,19 +228,18 @@ static struct commit *handle_commit(struct rev_info *revs, add_pending_object(revs, object, tag->tag); if (!tag->tagged) die("bad tag"); - object = parse_object(tag->tagged->sha1); + object = parse_object(tag->tagged->oid.hash); if (!object) { if (flags & UNINTERESTING) return NULL; - die("bad object %s", sha1_to_hex(tag->tagged->sha1)); + die("bad object %s", oid_to_hex(&tag->tagged->oid)); } object->flags |= flags; /* * We'll handle the tagged object by looping or dropping * through to the non-tag handlers below. Do not - * propagate data from the tag's pending entry. + * propagate path data from the tag's pending entry. */ - name = ""; path = NULL; mode = 0; } @@ -361,8 +307,8 @@ static int everybody_uninteresting(struct commit_list *orig, list = list->next; if (commit->object.flags & UNINTERESTING) continue; - if (interesting_cache) - *interesting_cache = commit; + + *interesting_cache = commit; return 0; } return 1; @@ -509,7 +455,7 @@ static int rev_compare_tree(struct rev_info *revs, tree_difference = REV_TREE_SAME; DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); - if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", + if (diff_tree_sha1(t1->object.oid.hash, t2->object.oid.hash, "", &revs->pruning) < 0) return REV_TREE_DIFFERENT; return tree_difference; @@ -525,7 +471,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit) tree_difference = REV_TREE_SAME; DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); - retval = diff_tree_sha1(NULL, t1->object.sha1, "", &revs->pruning); + retval = diff_tree_sha1(NULL, t1->object.oid.hash, "", &revs->pruning); return retval >= 0 && (tree_difference == REV_TREE_SAME); } @@ -538,7 +484,7 @@ struct treesame_state { static struct treesame_state *initialise_treesame(struct rev_info *revs, struct commit *commit) { unsigned n = commit_list_count(commit->parents); - struct treesame_state *st = xcalloc(1, sizeof(*st) + n); + struct treesame_state *st = xcalloc(1, st_add(sizeof(*st), n)); st->nparents = n; add_decoration(&revs->treesame, &commit->object, st); return st; @@ -609,7 +555,7 @@ static unsigned update_treesame(struct rev_info *revs, struct commit *commit) st = lookup_decoration(&revs->treesame, &commit->object); if (!st) - die("update_treesame %s", sha1_to_hex(commit->object.sha1)); + die("update_treesame %s", oid_to_hex(&commit->object.oid)); relevant_parents = 0; relevant_change = irrelevant_change = 0; for (p = commit->parents, n = 0; p; n++, p = p->next) { @@ -707,8 +653,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) } if (parse_commit(p) < 0) die("cannot simplify commit %s (because of %s)", - sha1_to_hex(commit->object.sha1), - sha1_to_hex(p->object.sha1)); + oid_to_hex(&commit->object.oid), + oid_to_hex(&p->object.oid)); switch (rev_compare_tree(revs, p, commit)) { case REV_TREE_SAME: if (!revs->simplify_history || !relevant_commit(p)) { @@ -740,8 +686,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) */ if (parse_commit(p) < 0) die("cannot simplify commit %s (invalid %s)", - sha1_to_hex(commit->object.sha1), - sha1_to_hex(p->object.sha1)); + oid_to_hex(&commit->object.oid), + oid_to_hex(&p->object.oid)); p->parents = NULL; } /* fallthrough */ @@ -753,7 +699,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) irrelevant_change = 1; continue; } - die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1)); + die("bad tree compare for commit %s", oid_to_hex(&commit->object.oid)); } /* @@ -1098,14 +1044,10 @@ static int limit_list(struct rev_info *revs) } while (list) { - struct commit_list *entry = list; - struct commit *commit = list->item; + struct commit *commit = pop_commit(&list); struct object *obj = &commit->object; show_early_output_fn_t show; - list = list->next; - free(entry); - if (commit == interesting_cache) interesting_cache = NULL; @@ -1192,7 +1134,7 @@ static void add_rev_cmdline_list(struct rev_info *revs, { while (commit_list) { struct object *object = &commit_list->item->object; - add_rev_cmdline(revs, object, sha1_to_hex(object->sha1), + add_rev_cmdline(revs, object, oid_to_hex(&object->oid), whence, flags); commit_list = commit_list->next; } @@ -1218,7 +1160,8 @@ int ref_excluded(struct string_list *ref_excludes, const char *path) return 0; } -static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) +static int handle_one_ref(const char *path, const struct object_id *oid, + int flag, void *cb_data) { struct all_refs_cb *cb = cb_data; struct object *object; @@ -1226,9 +1169,9 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, if (ref_excluded(cb->all_revs->ref_excludes, path)) return 0; - object = get_reference(cb->all_revs, path, sha1, cb->all_flags); + object = get_reference(cb->all_revs, path, oid->hash, cb->all_flags); add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags); - add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags); + add_pending_sha1(cb->all_revs, path, oid->hash, cb->all_flags); return 0; } @@ -1292,7 +1235,8 @@ static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, return 0; } -static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data) +static int handle_one_reflog(const char *path, const struct object_id *oid, + int flag, void *cb_data) { struct all_refs_cb *cb = cb_data; cb->warned_bad_reflog = 0; @@ -1304,6 +1248,7 @@ static int handle_one_reflog(const char *path, const unsigned char *sha1, int fl void add_reflogs_to_pending(struct rev_info *revs, unsigned flags) { struct all_refs_cb cb; + cb.all_revs = revs; cb.all_flags = flags; for_each_reflog(handle_one_reflog, &cb); @@ -1378,7 +1323,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags) break; if (!((struct tag*)it)->tagged) return 0; - hashcpy(sha1, ((struct tag*)it)->tagged->sha1); + hashcpy(sha1, ((struct tag*)it)->tagged->oid.hash); } if (it->type != OBJ_COMMIT) return 0; @@ -1435,7 +1380,7 @@ static void add_pending_commit_list(struct rev_info *revs, while (commit_list) { struct object *object = &commit_list->item->object; object->flags |= flags; - add_pending_object(revs, object, sha1_to_hex(object->sha1)); + add_pending_object(revs, object, oid_to_hex(&object->oid)); commit_list = commit_list->next; } } @@ -1555,10 +1500,10 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi a = (a_obj->type == OBJ_COMMIT ? (struct commit *)a_obj - : lookup_commit_reference(a_obj->sha1)); + : lookup_commit_reference(a_obj->oid.hash)); b = (b_obj->type == OBJ_COMMIT ? (struct commit *)b_obj - : lookup_commit_reference(b_obj->sha1)); + : lookup_commit_reference(b_obj->oid.hash)); if (!a || !b) goto missing; exclude = get_merge_bases(a, b); @@ -1993,10 +1938,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--full-history")) { revs->simplify_history = 0; } else if (!strcmp(arg, "--relative-date")) { - revs->date_mode = DATE_RELATIVE; + revs->date_mode.type = DATE_RELATIVE; revs->date_mode_explicit = 1; } else if ((argcount = parse_long_opt("date", argv, &optarg))) { - revs->date_mode = parse_date_format(optarg); + parse_date_format(optarg, &revs->date_mode); revs->date_mode_explicit = 1; return argcount; } else if (!strcmp(arg, "--log-size")) { @@ -2048,7 +1993,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--ignore-missing")) { revs->ignore_missing = 1; } else { - int opts = diff_opt_parse(&revs->diffopt, argv, argc); + int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix); if (!opts) unkv[(*unkc)++] = arg; return opts; @@ -2073,14 +2018,23 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, ctx->argc -= n; } +static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data, const char *term) { + struct strbuf bisect_refs = STRBUF_INIT; + int status; + strbuf_addf(&bisect_refs, "refs/bisect/%s", term); + status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data); + strbuf_release(&bisect_refs); + return status; +} + static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data) { - return for_each_ref_in_submodule(submodule, "refs/bisect/bad", fn, cb_data); + return for_each_bisect_ref(submodule, fn, cb_data, term_bad); } static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data) { - return for_each_ref_in_submodule(submodule, "refs/bisect/good", fn, cb_data); + return for_each_bisect_ref(submodule, fn, cb_data, term_good); } static int handle_revision_pseudo_opt(const char *submodule, @@ -2109,6 +2063,7 @@ static int handle_revision_pseudo_opt(const char *submodule, handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule); clear_ref_exclusion(&revs->ref_excludes); } else if (!strcmp(arg, "--bisect")) { + read_bisect_terms(&term_bad, &term_good); handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref); handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref); revs->bisect = 1; @@ -2170,6 +2125,21 @@ static int handle_revision_pseudo_opt(const char *submodule, return 1; } +static void NORETURN diagnose_missing_default(const char *def) +{ + unsigned char sha1[20]; + int flags; + const char *refname; + + refname = resolve_ref_unsafe(def, 0, sha1, &flags); + if (!refname || !(flags & REF_ISSYMREF) || (flags & REF_ISBROKEN)) + die(_("your current branch appears to be broken")); + + skip_prefix(refname, "refs/heads/", &refname); + die(_("your current branch '%s' does not have any commits yet"), + refname); +} + /* * Parse revision information, filling in the "rev_info" structure, * and removing the used arguments from the argument list. @@ -2299,7 +2269,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s struct object *object; struct object_context oc; if (get_sha1_with_context(revs->def, 0, sha1, &oc)) - die("bad default revision '%s'", revs->def); + diagnose_missing_default(revs->def); object = get_reference(revs, revs->def, sha1, 0); add_pending_object_with_mode(revs, object, revs->def, oc.mode); } @@ -2701,10 +2671,7 @@ static void simplify_merges(struct rev_info *revs) yet_to_do = NULL; tail = &yet_to_do; while (list) { - commit = list->item; - next = list->next; - free(list); - list = next; + commit = pop_commit(&list); tail = simplify_one(revs, commit, tail); } } @@ -2716,10 +2683,7 @@ static void simplify_merges(struct rev_info *revs) while (list) { struct merge_simplify_state *st; - commit = list->item; - next = list->next; - free(list); - list = next; + commit = pop_commit(&list); st = locate_simplify_state(revs, commit); if (st->simplified == commit) tail = &commit_list_insert(commit, tail)->next; @@ -2919,7 +2883,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) if (opt->show_notes) { if (!buf.len) strbuf_addstr(&buf, message); - format_display_notes(commit->object.sha1, &buf, encoding, 1); + format_display_notes(commit->object.oid.hash, &buf, encoding, 1); } /* @@ -2949,7 +2913,7 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi { if (commit->object.flags & SHOWN) return commit_ignore; - if (revs->unpacked && has_sha1_pack(commit->object.sha1)) + if (revs->unpacked && has_sha1_pack(commit->object.oid.hash)) return commit_ignore; if (revs->show_all) return commit_show; @@ -3075,7 +3039,7 @@ static void track_linear(struct rev_info *revs, struct commit *commit) struct commit_list *p; for (p = revs->previous_parents; p; p = p->next) if (p->item == NULL || /* first commit */ - !hashcmp(p->item->object.sha1, commit->object.sha1)) + !oidcmp(&p->item->object.oid, &commit->object.oid)) break; revs->linear = p != NULL; } @@ -3093,11 +3057,7 @@ static struct commit *get_revision_1(struct rev_info *revs) return NULL; do { - struct commit_list *entry = revs->commits; - struct commit *commit = entry->item; - - revs->commits = entry->next; - free(entry); + struct commit *commit = pop_commit(&revs->commits); if (revs->reflog_info) { save_parents(revs, commit); @@ -3117,7 +3077,7 @@ static struct commit *get_revision_1(struct rev_info *revs) if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) { if (!revs->ignore_missing_links) die("Failed to traverse parents of commit %s", - sha1_to_hex(commit->object.sha1)); + oid_to_hex(&commit->object.oid)); } } @@ -3126,7 +3086,7 @@ static struct commit *get_revision_1(struct rev_info *revs) continue; case commit_error: die("Failed to simplify parents of commit %s", - sha1_to_hex(commit->object.sha1)); + oid_to_hex(&commit->object.oid)); default: if (revs->track_linear) track_linear(revs, commit); |