Skip to content

Commit 3bcad5a

Browse files
committed
Merge branch 'bk/ancestry-path' into jc/branch-desc
* bk/ancestry-path: t6019: avoid refname collision on case-insensitive systems revision: do not include sibling history in --ancestry-path output revision: keep track of the end-user input from the command line rev-list: Demonstrate breakage with --ancestry-path --all
2 parents 5ec8217 + c05b988 commit 3bcad5a

File tree

3 files changed

+101
-10
lines changed

3 files changed

+101
-10
lines changed

revision.c

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -729,12 +729,16 @@ static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *li
729729
* to filter the result of "A..B" further to the ones that can actually
730730
* reach A.
731731
*/
732-
static struct commit_list *collect_bottom_commits(struct commit_list *list)
732+
static struct commit_list *collect_bottom_commits(struct rev_info *revs)
733733
{
734-
struct commit_list *elem, *bottom = NULL;
735-
for (elem = list; elem; elem = elem->next)
736-
if (elem->item->object.flags & UNINTERESTING)
737-
commit_list_insert(elem->item, &bottom);
734+
struct commit_list *bottom = NULL;
735+
int i;
736+
for (i = 0; i < revs->cmdline.nr; i++) {
737+
struct rev_cmdline_entry *elem = &revs->cmdline.rev[i];
738+
if ((elem->flags & UNINTERESTING) &&
739+
elem->item->type == OBJ_COMMIT)
740+
commit_list_insert((struct commit *)elem->item, &bottom);
741+
}
738742
return bottom;
739743
}
740744

@@ -765,7 +769,7 @@ static int limit_list(struct rev_info *revs)
765769
struct commit_list *bottom = NULL;
766770

767771
if (revs->ancestry_path) {
768-
bottom = collect_bottom_commits(list);
772+
bottom = collect_bottom_commits(revs);
769773
if (!bottom)
770774
die("--ancestry-path given but there are no bottom commits");
771775
}
@@ -822,6 +826,23 @@ static int limit_list(struct rev_info *revs)
822826
return 0;
823827
}
824828

829+
static void add_rev_cmdline(struct rev_info *revs,
830+
struct object *item,
831+
const char *name,
832+
int whence,
833+
unsigned flags)
834+
{
835+
struct rev_cmdline_info *info = &revs->cmdline;
836+
int nr = info->nr;
837+
838+
ALLOC_GROW(info->rev, nr + 1, info->alloc);
839+
info->rev[nr].item = item;
840+
info->rev[nr].name = name;
841+
info->rev[nr].whence = whence;
842+
info->rev[nr].flags = flags;
843+
info->nr++;
844+
}
845+
825846
struct all_refs_cb {
826847
int all_flags;
827848
int warned_bad_reflog;
@@ -834,6 +855,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
834855
struct all_refs_cb *cb = cb_data;
835856
struct object *object = get_reference(cb->all_revs, path, sha1,
836857
cb->all_flags);
858+
add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
837859
add_pending_object(cb->all_revs, object, path);
838860
return 0;
839861
}
@@ -860,6 +882,7 @@ static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
860882
struct object *o = parse_object(sha1);
861883
if (o) {
862884
o->flags |= cb->all_flags;
885+
/* ??? CMDLINEFLAGS ??? */
863886
add_pending_object(cb->all_revs, o, "");
864887
}
865888
else if (!cb->warned_bad_reflog) {
@@ -896,12 +919,13 @@ static void handle_reflog(struct rev_info *revs, unsigned flags)
896919
for_each_reflog(handle_one_reflog, &cb);
897920
}
898921

899-
static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
922+
static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
900923
{
901924
unsigned char sha1[20];
902925
struct object *it;
903926
struct commit *commit;
904927
struct commit_list *parents;
928+
const char *arg = arg_;
905929

906930
if (*arg == '^') {
907931
flags ^= UNINTERESTING;
@@ -925,6 +949,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
925949
for (parents = commit->parents; parents; parents = parents->next) {
926950
it = &parents->item->object;
927951
it->flags |= flags;
952+
add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags);
928953
add_pending_object(revs, it, arg);
929954
}
930955
return 1;
@@ -1018,7 +1043,7 @@ static void prepare_show_merge(struct rev_info *revs)
10181043
revs->limited = 1;
10191044
}
10201045

1021-
int handle_revision_arg(const char *arg, struct rev_info *revs,
1046+
int handle_revision_arg(const char *arg_, struct rev_info *revs,
10221047
int flags,
10231048
int cant_be_filename)
10241049
{
@@ -1027,6 +1052,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
10271052
struct object *object;
10281053
unsigned char sha1[20];
10291054
int local_flags;
1055+
const char *arg = arg_;
10301056

10311057
dotdot = strstr(arg, "..");
10321058
if (dotdot) {
@@ -1035,6 +1061,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
10351061
const char *this = arg;
10361062
int symmetric = *next == '.';
10371063
unsigned int flags_exclude = flags ^ UNINTERESTING;
1064+
unsigned int a_flags;
10381065

10391066
*dotdot = 0;
10401067
next += symmetric;
@@ -1069,10 +1096,15 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
10691096
add_pending_commit_list(revs, exclude,
10701097
flags_exclude);
10711098
free_commit_list(exclude);
1072-
a->object.flags |= flags | SYMMETRIC_LEFT;
1099+
a_flags = flags | SYMMETRIC_LEFT;
10731100
} else
1074-
a->object.flags |= flags_exclude;
1101+
a_flags = flags_exclude;
1102+
a->object.flags |= a_flags;
10751103
b->object.flags |= flags;
1104+
add_rev_cmdline(revs, &a->object, this,
1105+
REV_CMD_LEFT, a_flags);
1106+
add_rev_cmdline(revs, &b->object, next,
1107+
REV_CMD_RIGHT, flags);
10761108
add_pending_object(revs, &a->object, this);
10771109
add_pending_object(revs, &b->object, next);
10781110
return 0;
@@ -1103,6 +1135,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
11031135
if (!cant_be_filename)
11041136
verify_non_filename(revs->prefix, arg);
11051137
object = get_reference(revs, arg, sha1, flags ^ local_flags);
1138+
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
11061139
add_pending_object_with_mode(revs, object, arg, mode);
11071140
return 0;
11081141
}

revision.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@ struct rev_info;
2424
struct log_info;
2525
struct string_list;
2626

27+
struct rev_cmdline_info {
28+
unsigned int nr;
29+
unsigned int alloc;
30+
struct rev_cmdline_entry {
31+
struct object *item;
32+
const char *name;
33+
enum {
34+
REV_CMD_REF,
35+
REV_CMD_PARENTS_ONLY,
36+
REV_CMD_LEFT,
37+
REV_CMD_RIGHT,
38+
REV_CMD_REV
39+
} whence;
40+
unsigned flags;
41+
} *rev;
42+
};
43+
2744
struct rev_info {
2845
/* Starting list */
2946
struct commit_list *commits;
@@ -32,6 +49,9 @@ struct rev_info {
3249
/* Parents of shown commits */
3350
struct object_array boundary_commits;
3451

52+
/* The end-points specified by the end user */
53+
struct rev_cmdline_info cmdline;
54+
3555
/* Basic information */
3656
const char *prefix;
3757
const char *def;

t/t6019-rev-list-ancestry-path.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,42 @@ test_expect_success 'rev-list --ancestry-patch D..M -- M.t' '
7070
test_cmp expect actual
7171
'
7272

73+
# b---bc
74+
# / \ /
75+
# a X
76+
# \ / \
77+
# c---cb
78+
#
79+
# All refnames prefixed with 'x' to avoid confusion with the tags
80+
# generated by test_commit on case-insensitive systems.
81+
test_expect_success 'setup criss-cross' '
82+
mkdir criss-cross &&
83+
(cd criss-cross &&
84+
git init &&
85+
test_commit A &&
86+
git checkout -b xb master &&
87+
test_commit B &&
88+
git checkout -b xc master &&
89+
test_commit C &&
90+
git checkout -b xbc xb -- &&
91+
git merge xc &&
92+
git checkout -b xcb xc -- &&
93+
git merge xb &&
94+
git checkout master)
95+
'
96+
97+
# no commits in bc descend from cb
98+
test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' '
99+
(cd criss-cross &&
100+
git rev-list --ancestry-path xcb..xbc > actual &&
101+
test -z "$(cat actual)")
102+
'
103+
104+
# no commits in repository descend from cb
105+
test_expect_success 'criss-cross: rev-list --ancestry-path --all ^cb' '
106+
(cd criss-cross &&
107+
git rev-list --ancestry-path --all ^xcb > actual &&
108+
test -z "$(cat actual)")
109+
'
110+
73111
test_done

0 commit comments

Comments
 (0)