diff options
author | Linus Torvalds <torvalds@osdl.org> | 2006-02-28 15:07:20 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-03-01 01:45:50 -0800 |
commit | 765ac8ec469f110e88376e4fac05d0ed475bcb28 (patch) | |
tree | 151dd9135fb335aeffc4b0e4406c8c4cf8b27e2c /revision.c | |
parent | 70b006b9712b57741ec1320b15aef2f8b1d6a905 (diff) | |
download | git-765ac8ec469f110e88376e4fac05d0ed475bcb28.tar.gz git-765ac8ec469f110e88376e4fac05d0ed475bcb28.tar.xz |
Rip out merge-order and make "git log <paths>..." work again.
Well, assuming breaking --merge-order is fine, here's a patch (on top of
the other ones) that makes
git log <filename>
actually work, as far as I can tell.
I didn't add the logic for --before/--after flags, but that should be
pretty trivial, and is independent of this anyway.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'revision.c')
-rw-r--r-- | revision.c | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/revision.c b/revision.c index f1ac62d7d..c84f14609 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)); @@ -525,6 +529,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 +609,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 +621,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; +} |