X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=revision.c;h=a3df8100763136e8936b8e3b4c647d5b83cc7239;hb=061ad5f4de16b4997f1de962dc4512546c62fe53;hp=f1ac62d7d85453b0d4b9b3969a432b1a488c4c60;hpb=a4a88b2bab3b6fb0b30f63418701f42388e0fe0a;p=git.git diff --git a/revision.c b/revision.c index f1ac62d7..a3df8100 100644 --- a/revision.c +++ b/revision.c @@ -381,6 +381,9 @@ static void limit_list(struct rev_info *revs) struct commit_list *newlist = NULL; struct commit_list **p = &newlist; + if (revs->paths) + diff_tree_setup_paths(revs->paths); + while (list) { struct commit_list *entry = list; struct commit *commit = list->item; @@ -436,12 +439,13 @@ static void handle_all(struct rev_info *revs, unsigned flags) * Parse revision information, filling in the "rev_info" structure, * and removing the used arguments from the argument list. * - * Returns the number of arguments left ("new argc"). + * Returns the number of arguments left that weren't recognized + * (which are also moved to the head of the argument list) */ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def) { int i, flags, seen_dashdash; - const char **unrecognized = argv+1; + const char **unrecognized = argv + 1; int left = 1; memset(revs, 0, sizeof(*revs)); @@ -478,6 +482,21 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->max_count = atoi(arg + 12); continue; } + /* accept -, like traditilnal "head" */ + if ((*arg == '-') && isdigit(arg[1])) { + revs->max_count = atoi(arg + 1); + continue; + } + if (!strcmp(arg, "-n")) { + if (argc <= i + 1) + die("-n requires an argument"); + revs->max_count = atoi(argv[++i]); + continue; + } + if (!strncmp(arg,"-n",2)) { + revs->max_count = atoi(arg + 2); + continue; + } if (!strncmp(arg, "--max-age=", 10)) { revs->max_age = atoi(arg + 10); revs->limited = 1; @@ -488,6 +507,26 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->limited = 1; continue; } + if (!strncmp(arg, "--since=", 8)) { + revs->max_age = approxidate(arg + 8); + revs->limited = 1; + continue; + } + if (!strncmp(arg, "--after=", 8)) { + revs->max_age = approxidate(arg + 8); + revs->limited = 1; + continue; + } + if (!strncmp(arg, "--before=", 9)) { + revs->min_age = approxidate(arg + 9); + revs->limited = 1; + continue; + } + if (!strncmp(arg, "--until=", 8)) { + revs->min_age = approxidate(arg + 8); + revs->limited = 1; + continue; + } if (!strcmp(arg, "--all")) { handle_all(revs, flags); continue; @@ -525,6 +564,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->remove_empty_trees = 1; continue; } + if (!strncmp(arg, "--no-merges", 11)) { + revs->no_merges = 1; + continue; + } if (!strcmp(arg, "--objects")) { revs->tag_objects = 1; revs->tree_objects = 1; @@ -601,14 +644,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } if (revs->paths) revs->limited = 1; - *unrecognized = NULL; return left; } void prepare_revision_walk(struct rev_info *revs) { - if (revs->paths) - diff_tree_setup_paths(revs->paths); sort_by_date(&revs->commits); if (revs->limited) limit_list(revs); @@ -616,11 +656,67 @@ void prepare_revision_walk(struct rev_info *revs) sort_in_topological_order(&revs->commits, revs->lifo); } +static int rewrite_one(struct commit **pp) +{ + for (;;) { + struct commit *p = *pp; + if (p->object.flags & (TREECHANGE | UNINTERESTING)) + return 0; + if (!p->parents) + return -1; + *pp = p->parents->item; + } +} + +static void rewrite_parents(struct commit *commit) +{ + struct commit_list **pp = &commit->parents; + while (*pp) { + struct commit_list *parent = *pp; + if (rewrite_one(&parent->item) < 0) { + *pp = parent->next; + continue; + } + pp = &parent->next; + } +} + struct commit *get_revision(struct rev_info *revs) { - if (!revs->commits) + struct commit_list *list = revs->commits; + struct commit *commit; + + if (!list) return NULL; - return pop_most_recent_commit(&revs->commits, SEEN); -} + /* Check the max_count ... */ + commit = list->item; + switch (revs->max_count) { + case -1: + break; + case 0: + return NULL; + default: + revs->max_count--; + } + do { + commit = pop_most_recent_commit(&revs->commits, SEEN); + if (commit->object.flags & (UNINTERESTING|SHOWN)) + continue; + if (revs->min_age != -1 && (commit->date > revs->min_age)) + continue; + if (revs->max_age != -1 && (commit->date < revs->max_age)) + return NULL; + if (revs->no_merges && commit->parents && commit->parents->next) + continue; + if (revs->paths && revs->dense) { + if (!(commit->object.flags & TREECHANGE)) + continue; + rewrite_parents(commit); + } + commit->object.flags |= SHOWN; + return commit; + } while (revs->commits); + return NULL; +}