summaryrefslogtreecommitdiff
path: root/revision.c
diff options
context:
space:
mode:
authorMichael J Gruber <git@drmicha.warpmail.net>2011-03-21 10:14:06 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-03-23 17:16:44 (GMT)
commitad5aeeded3295589b2573b143f754762a56f8f82 (patch)
tree264a93fc2b35d7e97ae4cd89b16d011cd4e149fa /revision.c
parent8ee50594889056322f2fc00a589a36e83b9119fd (diff)
downloadgit-ad5aeeded3295589b2573b143f754762a56f8f82.zip
git-ad5aeeded3295589b2573b143f754762a56f8f82.tar.gz
git-ad5aeeded3295589b2573b143f754762a56f8f82.tar.bz2
revision.c: introduce --min-parents and --max-parents options
Introduce --min-parents and --max-parents options which limit the revisions to those commits which have at least (or at most) that many commits, where negative arguments for --max-parents= denote infinity (i.e. no upper limit). In particular: --max-parents=1 is the same as --no-merges; --min-parents=2 is the same as --merges; --max-parents=0 shows only roots; and --min-parents=3 shows only octopus merges Using --min-parents=n and --max-parents=m with n>m gives you what you ask for (i.e. nothing) for obvious reasons, just like when you give --merges (show only merge commits) and --no-merges (show only non-merge commits) at the same time. Also, introduce --no-min-parents and --no-max-parents to do the obvious thing for convenience. We compute the number of parents only when we limit by that, so there is no performance impact when there are no limiters. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'revision.c')
-rw-r--r--revision.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/revision.c b/revision.c
index 626f6a2..8540a5d 100644
--- a/revision.c
+++ b/revision.c
@@ -945,6 +945,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->min_age = -1;
revs->skip_count = -1;
revs->max_count = -1;
+ revs->max_parents = -1;
revs->commit_format = CMIT_FMT_DEFAULT;
@@ -1280,9 +1281,17 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
} else if (!strcmp(arg, "--remove-empty")) {
revs->remove_empty_trees = 1;
} else if (!strcmp(arg, "--merges")) {
- revs->merges_only = 1;
+ revs->min_parents = 2;
} else if (!strcmp(arg, "--no-merges")) {
- revs->no_merges = 1;
+ revs->max_parents = 1;
+ } else if (!prefixcmp(arg, "--min-parents=")) {
+ revs->min_parents = atoi(arg+14);
+ } else if (!prefixcmp(arg, "--no-min-parents")) {
+ revs->min_parents = 0;
+ } else if (!prefixcmp(arg, "--max-parents=")) {
+ revs->max_parents = atoi(arg+14);
+ } else if (!prefixcmp(arg, "--no-max-parents")) {
+ revs->max_parents = -1;
} else if (!strcmp(arg, "--boundary")) {
revs->boundary = 1;
} else if (!strcmp(arg, "--left-right")) {
@@ -1301,7 +1310,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
die("--cherry is incompatible with --left-only");
revs->cherry_mark = 1;
revs->right_only = 1;
- revs->no_merges = 1;
+ revs->max_parents = 1;
revs->limited = 1;
} else if (!strcmp(arg, "--count")) {
revs->count = 1;
@@ -2032,10 +2041,15 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
return commit_ignore;
if (revs->min_age != -1 && (commit->date > revs->min_age))
return commit_ignore;
- if (revs->no_merges && commit->parents && commit->parents->next)
- return commit_ignore;
- if (revs->merges_only && !(commit->parents && commit->parents->next))
- return commit_ignore;
+ if (revs->min_parents || (revs->max_parents >= 0)) {
+ int n = 0;
+ struct commit_list *p;
+ for (p = commit->parents; p; p = p->next)
+ n++;
+ if ((n < revs->min_parents) ||
+ ((revs->max_parents >= 0) && (n > revs->max_parents)))
+ return commit_ignore;
+ }
if (!commit_match(commit, revs))
return commit_ignore;
if (revs->prune && revs->dense) {