diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-04 14:38:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-04 14:38:28 -0700 |
commit | 337cb3fb8da45f10fe9a0c3cf571600f55ead2ce (patch) | |
tree | a0b72bf6b71119b47b65072ef45592f69749a07d /rev-list.c | |
parent | dba385bb3ed541c4d18e2b8080960eee358394fa (diff) | |
download | git-337cb3fb8da45f10fe9a0c3cf571600f55ead2ce.tar.gz |
git-rev-list: allow arbitrary head selections, use git-rev-tree syntax
This makes git-rev-list use the same command line syntax to mark the
commits as git-rev-tree does, and instead of just allowing a start and
end commit, it allows an arbitrary list of "interesting" and "uninteresting"
commits.
For example, imagine that you had three branches (a, b and c) that you
are interested in, but you don't want to see stuff that already exists
in another persons three releases (x, y and z). You can do
git-rev-list a b c ^x ^y ^z
(order doesn't matter, btw - feel free to put the uninteresting ones
first or otherwise swithc them around), and it will show all the
commits that are reachable from a/b/c but not reachable from x/y/z.
The old syntax "git-rev-list start end" would not be written as
"git-rev-list start ^end", or "git-rev-list ^end start".
There's no limit to the number of heads you can specify (unlike
git-rev-tree, which can handle a maximum of 16 heads).
Diffstat (limited to 'rev-list.c')
-rw-r--r-- | rev-list.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/rev-list.c b/rev-list.c index 56dd814c0e..cbfc5c439d 100644 --- a/rev-list.c +++ b/rev-list.c @@ -84,7 +84,7 @@ static int everybody_uninteresting(struct commit_list *list) return 1; } -struct commit_list *limit_list(struct commit_list *list, struct commit *end) +struct commit_list *limit_list(struct commit_list *list) { struct commit_list *newlist = NULL; struct commit_list **p = &newlist; @@ -92,7 +92,7 @@ struct commit_list *limit_list(struct commit_list *list, struct commit *end) struct commit *commit = pop_most_recent_commit(&list, SEEN); struct object *obj = &commit->object; - if (commit == end || (obj->flags & UNINTERESTING)) { + if (obj->flags & UNINTERESTING) { mark_parents_uninteresting(commit); if (everybody_uninteresting(list)) break; @@ -105,15 +105,14 @@ struct commit_list *limit_list(struct commit_list *list, struct commit *end) int main(int argc, char **argv) { - int nr_sha; - unsigned char sha1[2][20]; struct commit_list *list = NULL; - struct commit *commit, *end; - int i; + int i, limited = 0; - nr_sha = 0; for (i = 1 ; i < argc; i++) { + int flags; char *arg = argv[i]; + unsigned char sha1[20]; + struct commit *commit; if (!strncmp(arg, "--max-count=", 12)) { max_count = atoi(arg + 12); @@ -143,28 +142,26 @@ int main(int argc, char **argv) continue; } - if (nr_sha > 2 || get_sha1(arg, sha1[nr_sha])) + flags = 0; + if (*arg == '^') { + flags = UNINTERESTING; + arg++; + limited = 1; + } + if (get_sha1(arg, sha1)) usage(rev_list_usage); - nr_sha++; + commit = lookup_commit_reference(sha1); + if (!commit || parse_commit(commit) < 0) + die("bad commit object %s", arg); + commit->object.flags |= flags; + commit_list_insert(commit, &list); } - if (!nr_sha) + if (!list) usage(rev_list_usage); - commit = lookup_commit_reference(sha1[0]); - if (!commit || parse_commit(commit) < 0) - die("bad starting commit object"); - - end = NULL; - if (nr_sha > 1) { - end = lookup_commit_reference(sha1[1]); - if (!end || parse_commit(end) < 0) - die("bad ending commit object"); - } - - commit_list_insert(commit, &list); - if (end) - list = limit_list(list, end); + if (limited) + list = limit_list(list); show_commit_list(list); return 0; |