зеркало из https://github.com/microsoft/git.git
Merge branch 'bk/ancestry-path' into maint
* 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
This commit is contained in:
Коммит
a151c28c72
53
revision.c
53
revision.c
|
@ -729,12 +729,16 @@ static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *li
|
||||||
* 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 struct commit_list *collect_bottom_commits(struct rev_info *revs)
|
||||||
{
|
{
|
||||||
struct commit_list *elem, *bottom = NULL;
|
struct commit_list *bottom = NULL;
|
||||||
for (elem = list; elem; elem = elem->next)
|
int i;
|
||||||
if (elem->item->object.flags & UNINTERESTING)
|
for (i = 0; i < revs->cmdline.nr; i++) {
|
||||||
commit_list_insert(elem->item, &bottom);
|
struct rev_cmdline_entry *elem = &revs->cmdline.rev[i];
|
||||||
|
if ((elem->flags & UNINTERESTING) &&
|
||||||
|
elem->item->type == OBJ_COMMIT)
|
||||||
|
commit_list_insert((struct commit *)elem->item, &bottom);
|
||||||
|
}
|
||||||
return bottom;
|
return bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,7 +769,7 @@ static int limit_list(struct rev_info *revs)
|
||||||
struct commit_list *bottom = NULL;
|
struct commit_list *bottom = NULL;
|
||||||
|
|
||||||
if (revs->ancestry_path) {
|
if (revs->ancestry_path) {
|
||||||
bottom = collect_bottom_commits(list);
|
bottom = collect_bottom_commits(revs);
|
||||||
if (!bottom)
|
if (!bottom)
|
||||||
die("--ancestry-path given but there are no bottom commits");
|
die("--ancestry-path given but there are no bottom commits");
|
||||||
}
|
}
|
||||||
|
@ -822,6 +826,23 @@ static int limit_list(struct rev_info *revs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_rev_cmdline(struct rev_info *revs,
|
||||||
|
struct object *item,
|
||||||
|
const char *name,
|
||||||
|
int whence,
|
||||||
|
unsigned flags)
|
||||||
|
{
|
||||||
|
struct rev_cmdline_info *info = &revs->cmdline;
|
||||||
|
int nr = info->nr;
|
||||||
|
|
||||||
|
ALLOC_GROW(info->rev, nr + 1, info->alloc);
|
||||||
|
info->rev[nr].item = item;
|
||||||
|
info->rev[nr].name = name;
|
||||||
|
info->rev[nr].whence = whence;
|
||||||
|
info->rev[nr].flags = flags;
|
||||||
|
info->nr++;
|
||||||
|
}
|
||||||
|
|
||||||
struct all_refs_cb {
|
struct all_refs_cb {
|
||||||
int all_flags;
|
int all_flags;
|
||||||
int warned_bad_reflog;
|
int warned_bad_reflog;
|
||||||
|
@ -834,6 +855,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
|
||||||
struct all_refs_cb *cb = cb_data;
|
struct all_refs_cb *cb = cb_data;
|
||||||
struct object *object = get_reference(cb->all_revs, path, sha1,
|
struct object *object = get_reference(cb->all_revs, path, sha1,
|
||||||
cb->all_flags);
|
cb->all_flags);
|
||||||
|
add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
|
||||||
add_pending_object(cb->all_revs, object, path);
|
add_pending_object(cb->all_revs, object, path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -860,6 +882,7 @@ static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
|
||||||
struct object *o = parse_object(sha1);
|
struct object *o = parse_object(sha1);
|
||||||
if (o) {
|
if (o) {
|
||||||
o->flags |= cb->all_flags;
|
o->flags |= cb->all_flags;
|
||||||
|
/* ??? CMDLINEFLAGS ??? */
|
||||||
add_pending_object(cb->all_revs, o, "");
|
add_pending_object(cb->all_revs, o, "");
|
||||||
}
|
}
|
||||||
else if (!cb->warned_bad_reflog) {
|
else if (!cb->warned_bad_reflog) {
|
||||||
|
@ -896,12 +919,13 @@ static void handle_reflog(struct rev_info *revs, unsigned flags)
|
||||||
for_each_reflog(handle_one_reflog, &cb);
|
for_each_reflog(handle_one_reflog, &cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
|
static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
|
||||||
{
|
{
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
struct object *it;
|
struct object *it;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
struct commit_list *parents;
|
struct commit_list *parents;
|
||||||
|
const char *arg = arg_;
|
||||||
|
|
||||||
if (*arg == '^') {
|
if (*arg == '^') {
|
||||||
flags ^= UNINTERESTING;
|
flags ^= UNINTERESTING;
|
||||||
|
@ -925,6 +949,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
|
||||||
for (parents = commit->parents; parents; parents = parents->next) {
|
for (parents = commit->parents; parents; parents = parents->next) {
|
||||||
it = &parents->item->object;
|
it = &parents->item->object;
|
||||||
it->flags |= flags;
|
it->flags |= flags;
|
||||||
|
add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags);
|
||||||
add_pending_object(revs, it, arg);
|
add_pending_object(revs, it, arg);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1018,7 +1043,7 @@ static void prepare_show_merge(struct rev_info *revs)
|
||||||
revs->limited = 1;
|
revs->limited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_revision_arg(const char *arg, struct rev_info *revs,
|
int handle_revision_arg(const char *arg_, struct rev_info *revs,
|
||||||
int flags,
|
int flags,
|
||||||
int cant_be_filename)
|
int cant_be_filename)
|
||||||
{
|
{
|
||||||
|
@ -1027,6 +1052,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
|
||||||
struct object *object;
|
struct object *object;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
int local_flags;
|
int local_flags;
|
||||||
|
const char *arg = arg_;
|
||||||
|
|
||||||
dotdot = strstr(arg, "..");
|
dotdot = strstr(arg, "..");
|
||||||
if (dotdot) {
|
if (dotdot) {
|
||||||
|
@ -1035,6 +1061,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
|
||||||
const char *this = arg;
|
const char *this = arg;
|
||||||
int symmetric = *next == '.';
|
int symmetric = *next == '.';
|
||||||
unsigned int flags_exclude = flags ^ UNINTERESTING;
|
unsigned int flags_exclude = flags ^ UNINTERESTING;
|
||||||
|
unsigned int a_flags;
|
||||||
|
|
||||||
*dotdot = 0;
|
*dotdot = 0;
|
||||||
next += symmetric;
|
next += symmetric;
|
||||||
|
@ -1069,10 +1096,15 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
|
||||||
add_pending_commit_list(revs, exclude,
|
add_pending_commit_list(revs, exclude,
|
||||||
flags_exclude);
|
flags_exclude);
|
||||||
free_commit_list(exclude);
|
free_commit_list(exclude);
|
||||||
a->object.flags |= flags | SYMMETRIC_LEFT;
|
a_flags = flags | SYMMETRIC_LEFT;
|
||||||
} else
|
} else
|
||||||
a->object.flags |= flags_exclude;
|
a_flags = flags_exclude;
|
||||||
|
a->object.flags |= a_flags;
|
||||||
b->object.flags |= flags;
|
b->object.flags |= flags;
|
||||||
|
add_rev_cmdline(revs, &a->object, this,
|
||||||
|
REV_CMD_LEFT, a_flags);
|
||||||
|
add_rev_cmdline(revs, &b->object, next,
|
||||||
|
REV_CMD_RIGHT, flags);
|
||||||
add_pending_object(revs, &a->object, this);
|
add_pending_object(revs, &a->object, this);
|
||||||
add_pending_object(revs, &b->object, next);
|
add_pending_object(revs, &b->object, next);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1103,6 +1135,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
|
||||||
if (!cant_be_filename)
|
if (!cant_be_filename)
|
||||||
verify_non_filename(revs->prefix, arg);
|
verify_non_filename(revs->prefix, arg);
|
||||||
object = get_reference(revs, arg, sha1, flags ^ local_flags);
|
object = get_reference(revs, arg, sha1, flags ^ local_flags);
|
||||||
|
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
|
||||||
add_pending_object_with_mode(revs, object, arg, mode);
|
add_pending_object_with_mode(revs, object, arg, mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
20
revision.h
20
revision.h
|
@ -24,6 +24,23 @@ struct rev_info;
|
||||||
struct log_info;
|
struct log_info;
|
||||||
struct string_list;
|
struct string_list;
|
||||||
|
|
||||||
|
struct rev_cmdline_info {
|
||||||
|
unsigned int nr;
|
||||||
|
unsigned int alloc;
|
||||||
|
struct rev_cmdline_entry {
|
||||||
|
struct object *item;
|
||||||
|
const char *name;
|
||||||
|
enum {
|
||||||
|
REV_CMD_REF,
|
||||||
|
REV_CMD_PARENTS_ONLY,
|
||||||
|
REV_CMD_LEFT,
|
||||||
|
REV_CMD_RIGHT,
|
||||||
|
REV_CMD_REV
|
||||||
|
} whence;
|
||||||
|
unsigned flags;
|
||||||
|
} *rev;
|
||||||
|
};
|
||||||
|
|
||||||
struct rev_info {
|
struct rev_info {
|
||||||
/* Starting list */
|
/* Starting list */
|
||||||
struct commit_list *commits;
|
struct commit_list *commits;
|
||||||
|
@ -32,6 +49,9 @@ struct rev_info {
|
||||||
/* Parents of shown commits */
|
/* Parents of shown commits */
|
||||||
struct object_array boundary_commits;
|
struct object_array boundary_commits;
|
||||||
|
|
||||||
|
/* The end-points specified by the end user */
|
||||||
|
struct rev_cmdline_info cmdline;
|
||||||
|
|
||||||
/* Basic information */
|
/* Basic information */
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
const char *def;
|
const char *def;
|
||||||
|
|
|
@ -70,4 +70,42 @@ test_expect_success 'rev-list --ancestry-patch D..M -- M.t' '
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# b---bc
|
||||||
|
# / \ /
|
||||||
|
# a X
|
||||||
|
# \ / \
|
||||||
|
# c---cb
|
||||||
|
#
|
||||||
|
# All refnames prefixed with 'x' to avoid confusion with the tags
|
||||||
|
# generated by test_commit on case-insensitive systems.
|
||||||
|
test_expect_success 'setup criss-cross' '
|
||||||
|
mkdir criss-cross &&
|
||||||
|
(cd criss-cross &&
|
||||||
|
git init &&
|
||||||
|
test_commit A &&
|
||||||
|
git checkout -b xb master &&
|
||||||
|
test_commit B &&
|
||||||
|
git checkout -b xc master &&
|
||||||
|
test_commit C &&
|
||||||
|
git checkout -b xbc xb -- &&
|
||||||
|
git merge xc &&
|
||||||
|
git checkout -b xcb xc -- &&
|
||||||
|
git merge xb &&
|
||||||
|
git checkout master)
|
||||||
|
'
|
||||||
|
|
||||||
|
# no commits in bc descend from cb
|
||||||
|
test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' '
|
||||||
|
(cd criss-cross &&
|
||||||
|
git rev-list --ancestry-path xcb..xbc > actual &&
|
||||||
|
test -z "$(cat actual)")
|
||||||
|
'
|
||||||
|
|
||||||
|
# no commits in repository descend from cb
|
||||||
|
test_expect_success 'criss-cross: rev-list --ancestry-path --all ^cb' '
|
||||||
|
(cd criss-cross &&
|
||||||
|
git rev-list --ancestry-path --all ^xcb > actual &&
|
||||||
|
test -z "$(cat actual)")
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Загрузка…
Ссылка в новой задаче