The get_merge_bases*() API was easy to misuse by careless
copy&paste coders, leaving object flags tainted in the commits that
needed to be traversed.

* jc/merge-bases:
  get_merge_bases(): always clean-up object flags
  bisect: clean flags after checking merge bases
This commit is contained in:
Junio C Hamano 2015-01-07 12:55:05 -08:00
Родитель 58e0362edd 2ce406ccb8
Коммит 098501527f
11 изменённых файлов: 38 добавлений и 22 удалений

Просмотреть файл

@ -777,7 +777,7 @@ static void check_merge_bases(int no_checkout)
int rev_nr; int rev_nr;
struct commit **rev = get_bad_and_good_commits(&rev_nr); struct commit **rev = get_bad_and_good_commits(&rev_nr);
result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1, 0); result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1);
for (; result; result = result->next) { for (; result; result = result->next) {
const unsigned char *mb = result->item->object.sha1; const unsigned char *mb = result->item->object.sha1;

Просмотреть файл

@ -10,7 +10,7 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
{ {
struct commit_list *result; struct commit_list *result;
result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1, 0); result = get_merge_bases_many_dirty(rev[0], rev_nr - 1, rev + 1);
if (!result) if (!result)
return 1; return 1;
@ -176,7 +176,7 @@ static int handle_fork_point(int argc, const char **argv)
for (i = 0; i < revs.nr; i++) for (i = 0; i < revs.nr; i++)
revs.commit[i]->object.flags &= ~TMP_MARK; revs.commit[i]->object.flags &= ~TMP_MARK;
bases = get_merge_bases_many(derived, revs.nr, revs.commit, 0); bases = get_merge_bases_many_dirty(derived, revs.nr, revs.commit);
/* /*
* There should be one and only one merge base, when we found * There should be one and only one merge base, when we found

Просмотреть файл

@ -1312,7 +1312,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (!remoteheads) if (!remoteheads)
; /* already up-to-date */ ; /* already up-to-date */
else if (!remoteheads->next) else if (!remoteheads->next)
common = get_merge_bases(head_commit, remoteheads->item, 1); common = get_merge_bases(head_commit, remoteheads->item);
else { else {
struct commit_list *list = remoteheads; struct commit_list *list = remoteheads;
commit_list_insert(head_commit, &list); commit_list_insert(head_commit, &list);
@ -1409,7 +1409,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* merge_bases again, otherwise "git merge HEAD^ * merge_bases again, otherwise "git merge HEAD^
* HEAD^^" would be missed. * HEAD^^" would be missed.
*/ */
common_one = get_merge_bases(head_commit, j->item, 1); common_one = get_merge_bases(head_commit, j->item);
if (hashcmp(common_one->item->object.sha1, if (hashcmp(common_one->item->object.sha1,
j->item->object.sha1)) { j->item->object.sha1)) {
up_to_date = 0; up_to_date = 0;

Просмотреть файл

@ -279,7 +279,7 @@ static int try_difference(const char *arg)
struct commit *a, *b; struct commit *a, *b;
a = lookup_commit_reference(sha1); a = lookup_commit_reference(sha1);
b = lookup_commit_reference(end); b = lookup_commit_reference(end);
exclude = get_merge_bases(a, b, 1); exclude = get_merge_bases(a, b);
while (exclude) { while (exclude) {
struct commit_list *n = exclude->next; struct commit_list *n = exclude->next;
show_rev(REVERSED, show_rev(REVERSED,

Просмотреть файл

@ -867,7 +867,7 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
for (j = ret; j; j = j->next) { for (j = ret; j; j = j->next) {
struct commit_list *bases; struct commit_list *bases;
bases = get_merge_bases(i->item, j->item, 1); bases = get_merge_bases(i->item, j->item);
if (!new) if (!new)
new = bases; new = bases;
else else
@ -936,10 +936,10 @@ static int remove_redundant(struct commit **array, int cnt)
return filled; return filled;
} }
struct commit_list *get_merge_bases_many(struct commit *one, static struct commit_list *get_merge_bases_many_0(struct commit *one,
int n, int n,
struct commit **twos, struct commit **twos,
int cleanup) int cleanup)
{ {
struct commit_list *list; struct commit_list *list;
struct commit **rslt; struct commit **rslt;
@ -977,10 +977,23 @@ struct commit_list *get_merge_bases_many(struct commit *one,
return result; return result;
} }
struct commit_list *get_merge_bases(struct commit *one, struct commit *two, struct commit_list *get_merge_bases_many(struct commit *one,
int cleanup) int n,
struct commit **twos)
{ {
return get_merge_bases_many(one, 1, &two, cleanup); return get_merge_bases_many_0(one, n, twos, 1);
}
struct commit_list *get_merge_bases_many_dirty(struct commit *one,
int n,
struct commit **twos)
{
return get_merge_bases_many_0(one, n, twos, 0);
}
struct commit_list *get_merge_bases(struct commit *one, struct commit *two)
{
return get_merge_bases_many_0(one, 1, &two, 1);
} }
/* /*

Просмотреть файл

@ -236,10 +236,13 @@ struct commit_graft *read_graft_line(char *buf, int len);
int register_commit_graft(struct commit_graft *, int); int register_commit_graft(struct commit_graft *, int);
struct commit_graft *lookup_commit_graft(const unsigned char *sha1); struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup); extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2);
extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup); extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos);
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in); extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
/* To be used only when object flags after this call no longer matter */
extern struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
/* largest positive number a signed 32-bit integer can contain */ /* largest positive number a signed 32-bit integer can contain */
#define INFINITE_DEPTH 0x7fffffff #define INFINITE_DEPTH 0x7fffffff

Просмотреть файл

@ -1901,7 +1901,7 @@ int merge_recursive(struct merge_options *o,
} }
if (!ca) { if (!ca) {
ca = get_merge_bases(h1, h2, 1); ca = get_merge_bases(h1, h2);
ca = reverse_commit_list(ca); ca = reverse_commit_list(ca);
} }

Просмотреть файл

@ -594,7 +594,7 @@ int notes_merge(struct notes_merge_options *o,
assert(local && remote); assert(local && remote);
/* Find merge bases */ /* Find merge bases */
bases = get_merge_bases(local, remote, 1); bases = get_merge_bases(local, remote);
if (!bases) { if (!bases) {
base_sha1 = null_sha1; base_sha1 = null_sha1;
base_tree_sha1 = EMPTY_TREE_SHA1_BIN; base_tree_sha1 = EMPTY_TREE_SHA1_BIN;

Просмотреть файл

@ -1441,7 +1441,7 @@ static void prepare_show_merge(struct rev_info *revs)
other = lookup_commit_or_die(sha1, "MERGE_HEAD"); other = lookup_commit_or_die(sha1, "MERGE_HEAD");
add_pending_object(revs, &head->object, "HEAD"); add_pending_object(revs, &head->object, "HEAD");
add_pending_object(revs, &other->object, "MERGE_HEAD"); add_pending_object(revs, &other->object, "MERGE_HEAD");
bases = get_merge_bases(head, other, 1); bases = get_merge_bases(head, other);
add_rev_cmdline_list(revs, bases, REV_CMD_MERGE_BASE, UNINTERESTING | BOTTOM); add_rev_cmdline_list(revs, bases, REV_CMD_MERGE_BASE, UNINTERESTING | BOTTOM);
add_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM); add_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM);
free_commit_list(bases); free_commit_list(bases);
@ -1546,7 +1546,7 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
: lookup_commit_reference(b_obj->sha1)); : lookup_commit_reference(b_obj->sha1));
if (!a || !b) if (!a || !b)
goto missing; goto missing;
exclude = get_merge_bases(a, b, 1); exclude = get_merge_bases(a, b);
add_rev_cmdline_list(revs, exclude, add_rev_cmdline_list(revs, exclude,
REV_CMD_MERGE_BASE, REV_CMD_MERGE_BASE,
flags_exclude); flags_exclude);

Просмотреть файл

@ -993,7 +993,7 @@ int get_sha1_mb(const char *name, unsigned char *sha1)
two = lookup_commit_reference_gently(sha1_tmp, 0); two = lookup_commit_reference_gently(sha1_tmp, 0);
if (!two) if (!two)
return -1; return -1;
mbs = get_merge_bases(one, two, 1); mbs = get_merge_bases(one, two);
if (!mbs || mbs->next) if (!mbs || mbs->next)
st = -1; st = -1;
else { else {

Просмотреть файл

@ -301,7 +301,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
left->object.flags |= SYMMETRIC_LEFT; left->object.flags |= SYMMETRIC_LEFT;
add_pending_object(rev, &left->object, path); add_pending_object(rev, &left->object, path);
add_pending_object(rev, &right->object, path); add_pending_object(rev, &right->object, path);
merge_bases = get_merge_bases(left, right, 1); merge_bases = get_merge_bases(left, right);
if (merge_bases) { if (merge_bases) {
if (merge_bases->item == left) if (merge_bases->item == left)
*fast_forward = 1; *fast_forward = 1;