Merge branch 'en/ancestry-path-in-a-range'
"git rev-list --ancestry-path=C A..B" is a natural extension of "git rev-list A..B"; instead of choosing a subset of A..B to those that have ancestry relationship with A, it lets a subset with ancestry relationship with C. * en/ancestry-path-in-a-range: revision: allow --ancestry-path to take an argument t6019: modernize tests with helper rev-list-options.txt: fix simple typo
This commit is contained in:
commit
0b08ba7eb6
@ -392,12 +392,14 @@ Default mode::
|
|||||||
merges from the resulting history, as there are no selected
|
merges from the resulting history, as there are no selected
|
||||||
commits contributing to this merge.
|
commits contributing to this merge.
|
||||||
|
|
||||||
--ancestry-path::
|
--ancestry-path[=<commit>]::
|
||||||
When given a range of commits to display (e.g. 'commit1..commit2'
|
When given a range of commits to display (e.g. 'commit1..commit2'
|
||||||
or 'commit2 {caret}commit1'), only display commits that exist
|
or 'commit2 {caret}commit1'), only display commits in that range
|
||||||
directly on the ancestry chain between the 'commit1' and
|
that are ancestors of <commit>, descendants of <commit>, or
|
||||||
'commit2', i.e. commits that are both descendants of 'commit1',
|
<commit> itself. If no commit is specified, use 'commit1' (the
|
||||||
and ancestors of 'commit2'.
|
excluded part of the range) as <commit>. Can be passed multiple
|
||||||
|
times; if so, a commit is included if it is any of the commits
|
||||||
|
given or if it is an ancestor or descendant of one of them.
|
||||||
|
|
||||||
A more detailed explanation follows.
|
A more detailed explanation follows.
|
||||||
|
|
||||||
@ -571,11 +573,10 @@ Note the major differences in `N`, `P`, and `Q` over `--full-history`:
|
|||||||
|
|
||||||
There is another simplification mode available:
|
There is another simplification mode available:
|
||||||
|
|
||||||
--ancestry-path::
|
--ancestry-path[=<commit>]::
|
||||||
Limit the displayed commits to those directly on the ancestry
|
Limit the displayed commits to those which are an ancestor of
|
||||||
chain between the ``from'' and ``to'' commits in the given commit
|
<commit>, or which are a descendant of <commit>, or are <commit>
|
||||||
range. I.e. only display commits that are ancestor of the ``to''
|
itself.
|
||||||
commit and descendants of the ``from'' commit.
|
|
||||||
+
|
+
|
||||||
As an example use case, consider the following commit history:
|
As an example use case, consider the following commit history:
|
||||||
+
|
+
|
||||||
@ -607,6 +608,29 @@ option does. Applied to the 'D..M' range, it results in:
|
|||||||
\
|
\
|
||||||
L--M
|
L--M
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
+
|
||||||
|
We can also use `--ancestry-path=D` instead of `--ancestry-path` which
|
||||||
|
means the same thing when applied to the 'D..M' range but is just more
|
||||||
|
explicit.
|
||||||
|
+
|
||||||
|
If we instead are interested in a given topic within this range, and all
|
||||||
|
commits affected by that topic, we may only want to view the subset of
|
||||||
|
`D..M` which contain that topic in their ancestry path. So, using
|
||||||
|
`--ancestry-path=H D..M` for example would result in:
|
||||||
|
+
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
E
|
||||||
|
\
|
||||||
|
G---H---I---J
|
||||||
|
\
|
||||||
|
L--M
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
+
|
||||||
|
Whereas `--ancestry-path=K D..M` would result in
|
||||||
|
+
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
K---------------L--M
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
Before discussing another option, `--show-pulls`, we need to
|
Before discussing another option, `--show-pulls`, we need to
|
||||||
create a new example history.
|
create a new example history.
|
||||||
@ -662,7 +686,7 @@ Here, the merge commits `O` and `P` contribute extra noise, as they did
|
|||||||
not actually contribute a change to `file.txt`. They only merged a topic
|
not actually contribute a change to `file.txt`. They only merged a topic
|
||||||
that was based on an older version of `file.txt`. This is a common
|
that was based on an older version of `file.txt`. This is a common
|
||||||
issue in repositories using a workflow where many contributors work in
|
issue in repositories using a workflow where many contributors work in
|
||||||
parallel and merge their topic branches along a single trunk: manu
|
parallel and merge their topic branches along a single trunk: many
|
||||||
unrelated merges appear in the `--full-history` results.
|
unrelated merges appear in the `--full-history` results.
|
||||||
|
|
||||||
When using the `--simplify-merges` option, the commits `O` and `P`
|
When using the `--simplify-merges` option, the commits `O` and `P`
|
||||||
|
2
object.h
2
object.h
@ -59,7 +59,7 @@ struct object_array {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* object flag allocation:
|
* object flag allocation:
|
||||||
* revision.h: 0---------10 15 23------26
|
* revision.h: 0---------10 15 23------27
|
||||||
* fetch-pack.c: 01 67
|
* fetch-pack.c: 01 67
|
||||||
* negotiator/default.c: 2--5
|
* negotiator/default.c: 2--5
|
||||||
* walker.c: 0-2
|
* walker.c: 0-2
|
||||||
|
89
revision.c
89
revision.c
@ -1105,7 +1105,7 @@ static int process_parents(struct rev_info *revs, struct commit *commit,
|
|||||||
struct commit_list **list, struct prio_queue *queue)
|
struct commit_list **list, struct prio_queue *queue)
|
||||||
{
|
{
|
||||||
struct commit_list *parent = commit->parents;
|
struct commit_list *parent = commit->parents;
|
||||||
unsigned left_flag;
|
unsigned pass_flags;
|
||||||
|
|
||||||
if (commit->object.flags & ADDED)
|
if (commit->object.flags & ADDED)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1160,7 +1160,7 @@ static int process_parents(struct rev_info *revs, struct commit *commit,
|
|||||||
if (revs->no_walk)
|
if (revs->no_walk)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
left_flag = (commit->object.flags & SYMMETRIC_LEFT);
|
pass_flags = (commit->object.flags & (SYMMETRIC_LEFT | ANCESTRY_PATH));
|
||||||
|
|
||||||
for (parent = commit->parents; parent; parent = parent->next) {
|
for (parent = commit->parents; parent; parent = parent->next) {
|
||||||
struct commit *p = parent->item;
|
struct commit *p = parent->item;
|
||||||
@ -1181,7 +1181,7 @@ static int process_parents(struct rev_info *revs, struct commit *commit,
|
|||||||
if (!*slot)
|
if (!*slot)
|
||||||
*slot = *revision_sources_at(revs->sources, commit);
|
*slot = *revision_sources_at(revs->sources, commit);
|
||||||
}
|
}
|
||||||
p->object.flags |= left_flag;
|
p->object.flags |= pass_flags;
|
||||||
if (!(p->object.flags & SEEN)) {
|
if (!(p->object.flags & SEEN)) {
|
||||||
p->object.flags |= (SEEN | NOT_USER_GIVEN);
|
p->object.flags |= (SEEN | NOT_USER_GIVEN);
|
||||||
if (list)
|
if (list)
|
||||||
@ -1304,13 +1304,24 @@ static int still_interesting(struct commit_list *src, timestamp_t date, int slop
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "rev-list --ancestry-path A..B" computes commits that are ancestors
|
* "rev-list --ancestry-path=C_0 [--ancestry-path=C_1 ...] A..B"
|
||||||
* of B but not ancestors of A but further limits the result to those
|
* computes commits that are ancestors of B but not ancestors of A but
|
||||||
* that are descendants of A. This takes the list of bottom commits and
|
* further limits the result to those that have any of C in their
|
||||||
* the result of "A..B" without --ancestry-path, and limits the latter
|
* ancestry path (i.e. are either ancestors of any of C, descendants
|
||||||
* further to the ones that can reach one of the commits in "bottom".
|
* of any of C, or are any of C). If --ancestry-path is specified with
|
||||||
|
* no commit, we use all bottom commits for C.
|
||||||
|
*
|
||||||
|
* Before this function is called, ancestors of C will have already
|
||||||
|
* been marked with ANCESTRY_PATH previously.
|
||||||
|
*
|
||||||
|
* This takes the list of bottom commits and the result of "A..B"
|
||||||
|
* without --ancestry-path, and limits the latter further to the ones
|
||||||
|
* that have any of C in their ancestry path. Since the ancestors of C
|
||||||
|
* have already been marked (a prerequisite of this function), we just
|
||||||
|
* need to mark the descendants, then exclude any commit that does not
|
||||||
|
* have any of these marks.
|
||||||
*/
|
*/
|
||||||
static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *list)
|
static void limit_to_ancestry(struct commit_list *bottoms, struct commit_list *list)
|
||||||
{
|
{
|
||||||
struct commit_list *p;
|
struct commit_list *p;
|
||||||
struct commit_list *rlist = NULL;
|
struct commit_list *rlist = NULL;
|
||||||
@ -1323,7 +1334,7 @@ static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *li
|
|||||||
for (p = list; p; p = p->next)
|
for (p = list; p; p = p->next)
|
||||||
commit_list_insert(p->item, &rlist);
|
commit_list_insert(p->item, &rlist);
|
||||||
|
|
||||||
for (p = bottom; p; p = p->next)
|
for (p = bottoms; p; p = p->next)
|
||||||
p->item->object.flags |= TMP_MARK;
|
p->item->object.flags |= TMP_MARK;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1356,38 +1367,39 @@ static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *li
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ones that are not marked with TMP_MARK are uninteresting
|
* The ones that are not marked with either TMP_MARK or
|
||||||
|
* ANCESTRY_PATH are uninteresting
|
||||||
*/
|
*/
|
||||||
for (p = list; p; p = p->next) {
|
for (p = list; p; p = p->next) {
|
||||||
struct commit *c = p->item;
|
struct commit *c = p->item;
|
||||||
if (c->object.flags & TMP_MARK)
|
if (c->object.flags & (TMP_MARK | ANCESTRY_PATH))
|
||||||
continue;
|
continue;
|
||||||
c->object.flags |= UNINTERESTING;
|
c->object.flags |= UNINTERESTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are done with the TMP_MARK */
|
/* We are done with TMP_MARK and ANCESTRY_PATH */
|
||||||
for (p = list; p; p = p->next)
|
for (p = list; p; p = p->next)
|
||||||
p->item->object.flags &= ~TMP_MARK;
|
p->item->object.flags &= ~(TMP_MARK | ANCESTRY_PATH);
|
||||||
for (p = bottom; p; p = p->next)
|
for (p = bottoms; p; p = p->next)
|
||||||
p->item->object.flags &= ~TMP_MARK;
|
p->item->object.flags &= ~(TMP_MARK | ANCESTRY_PATH);
|
||||||
free_commit_list(rlist);
|
free_commit_list(rlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before walking the history, keep the set of "negative" refs the
|
* Before walking the history, add the set of "negative" refs the
|
||||||
* caller has asked to exclude.
|
* caller has asked to exclude to the bottom list.
|
||||||
*
|
*
|
||||||
* This is used to compute "rev-list --ancestry-path A..B", as we need
|
* This is used to compute "rev-list --ancestry-path A..B", as we need
|
||||||
* to filter the result of "A..B" further to the ones that can actually
|
* to filter the result of "A..B" further to the ones that can actually
|
||||||
* reach A.
|
* reach A.
|
||||||
*/
|
*/
|
||||||
static struct commit_list *collect_bottom_commits(struct commit_list *list)
|
static void collect_bottom_commits(struct commit_list *list,
|
||||||
|
struct commit_list **bottom)
|
||||||
{
|
{
|
||||||
struct commit_list *elem, *bottom = NULL;
|
struct commit_list *elem;
|
||||||
for (elem = list; elem; elem = elem->next)
|
for (elem = list; elem; elem = elem->next)
|
||||||
if (elem->item->object.flags & BOTTOM)
|
if (elem->item->object.flags & BOTTOM)
|
||||||
commit_list_insert(elem->item, &bottom);
|
commit_list_insert(elem->item, bottom);
|
||||||
return bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes either left_only or right_only is set */
|
/* Assumes either left_only or right_only is set */
|
||||||
@ -1414,12 +1426,12 @@ static int limit_list(struct rev_info *revs)
|
|||||||
struct commit_list *original_list = revs->commits;
|
struct commit_list *original_list = revs->commits;
|
||||||
struct commit_list *newlist = NULL;
|
struct commit_list *newlist = NULL;
|
||||||
struct commit_list **p = &newlist;
|
struct commit_list **p = &newlist;
|
||||||
struct commit_list *bottom = NULL;
|
|
||||||
struct commit *interesting_cache = NULL;
|
struct commit *interesting_cache = NULL;
|
||||||
|
|
||||||
if (revs->ancestry_path) {
|
if (revs->ancestry_path_implicit_bottoms) {
|
||||||
bottom = collect_bottom_commits(original_list);
|
collect_bottom_commits(original_list,
|
||||||
if (!bottom)
|
&revs->ancestry_path_bottoms);
|
||||||
|
if (!revs->ancestry_path_bottoms)
|
||||||
die("--ancestry-path given but there are no bottom commits");
|
die("--ancestry-path given but there are no bottom commits");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1464,9 +1476,8 @@ static int limit_list(struct rev_info *revs)
|
|||||||
if (revs->left_only || revs->right_only)
|
if (revs->left_only || revs->right_only)
|
||||||
limit_left_right(newlist, revs);
|
limit_left_right(newlist, revs);
|
||||||
|
|
||||||
if (bottom)
|
if (revs->ancestry_path)
|
||||||
limit_to_ancestry(bottom, newlist);
|
limit_to_ancestry(revs->ancestry_path_bottoms, newlist);
|
||||||
free_commit_list(bottom);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if any commits have become TREESAME by some of their parents
|
* Check if any commits have become TREESAME by some of their parents
|
||||||
@ -2213,7 +2224,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
|||||||
const struct setup_revision_opt* opt)
|
const struct setup_revision_opt* opt)
|
||||||
{
|
{
|
||||||
const char *arg = argv[0];
|
const char *arg = argv[0];
|
||||||
const char *optarg;
|
const char *optarg = NULL;
|
||||||
int argcount;
|
int argcount;
|
||||||
const unsigned hexsz = the_hash_algo->hexsz;
|
const unsigned hexsz = the_hash_algo->hexsz;
|
||||||
|
|
||||||
@ -2284,6 +2295,23 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
|||||||
revs->ancestry_path = 1;
|
revs->ancestry_path = 1;
|
||||||
revs->simplify_history = 0;
|
revs->simplify_history = 0;
|
||||||
revs->limited = 1;
|
revs->limited = 1;
|
||||||
|
revs->ancestry_path_implicit_bottoms = 1;
|
||||||
|
} else if (skip_prefix(arg, "--ancestry-path=", &optarg)) {
|
||||||
|
struct commit *c;
|
||||||
|
struct object_id oid;
|
||||||
|
const char *msg = _("could not get commit for ancestry-path argument %s");
|
||||||
|
|
||||||
|
revs->ancestry_path = 1;
|
||||||
|
revs->simplify_history = 0;
|
||||||
|
revs->limited = 1;
|
||||||
|
|
||||||
|
if (repo_get_oid_committish(revs->repo, optarg, &oid))
|
||||||
|
return error(msg, optarg);
|
||||||
|
get_reference(revs, optarg, &oid, ANCESTRY_PATH);
|
||||||
|
c = lookup_commit_reference(revs->repo, &oid);
|
||||||
|
if (!c)
|
||||||
|
return error(msg, optarg);
|
||||||
|
commit_list_insert(c, &revs->ancestry_path_bottoms);
|
||||||
} else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) {
|
} else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) {
|
||||||
init_reflog_walk(&revs->reflog_info);
|
init_reflog_walk(&revs->reflog_info);
|
||||||
} else if (!strcmp(arg, "--default")) {
|
} else if (!strcmp(arg, "--default")) {
|
||||||
@ -2993,6 +3021,7 @@ static void release_revisions_topo_walk_info(struct topo_walk_info *info);
|
|||||||
void release_revisions(struct rev_info *revs)
|
void release_revisions(struct rev_info *revs)
|
||||||
{
|
{
|
||||||
free_commit_list(revs->commits);
|
free_commit_list(revs->commits);
|
||||||
|
free_commit_list(revs->ancestry_path_bottoms);
|
||||||
object_array_clear(&revs->pending);
|
object_array_clear(&revs->pending);
|
||||||
object_array_clear(&revs->boundary_commits);
|
object_array_clear(&revs->boundary_commits);
|
||||||
release_revisions_cmdline(&revs->cmdline);
|
release_revisions_cmdline(&revs->cmdline);
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
*/
|
*/
|
||||||
#define NOT_USER_GIVEN (1u<<25)
|
#define NOT_USER_GIVEN (1u<<25)
|
||||||
#define TRACK_LINEAR (1u<<26)
|
#define TRACK_LINEAR (1u<<26)
|
||||||
|
#define ANCESTRY_PATH (1u<<27)
|
||||||
#define ALL_REV_FLAGS (((1u<<11)-1) | NOT_USER_GIVEN | TRACK_LINEAR | PULL_MERGE)
|
#define ALL_REV_FLAGS (((1u<<11)-1) | NOT_USER_GIVEN | TRACK_LINEAR | PULL_MERGE)
|
||||||
|
|
||||||
#define DECORATE_SHORT_REFS 1
|
#define DECORATE_SHORT_REFS 1
|
||||||
@ -164,6 +165,13 @@ struct rev_info {
|
|||||||
cherry_mark:1,
|
cherry_mark:1,
|
||||||
bisect:1,
|
bisect:1,
|
||||||
ancestry_path:1,
|
ancestry_path:1,
|
||||||
|
|
||||||
|
/* True if --ancestry-path was specified without an
|
||||||
|
* argument. The bottom revisions are implicitly
|
||||||
|
* the arguments in this case.
|
||||||
|
*/
|
||||||
|
ancestry_path_implicit_bottoms:1,
|
||||||
|
|
||||||
first_parent_only:1,
|
first_parent_only:1,
|
||||||
exclude_first_parent_only:1,
|
exclude_first_parent_only:1,
|
||||||
line_level_traverse:1,
|
line_level_traverse:1,
|
||||||
@ -306,6 +314,7 @@ struct rev_info {
|
|||||||
struct saved_parents *saved_parents_slab;
|
struct saved_parents *saved_parents_slab;
|
||||||
|
|
||||||
struct commit_list *previous_parents;
|
struct commit_list *previous_parents;
|
||||||
|
struct commit_list *ancestry_path_bottoms;
|
||||||
const char *break_bar;
|
const char *break_bar;
|
||||||
|
|
||||||
struct revision_sources *sources;
|
struct revision_sources *sources;
|
||||||
|
@ -10,6 +10,11 @@ test_description='--ancestry-path'
|
|||||||
#
|
#
|
||||||
# D..M == E F G H I J K L M
|
# D..M == E F G H I J K L M
|
||||||
# --ancestry-path D..M == E F H I J L M
|
# --ancestry-path D..M == E F H I J L M
|
||||||
|
# --ancestry-path=F D..M == E F J L M
|
||||||
|
# --ancestry-path=G D..M == G H I J L M
|
||||||
|
# --ancestry-path=H D..M == E G H I J L M
|
||||||
|
# --ancestry-path=K D..M == K L M
|
||||||
|
# --ancestry-path=K --ancestry-path=F D..M == E F J K L M
|
||||||
#
|
#
|
||||||
# D..M -- M.t == M
|
# D..M -- M.t == M
|
||||||
# --ancestry-path D..M -- M.t == M
|
# --ancestry-path D..M -- M.t == M
|
||||||
@ -50,73 +55,41 @@ test_expect_success setup '
|
|||||||
test_commit M
|
test_commit M
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rev-list D..M' '
|
test_ancestry () {
|
||||||
test_write_lines E F G H I J K L M >expect &&
|
args=$1
|
||||||
git rev-list --format=%s D..M |
|
expected=$2
|
||||||
sed -e "/^commit /d" |
|
test_expect_success "log $args" "
|
||||||
sort >actual &&
|
test_write_lines $expected >expect &&
|
||||||
test_cmp expect actual
|
git log --format=%s $args >raw &&
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rev-list --ancestry-path D..M' '
|
if test -n \"$expected\"
|
||||||
test_write_lines E F H I J L M >expect &&
|
then
|
||||||
git rev-list --ancestry-path --format=%s D..M |
|
sort raw >actual &&
|
||||||
sed -e "/^commit /d" |
|
|
||||||
sort >actual &&
|
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
else
|
||||||
|
test_must_be_empty raw
|
||||||
|
fi
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
test_expect_success 'rev-list D..M -- M.t' '
|
test_ancestry "D..M" "E F G H I J K L M"
|
||||||
echo M >expect &&
|
|
||||||
git rev-list --format=%s D..M -- M.t |
|
|
||||||
sed -e "/^commit /d" >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rev-list --ancestry-path D..M -- M.t' '
|
test_ancestry "--ancestry-path D..M" "E F H I J L M"
|
||||||
echo M >expect &&
|
test_ancestry "--ancestry-path=F D..M" "E F J L M"
|
||||||
git rev-list --ancestry-path --format=%s D..M -- M.t |
|
test_ancestry "--ancestry-path=G D..M" "G H I J L M"
|
||||||
sed -e "/^commit /d" >actual &&
|
test_ancestry "--ancestry-path=H D..M" "E G H I J L M"
|
||||||
test_cmp expect actual
|
test_ancestry "--ancestry-path=K D..M" "K L M"
|
||||||
'
|
test_ancestry "--ancestry-path=F --ancestry-path=K D..M" "E F J K L M"
|
||||||
|
|
||||||
test_expect_success 'rev-list F...I' '
|
test_ancestry "D..M -- M.t" "M"
|
||||||
test_write_lines F G H I >expect &&
|
test_ancestry "--ancestry-path D..M -- M.t" "M"
|
||||||
git rev-list --format=%s F...I |
|
|
||||||
sed -e "/^commit /d" |
|
|
||||||
sort >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rev-list --ancestry-path F...I' '
|
test_ancestry "F...I" "F G H I"
|
||||||
test_write_lines F H I >expect &&
|
test_ancestry "--ancestry-path F...I" "F H I"
|
||||||
git rev-list --ancestry-path --format=%s F...I |
|
|
||||||
sed -e "/^commit /d" |
|
|
||||||
sort >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
# G.t is dropped in an "-s ours" merge
|
test_ancestry "G..M -- G.t" ""
|
||||||
test_expect_success 'rev-list G..M -- G.t' '
|
test_ancestry "--ancestry-path G..M -- G.t" "L"
|
||||||
git rev-list --format=%s G..M -- G.t |
|
test_ancestry "--ancestry-path --simplify-merges G^..M -- G.t" "G L"
|
||||||
sed -e "/^commit /d" >actual &&
|
|
||||||
test_must_be_empty actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rev-list --ancestry-path G..M -- G.t' '
|
|
||||||
echo L >expect &&
|
|
||||||
git rev-list --ancestry-path --format=%s G..M -- G.t |
|
|
||||||
sed -e "/^commit /d" >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rev-list --ancestry-path --simplify-merges G^..M -- G.t' '
|
|
||||||
test_write_lines G L >expect &&
|
|
||||||
git rev-list --ancestry-path --simplify-merges --format=%s G^..M -- G.t |
|
|
||||||
sed -e "/^commit /d" |
|
|
||||||
sort >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
# b---bc
|
# b---bc
|
||||||
# / \ /
|
# / \ /
|
||||||
|
Loading…
Reference in New Issue
Block a user