mirror of
https://github.com/git/git.git
synced 2025-03-15 21:31:12 +00:00
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 ]
|
[ \--sparse ]
|
||||||
[ \--merges ]
|
[ \--merges ]
|
||||||
[ \--no-merges ]
|
[ \--no-merges ]
|
||||||
|
[ \--min-parents=<number> ]
|
||||||
|
[ \--no-min-parents ]
|
||||||
|
[ \--max-parents=<number> ]
|
||||||
|
[ \--no-max-parents ]
|
||||||
[ \--first-parent ]
|
[ \--first-parent ]
|
||||||
[ \--remove-empty ]
|
[ \--remove-empty ]
|
||||||
[ \--full-history ]
|
[ \--full-history ]
|
||||||
|
@ -72,11 +72,26 @@ endif::git-rev-list[]
|
|||||||
|
|
||||||
--merges::
|
--merges::
|
||||||
|
|
||||||
Print only merge commits.
|
Print only merge commits. This is exactly the same as `--min-parents=2`.
|
||||||
|
|
||||||
--no-merges::
|
--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::
|
--first-parent::
|
||||||
Follow only the first parent commit upon seeing a merge
|
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.commit_format = CMIT_FMT_EMAIL;
|
||||||
rev.verbose_header = 1;
|
rev.verbose_header = 1;
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
rev.no_merges = 1;
|
rev.max_parents = 1;
|
||||||
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
|
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
|
||||||
rev.subject_prefix = fmt_patch_subject_prefix;
|
rev.subject_prefix = fmt_patch_subject_prefix;
|
||||||
memset(&s_r_opt, 0, sizeof(s_r_opt));
|
memset(&s_r_opt, 0, sizeof(s_r_opt));
|
||||||
|
@ -16,6 +16,10 @@ static const char rev_list_usage[] =
|
|||||||
" --min-age=<epoch>\n"
|
" --min-age=<epoch>\n"
|
||||||
" --sparse\n"
|
" --sparse\n"
|
||||||
" --no-merges\n"
|
" --no-merges\n"
|
||||||
|
" --min-parents=<n>\n"
|
||||||
|
" --no-min-parents\n"
|
||||||
|
" --max-parents=<n>\n"
|
||||||
|
" --no-max-parents\n"
|
||||||
" --remove-empty\n"
|
" --remove-empty\n"
|
||||||
" --all\n"
|
" --all\n"
|
||||||
" --branches\n"
|
" --branches\n"
|
||||||
|
@ -48,6 +48,10 @@ static int is_rev_argument(const char *arg)
|
|||||||
"--max-count=",
|
"--max-count=",
|
||||||
"--min-age=",
|
"--min-age=",
|
||||||
"--no-merges",
|
"--no-merges",
|
||||||
|
"--min-parents=",
|
||||||
|
"--no-min-parents",
|
||||||
|
"--max-parents=",
|
||||||
|
"--no-max-parents",
|
||||||
"--objects",
|
"--objects",
|
||||||
"--objects-edge",
|
"--objects-edge",
|
||||||
"--parents",
|
"--parents",
|
||||||
|
@ -1577,6 +1577,8 @@ __git_log_common_options="
|
|||||||
--max-count=
|
--max-count=
|
||||||
--max-age= --since= --after=
|
--max-age= --since= --after=
|
||||||
--min-age= --until= --before=
|
--min-age= --until= --before=
|
||||||
|
--min-parents= --max-parents=
|
||||||
|
--no-min-parents --no-max-parents
|
||||||
"
|
"
|
||||||
# Options that go well for log and gitk (not shortlog)
|
# Options that go well for log and gitk (not shortlog)
|
||||||
__git_log_gitk_options="
|
__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->min_age = -1;
|
||||||
revs->skip_count = -1;
|
revs->skip_count = -1;
|
||||||
revs->max_count = -1;
|
revs->max_count = -1;
|
||||||
|
revs->max_parents = -1;
|
||||||
|
|
||||||
revs->commit_format = CMIT_FMT_DEFAULT;
|
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")) {
|
} else if (!strcmp(arg, "--remove-empty")) {
|
||||||
revs->remove_empty_trees = 1;
|
revs->remove_empty_trees = 1;
|
||||||
} else if (!strcmp(arg, "--merges")) {
|
} else if (!strcmp(arg, "--merges")) {
|
||||||
revs->merges_only = 1;
|
revs->min_parents = 2;
|
||||||
} else if (!strcmp(arg, "--no-merges")) {
|
} 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")) {
|
} else if (!strcmp(arg, "--boundary")) {
|
||||||
revs->boundary = 1;
|
revs->boundary = 1;
|
||||||
} else if (!strcmp(arg, "--left-right")) {
|
} 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");
|
die("--cherry is incompatible with --left-only");
|
||||||
revs->cherry_mark = 1;
|
revs->cherry_mark = 1;
|
||||||
revs->right_only = 1;
|
revs->right_only = 1;
|
||||||
revs->no_merges = 1;
|
revs->max_parents = 1;
|
||||||
revs->limited = 1;
|
revs->limited = 1;
|
||||||
} else if (!strcmp(arg, "--count")) {
|
} else if (!strcmp(arg, "--count")) {
|
||||||
revs->count = 1;
|
revs->count = 1;
|
||||||
@ -2029,10 +2038,15 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
|
|||||||
return commit_ignore;
|
return commit_ignore;
|
||||||
if (revs->min_age != -1 && (commit->date > revs->min_age))
|
if (revs->min_age != -1 && (commit->date > revs->min_age))
|
||||||
return commit_ignore;
|
return commit_ignore;
|
||||||
if (revs->no_merges && commit->parents && commit->parents->next)
|
if (revs->min_parents || (revs->max_parents >= 0)) {
|
||||||
return commit_ignore;
|
int n = 0;
|
||||||
if (revs->merges_only && !(commit->parents && commit->parents->next))
|
struct commit_list *p;
|
||||||
return commit_ignore;
|
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))
|
if (!commit_match(commit, revs))
|
||||||
return commit_ignore;
|
return commit_ignore;
|
||||||
if (revs->prune && revs->dense) {
|
if (revs->prune && revs->dense) {
|
||||||
|
@ -41,8 +41,6 @@ struct rev_info {
|
|||||||
/* Traversal flags */
|
/* Traversal flags */
|
||||||
unsigned int dense:1,
|
unsigned int dense:1,
|
||||||
prune:1,
|
prune:1,
|
||||||
no_merges:1,
|
|
||||||
merges_only:1,
|
|
||||||
no_walk:1,
|
no_walk:1,
|
||||||
show_all:1,
|
show_all:1,
|
||||||
remove_empty_trees:1,
|
remove_empty_trees:1,
|
||||||
@ -126,6 +124,8 @@ struct rev_info {
|
|||||||
int max_count;
|
int max_count;
|
||||||
unsigned long max_age;
|
unsigned long max_age;
|
||||||
unsigned long min_age;
|
unsigned long min_age;
|
||||||
|
int min_parents;
|
||||||
|
int max_parents;
|
||||||
|
|
||||||
/* diff info for patches and for paths limiting */
|
/* diff info for patches and for paths limiting */
|
||||||
struct diff_options diffopt;
|
struct diff_options diffopt;
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
test_description='properly cull all ancestors'
|
test_description='ancestor culling and limiting by parent number'
|
||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
commit () {
|
check_revlist () {
|
||||||
test_tick &&
|
rev_list_args="$1" &&
|
||||||
echo $1 >file &&
|
shift &&
|
||||||
git commit -a -m $1 &&
|
git rev-parse "$@" >expect &&
|
||||||
git tag $1
|
git rev-list $rev_list_args --all >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
}
|
}
|
||||||
|
|
||||||
test_expect_success setup '
|
test_expect_success setup '
|
||||||
@ -16,13 +17,13 @@ test_expect_success setup '
|
|||||||
touch file &&
|
touch file &&
|
||||||
git add file &&
|
git add file &&
|
||||||
|
|
||||||
commit one &&
|
test_commit one &&
|
||||||
|
|
||||||
test_tick=$(($test_tick - 2400)) &&
|
test_tick=$(($test_tick - 2400)) &&
|
||||||
|
|
||||||
commit two &&
|
test_commit two &&
|
||||||
commit three &&
|
test_commit three &&
|
||||||
commit four &&
|
test_commit four &&
|
||||||
|
|
||||||
git log --pretty=oneline --abbrev-commit
|
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
|
test_done
|
||||||
|
Loading…
x
Reference in New Issue
Block a user