X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=revision.c;h=b12c25e2b0c8e2c1d3bb097739f3c132a296c964;hb=27c96c4fd38ffbde98df22699c755a043bb383d1;hp=ce70f48ce0880e8b43c3f62cd13bc185bfee8c4b;hpb=520d7e278cfd25057e883575060b7378dfab61dc;p=git.git diff --git a/revision.c b/revision.c index ce70f48ce..b12c25e2b 100644 --- a/revision.c +++ b/revision.c @@ -114,16 +114,21 @@ void mark_parents_uninteresting(struct commit *commit) } } -void add_pending_object(struct rev_info *revs, struct object *obj, const char *name) +static void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode) { if (revs->no_walk && (obj->flags & UNINTERESTING)) die("object ranges do not make sense when not walking revisions"); - add_object_array(obj, name, &revs->pending); + add_object_array_with_mode(obj, name, &revs->pending, mode); if (revs->reflog_info && obj->type == OBJ_COMMIT) add_reflog_for_walk(revs->reflog_info, (struct commit *)obj, name); } +void add_pending_object(struct rev_info *revs, struct object *obj, const char *name) +{ + add_pending_object_with_mode(revs, obj, name, S_IFINVALID); +} + static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags) { struct object *object; @@ -257,7 +262,7 @@ static void file_change(struct diff_options *options, options->has_changes = 1; } -int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2) +static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2) { if (!t1) return REV_TREE_NEW; @@ -271,7 +276,7 @@ int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2) return tree_difference; } -int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1) +static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1) { int retval; void *tree; @@ -313,7 +318,10 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) while ((parent = *pp) != NULL) { struct commit *p = parent->item; - parse_commit(p); + 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)); switch (rev_compare_tree(revs, p->tree, commit->tree)) { case REV_TREE_SAME: tree_same = 1; @@ -342,7 +350,10 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) * IOW, we pretend this parent is a * "root" commit. */ - parse_commit(p); + if (parse_commit(p) < 0) + die("cannot simplify commit %s (invalid %s)", + sha1_to_hex(commit->object.sha1), + sha1_to_hex(p->object.sha1)); p->parents = NULL; } /* fallthrough */ @@ -357,14 +368,14 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) commit->object.flags |= TREECHANGE; } -static void add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list) +static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list) { struct commit_list *parent = commit->parents; unsigned left_flag; int add, rest; if (commit->object.flags & ADDED) - return; + return 0; commit->object.flags |= ADDED; /* @@ -383,7 +394,8 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st while (parent) { struct commit *p = parent->item; parent = parent->next; - parse_commit(p); + if (parse_commit(p) < 0) + return -1; p->object.flags |= UNINTERESTING; if (p->parents) mark_parents_uninteresting(p); @@ -392,7 +404,7 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st p->object.flags |= SEEN; insert_by_date(p, list); } - return; + return 0; } /* @@ -404,7 +416,7 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st revs->prune_fn(revs, commit); if (revs->no_walk) - return; + return 0; left_flag = (commit->object.flags & SYMMETRIC_LEFT); @@ -413,7 +425,8 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st struct commit *p = parent->item; parent = parent->next; - parse_commit(p); + if (parse_commit(p) < 0) + return -1; p->object.flags |= left_flag; if (p->object.flags & SEEN) continue; @@ -421,6 +434,7 @@ static void add_parents_to_list(struct rev_info *revs, struct commit *commit, st if (add) insert_by_date(p, list); } + return 0; } static void cherry_pick_list(struct commit_list *list) @@ -503,7 +517,7 @@ static void cherry_pick_list(struct commit_list *list) free_patch_ids(&ids); } -static void limit_list(struct rev_info *revs) +static int limit_list(struct rev_info *revs) { struct commit_list *list = revs->commits; struct commit_list *newlist = NULL; @@ -519,7 +533,8 @@ static void limit_list(struct rev_info *revs) if (revs->max_age != -1 && (commit->date < revs->max_age)) obj->flags |= UNINTERESTING; - add_parents_to_list(revs, commit, &list); + if (add_parents_to_list(revs, commit, &list) < 0) + return -1; if (obj->flags & UNINTERESTING) { mark_parents_uninteresting(commit); if (everybody_uninteresting(list)) @@ -534,6 +549,7 @@ static void limit_list(struct rev_info *revs) cherry_pick_list(newlist); revs->commits = newlist; + return 0; } struct all_refs_cb { @@ -723,6 +739,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, int cant_be_filename) { + unsigned mode; char *dotdot; struct object *object; unsigned char sha1[20]; @@ -796,12 +813,12 @@ int handle_revision_arg(const char *arg, struct rev_info *revs, local_flags = UNINTERESTING; arg++; } - if (get_sha1(arg, sha1)) + if (get_sha1_with_mode(arg, sha1, &mode)) return -1; if (!cant_be_filename) verify_non_filename(revs->prefix, arg); object = get_reference(revs, arg, sha1, flags ^ local_flags); - add_pending_object(revs, object, arg); + add_pending_object_with_mode(revs, object, arg, mode); return 0; } @@ -864,6 +881,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch const char **unrecognized = argv + 1; int left = 1; int all_match = 0; + int regflags = 0; /* First, search for "--" */ seen_dashdash = 0; @@ -1105,7 +1123,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch continue; } if (!strcmp(arg, "--relative-date")) { - revs->relative_date = 1; + revs->date_mode = DATE_RELATIVE; + continue; + } + if (!strncmp(arg, "--date=", 7)) { + if (!strcmp(arg + 7, "relative")) + revs->date_mode = DATE_RELATIVE; + else if (!strcmp(arg + 7, "local")) + revs->date_mode = DATE_LOCAL; + else if (!strcmp(arg + 7, "default")) + revs->date_mode = DATE_NORMAL; + else + die("unknown date format %s", arg); continue; } @@ -1124,6 +1153,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch add_message_grep(revs, arg+7); continue; } + if (!prefixcmp(arg, "--extended-regexp")) { + regflags |= REG_EXTENDED; + continue; + } + if (!prefixcmp(arg, "--regexp-ignore-case")) { + regflags |= REG_ICASE; + continue; + } if (!strcmp(arg, "--all-match")) { all_match = 1; continue; @@ -1172,15 +1209,19 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } } + if (revs->grep_filter) + revs->grep_filter->regflags |= regflags; + if (show_merge) prepare_show_merge(revs); if (def && !revs->pending.nr) { unsigned char sha1[20]; struct object *object; - if (get_sha1(def, sha1)) + unsigned mode; + if (get_sha1_with_mode(def, sha1, &mode)) die("bad default revision '%s'", def); object = get_reference(revs, def, sha1, 0); - add_pending_object(revs, object, def); + add_pending_object_with_mode(revs, object, def, mode); } if (revs->topo_order) @@ -1209,7 +1250,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch return left; } -void prepare_revision_walk(struct rev_info *revs) +int prepare_revision_walk(struct rev_info *revs) { int nr = revs->pending.nr; struct object_array_entry *e, *list; @@ -1231,42 +1272,57 @@ void prepare_revision_walk(struct rev_info *revs) free(list); if (revs->no_walk) - return; + return 0; if (revs->limited) - limit_list(revs); + if (limit_list(revs) < 0) + return -1; if (revs->topo_order) sort_in_topological_order_fn(&revs->commits, revs->lifo, revs->topo_setter, revs->topo_getter); + return 0; } -static int rewrite_one(struct rev_info *revs, struct commit **pp) +enum rewrite_result { + rewrite_one_ok, + rewrite_one_noparents, + rewrite_one_error, +}; + +static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp) { for (;;) { struct commit *p = *pp; if (!revs->limited) - add_parents_to_list(revs, p, &revs->commits); + if (add_parents_to_list(revs, p, &revs->commits) < 0) + return rewrite_one_error; if (p->parents && p->parents->next) - return 0; + return rewrite_one_ok; if (p->object.flags & (TREECHANGE | UNINTERESTING)) - return 0; + return rewrite_one_ok; if (!p->parents) - return -1; + return rewrite_one_noparents; *pp = p->parents->item; } } -static void rewrite_parents(struct rev_info *revs, struct commit *commit) +static int rewrite_parents(struct rev_info *revs, struct commit *commit) { struct commit_list **pp = &commit->parents; while (*pp) { struct commit_list *parent = *pp; - if (rewrite_one(revs, &parent->item) < 0) { + switch (rewrite_one(revs, &parent->item)) { + case rewrite_one_ok: + break; + case rewrite_one_noparents: *pp = parent->next; continue; + case rewrite_one_error: + return -1; } pp = &parent->next; } + return 0; } static int commit_match(struct commit *commit, struct rev_info *opt) @@ -1302,7 +1358,8 @@ static struct commit *get_revision_1(struct rev_info *revs) if (revs->max_age != -1 && (commit->date < revs->max_age)) continue; - add_parents_to_list(revs, commit, &revs->commits); + if (add_parents_to_list(revs, commit, &revs->commits) < 0) + return NULL; } if (commit->object.flags & SHOWN) continue; @@ -1330,8 +1387,8 @@ static struct commit *get_revision_1(struct rev_info *revs) if (!commit->parents || !commit->parents->next) continue; } - if (revs->parents) - rewrite_parents(revs, commit); + if (revs->parents && rewrite_parents(revs, commit) < 0) + return NULL; } return commit; } while (revs->commits);