Merge branch 'mg/rev-list-n-parents'
* mg/rev-list-n-parents: tests: avoid nonportable {foo,bar} glob rev-list --min-parents,--max-parents: doc, test and completion revision.c: introduce --min-parents and --max-parents options t6009: use test_commit() from test-lib.sh
This commit is contained in:
commit
bf0c5bbe25
@ -16,6 +16,10 @@ SYNOPSIS
|
||||
[ \--sparse ]
|
||||
[ \--merges ]
|
||||
[ \--no-merges ]
|
||||
[ \--min-parents=<number> ]
|
||||
[ \--no-min-parents ]
|
||||
[ \--max-parents=<number> ]
|
||||
[ \--no-max-parents ]
|
||||
[ \--first-parent ]
|
||||
[ \--remove-empty ]
|
||||
[ \--full-history ]
|
||||
|
@ -72,11 +72,26 @@ endif::git-rev-list[]
|
||||
|
||||
--merges::
|
||||
|
||||
Print only merge commits.
|
||||
Print only merge commits. This is exactly the same as `--min-parents=2`.
|
||||
|
||||
--no-merges::
|
||||
|
||||
Do not print commits with more than one parent.
|
||||
Do not print commits with more than one parent. This is
|
||||
exactly the same as `--max-parents=1`.
|
||||
|
||||
--min-parents=<number>::
|
||||
--max-parents=<number>::
|
||||
--no-min-parents::
|
||||
--no-max-parents::
|
||||
|
||||
Show only commits which have at least (or at most) that many
|
||||
commits. In particular, `--max-parents=1` is the same as `--no-merges`,
|
||||
`--min-parents=2` is the same as `--merges`. `--max-parents=0`
|
||||
gives all root commits and `--min-parents=3` all octopus merges.
|
||||
+
|
||||
`--no-min-parents` and `--no-max-parents` reset these limits (to no limit)
|
||||
again. Equivalent forms are `--min-parents=0` (any commit has 0 or more
|
||||
parents) and `--max-parents=-1` (negative numbers denote no upper limit).
|
||||
|
||||
--first-parent::
|
||||
Follow only the first parent commit upon seeing a merge
|
||||
|
@ -1061,7 +1061,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));
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -1577,6 +1577,8 @@ __git_log_common_options="
|
||||
--max-count=
|
||||
--max-age= --since= --after=
|
||||
--min-age= --until= --before=
|
||||
--min-parents= --max-parents=
|
||||
--no-min-parents --no-max-parents
|
||||
"
|
||||
# Options that go well for log and gitk (not shortlog)
|
||||
__git_log_gitk_options="
|
||||
|
28
revision.c
28
revision.c
@ -941,6 +941,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;
|
||||
|
||||
@ -1277,9 +1278,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")) {
|
||||
@ -1298,7 +1307,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;
|
||||
@ -2029,10 +2038,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) {
|
||||
|
@ -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 {
|
||||
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;
|
||||
|
@ -1,14 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='properly cull all ancestors'
|
||||
test_description='ancestor culling and limiting by parent number'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
commit () {
|
||||
test_tick &&
|
||||
echo $1 >file &&
|
||||
git commit -a -m $1 &&
|
||||
git tag $1
|
||||
check_revlist () {
|
||||
rev_list_args="$1" &&
|
||||
shift &&
|
||||
git rev-parse "$@" >expect &&
|
||||
git rev-list $rev_list_args --all >actual &&
|
||||
test_cmp expect actual
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
@ -16,13 +17,13 @@ test_expect_success setup '
|
||||
touch file &&
|
||||
git add file &&
|
||||
|
||||
commit one &&
|
||||
test_commit one &&
|
||||
|
||||
test_tick=$(($test_tick - 2400)) &&
|
||||
|
||||
commit two &&
|
||||
commit three &&
|
||||
commit four &&
|
||||
test_commit two &&
|
||||
test_commit three &&
|
||||
test_commit four &&
|
||||
|
||||
git log --pretty=oneline --abbrev-commit
|
||||
'
|
||||
@ -35,4 +36,101 @@ test_expect_success 'one is ancestor of others and should not be shown' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'setup roots, merges and octopuses' '
|
||||
|
||||
git checkout --orphan newroot &&
|
||||
test_commit five &&
|
||||
git checkout -b sidebranch two &&
|
||||
test_commit six &&
|
||||
git checkout -b anotherbranch three &&
|
||||
test_commit seven &&
|
||||
git checkout -b yetanotherbranch four &&
|
||||
test_commit eight &&
|
||||
git checkout master &&
|
||||
test_merge normalmerge newroot &&
|
||||
test_tick &&
|
||||
git merge -m tripus sidebranch anotherbranch &&
|
||||
git tag tripus &&
|
||||
git checkout -b tetrabranch normalmerge &&
|
||||
test_tick &&
|
||||
git merge -m tetrapus sidebranch anotherbranch yetanotherbranch &&
|
||||
git tag tetrapus &&
|
||||
git checkout master
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list roots' '
|
||||
|
||||
check_revlist "--max-parents=0" one five
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list no merges' '
|
||||
|
||||
check_revlist "--max-parents=1" one eight seven six five four three two &&
|
||||
check_revlist "--no-merges" one eight seven six five four three two
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list no octopuses' '
|
||||
|
||||
check_revlist "--max-parents=2" one normalmerge eight seven six five four three two
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list no roots' '
|
||||
|
||||
check_revlist "--min-parents=1" tetrapus tripus normalmerge eight seven six four three two
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list merges' '
|
||||
|
||||
check_revlist "--min-parents=2" tetrapus tripus normalmerge &&
|
||||
check_revlist "--merges" tetrapus tripus normalmerge
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list octopus' '
|
||||
|
||||
check_revlist "--min-parents=3" tetrapus tripus
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list ordinary commits' '
|
||||
|
||||
check_revlist "--min-parents=1 --max-parents=1" eight seven six four three two
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list --merges --no-merges yields empty set' '
|
||||
|
||||
check_revlist "--min-parents=2 --no-merges" &&
|
||||
check_revlist "--merges --no-merges" &&
|
||||
check_revlist "--no-merges --merges"
|
||||
'
|
||||
|
||||
test_expect_success 'rev-list override and infinities' '
|
||||
|
||||
check_revlist "--min-parents=2 --max-parents=1 --max-parents=3" tripus normalmerge &&
|
||||
check_revlist "--min-parents=1 --min-parents=2 --max-parents=7" tetrapus tripus normalmerge &&
|
||||
check_revlist "--min-parents=2 --max-parents=8" tetrapus tripus normalmerge &&
|
||||
check_revlist "--min-parents=2 --max-parents=-1" tetrapus tripus normalmerge &&
|
||||
check_revlist "--min-parents=2 --no-max-parents" tetrapus tripus normalmerge &&
|
||||
check_revlist "--max-parents=0 --min-parents=1 --no-min-parents" one five
|
||||
'
|
||||
|
||||
test_expect_success 'dodecapus' '
|
||||
|
||||
roots= &&
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 11
|
||||
do
|
||||
git checkout -b root$i five &&
|
||||
test_commit $i &&
|
||||
roots="$roots root$i" ||
|
||||
return
|
||||
done &&
|
||||
git checkout master &&
|
||||
test_tick &&
|
||||
git merge -m dodecapus $roots &&
|
||||
git tag dodecapus &&
|
||||
|
||||
check_revlist "--min-parents=4" dodecapus tetrapus &&
|
||||
check_revlist "--min-parents=8" dodecapus &&
|
||||
check_revlist "--min-parents=12" dodecapus &&
|
||||
check_revlist "--min-parents=13" &&
|
||||
check_revlist "--min-parents=4 --max-parents=11" tetrapus
|
||||
'
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user