Browse Source

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>
maint
Michael J Gruber 14 years ago committed by Junio C Hamano
parent
commit
ad5aeeded3
  1. 2
      builtin/log.c
  2. 4
      builtin/rev-list.c
  3. 4
      builtin/rev-parse.c
  4. 28
      revision.c
  5. 4
      revision.h

2
builtin/log.c

@ -1055,7 +1055,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) @@ -1055,7 +1055,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.commit_format = CMIT_FMT_EMAIL;
rev.verbose_header = 1;
rev.diff = 1;
rev.no_merges = 1;
rev.max_parents = 1;
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
rev.subject_prefix = fmt_patch_subject_prefix;
memset(&s_r_opt, 0, sizeof(s_r_opt));

4
builtin/rev-list.c

@ -16,6 +16,10 @@ static const char rev_list_usage[] = @@ -16,6 +16,10 @@ static const char rev_list_usage[] =
" --min-age=<epoch>\n"
" --sparse\n"
" --no-merges\n"
" --min-parents=<n>\n"
" --no-min-parents\n"
" --max-parents=<n>\n"
" --no-max-parents\n"
" --remove-empty\n"
" --all\n"
" --branches\n"

4
builtin/rev-parse.c

@ -48,6 +48,10 @@ static int is_rev_argument(const char *arg) @@ -48,6 +48,10 @@ static int is_rev_argument(const char *arg)
"--max-count=",
"--min-age=",
"--no-merges",
"--min-parents=",
"--no-min-parents",
"--max-parents=",
"--no-max-parents",
"--objects",
"--objects-edge",
"--parents",

28
revision.c

@ -945,6 +945,7 @@ void init_revisions(struct rev_info *revs, const char *prefix) @@ -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 @@ -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 @@ -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 @@ -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) {

4
revision.h

@ -41,8 +41,6 @@ struct rev_info { @@ -41,8 +41,6 @@ struct rev_info {
/* Traversal flags */
unsigned int dense:1,
prune:1,
no_merges:1,
merges_only:1,
no_walk:1,
show_all:1,
remove_empty_trees:1,
@ -126,6 +124,8 @@ struct rev_info { @@ -126,6 +124,8 @@ struct rev_info {
int max_count;
unsigned long max_age;
unsigned long min_age;
int min_parents;
int max_parents;

/* diff info for patches and for paths limiting */
struct diff_options diffopt;

Loading…
Cancel
Save