Skip to content

Commit 7745f92

Browse files
committed
Merge branch 'js/merge-base-with-missing-commit'
Make sure failure return from merge_bases_many() is properly caught. * js/merge-base-with-missing-commit: merge-ort/merge-recursive: do report errors in `merge_submodule()` merge-recursive: prepare for `merge_submodule()` to report errors commit-reach(repo_get_merge_bases_many_dirty): pass on errors commit-reach(repo_get_merge_bases_many): pass on "missing commits" errors commit-reach(get_octopus_merge_bases): pass on "missing commits" errors commit-reach(repo_get_merge_bases): pass on "missing commits" errors commit-reach(get_merge_bases_many_0): pass on "missing commits" errors commit-reach(merge_bases_many): pass on "missing commits" errors commit-reach(paint_down_to_common): start reporting errors commit-reach(paint_down_to_common): prepare for handling shallow commits commit-reach(repo_in_merge_bases_many): report missing commits commit-reach(repo_in_merge_bases_many): optionally expect missing commits commit-reach(paint_down_to_common): plug two memory leaks
2 parents e09f125 + 25fd20e commit 7745f92

29 files changed

+460
-188
lines changed

bisect.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,11 @@ static void handle_skipped_merge_base(const struct object_id *mb)
836836
static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int no_checkout)
837837
{
838838
enum bisect_error res = BISECT_OK;
839-
struct commit_list *result;
839+
struct commit_list *result = NULL;
840840

841-
result = repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,
842-
rev + 1);
841+
if (repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,
842+
rev + 1, &result) < 0)
843+
exit(128);
843844

844845
for (; result; result = result->next) {
845846
const struct object_id *mb = &result->item->object.oid;

builtin/branch.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ static int branch_merged(int kind, const char *name,
158158

159159
merged = reference_rev ? repo_in_merge_bases(the_repository, rev,
160160
reference_rev) : 0;
161+
if (merged < 0)
162+
exit(128);
161163

162164
/*
163165
* After the safety valve is fully redefined to "check with
@@ -166,9 +168,13 @@ static int branch_merged(int kind, const char *name,
166168
* any of the following code, but during the transition period,
167169
* a gentle reminder is in order.
168170
*/
169-
if ((head_rev != reference_rev) &&
170-
(head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0) != merged) {
171-
if (merged)
171+
if (head_rev != reference_rev) {
172+
int expect = head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0;
173+
if (expect < 0)
174+
exit(128);
175+
if (expect == merged)
176+
; /* okay */
177+
else if (merged)
172178
warning(_("deleting branch '%s' that has been merged to\n"
173179
" '%s', but not yet merged to HEAD"),
174180
name, reference_name);

builtin/fast-import.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,7 @@ static int update_branch(struct branch *b)
16251625
oidclr(&old_oid);
16261626
if (!force_update && !is_null_oid(&old_oid)) {
16271627
struct commit *old_cmit, *new_cmit;
1628+
int ret;
16281629

16291630
old_cmit = lookup_commit_reference_gently(the_repository,
16301631
&old_oid, 0);
@@ -1633,7 +1634,10 @@ static int update_branch(struct branch *b)
16331634
if (!old_cmit || !new_cmit)
16341635
return error("Branch %s is missing commits.", b->name);
16351636

1636-
if (!repo_in_merge_bases(the_repository, old_cmit, new_cmit)) {
1637+
ret = repo_in_merge_bases(the_repository, old_cmit, new_cmit);
1638+
if (ret < 0)
1639+
exit(128);
1640+
if (!ret) {
16371641
warning("Not updating %s"
16381642
" (new tip %s does not contain %s)",
16391643
b->name, oid_to_hex(&b->oid),

builtin/fetch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,8 @@ static int update_local_ref(struct ref *ref,
981981
uint64_t t_before = getnanotime();
982982
fast_forward = repo_in_merge_bases(the_repository, current,
983983
updated);
984+
if (fast_forward < 0)
985+
exit(128);
984986
forced_updates_ms += (getnanotime() - t_before) / 1000000;
985987
} else {
986988
fast_forward = 1;

builtin/log.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ static struct commit *get_base_commit(const char *base_commit,
16251625
{
16261626
struct commit *base = NULL;
16271627
struct commit **rev;
1628-
int i = 0, rev_nr = 0, auto_select, die_on_failure;
1628+
int i = 0, rev_nr = 0, auto_select, die_on_failure, ret;
16291629

16301630
switch (auto_base) {
16311631
case AUTO_BASE_NEVER:
@@ -1658,7 +1658,7 @@ static struct commit *get_base_commit(const char *base_commit,
16581658
struct branch *curr_branch = branch_get(NULL);
16591659
const char *upstream = branch_get_upstream(curr_branch, NULL);
16601660
if (upstream) {
1661-
struct commit_list *base_list;
1661+
struct commit_list *base_list = NULL;
16621662
struct commit *commit;
16631663
struct object_id oid;
16641664

@@ -1669,11 +1669,12 @@ static struct commit *get_base_commit(const char *base_commit,
16691669
return NULL;
16701670
}
16711671
commit = lookup_commit_or_die(&oid, "upstream base");
1672-
base_list = repo_get_merge_bases_many(the_repository,
1673-
commit, total,
1674-
list);
1675-
/* There should be one and only one merge base. */
1676-
if (!base_list || base_list->next) {
1672+
if (repo_get_merge_bases_many(the_repository,
1673+
commit, total,
1674+
list,
1675+
&base_list) < 0 ||
1676+
/* There should be one and only one merge base. */
1677+
!base_list || base_list->next) {
16771678
if (die_on_failure) {
16781679
die(_("could not find exact merge base"));
16791680
} else {
@@ -1704,11 +1705,11 @@ static struct commit *get_base_commit(const char *base_commit,
17041705
*/
17051706
while (rev_nr > 1) {
17061707
for (i = 0; i < rev_nr / 2; i++) {
1707-
struct commit_list *merge_base;
1708-
merge_base = repo_get_merge_bases(the_repository,
1709-
rev[2 * i],
1710-
rev[2 * i + 1]);
1711-
if (!merge_base || merge_base->next) {
1708+
struct commit_list *merge_base = NULL;
1709+
if (repo_get_merge_bases(the_repository,
1710+
rev[2 * i],
1711+
rev[2 * i + 1], &merge_base) < 0 ||
1712+
!merge_base || merge_base->next) {
17121713
if (die_on_failure) {
17131714
die(_("failed to find exact merge base"));
17141715
} else {
@@ -1725,7 +1726,10 @@ static struct commit *get_base_commit(const char *base_commit,
17251726
rev_nr = DIV_ROUND_UP(rev_nr, 2);
17261727
}
17271728

1728-
if (!repo_in_merge_bases(the_repository, base, rev[0])) {
1729+
ret = repo_in_merge_bases(the_repository, base, rev[0]);
1730+
if (ret < 0)
1731+
exit(128);
1732+
if (!ret) {
17291733
if (die_on_failure) {
17301734
die(_("base commit should be the ancestor of revision list"));
17311735
} else {

builtin/merge-base.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010

1111
static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
1212
{
13-
struct commit_list *result, *r;
13+
struct commit_list *result = NULL, *r;
1414

15-
result = repo_get_merge_bases_many_dirty(the_repository, rev[0],
16-
rev_nr - 1, rev + 1);
15+
if (repo_get_merge_bases_many_dirty(the_repository, rev[0],
16+
rev_nr - 1, rev + 1, &result) < 0) {
17+
free_commit_list(result);
18+
return -1;
19+
}
1720

1821
if (!result)
1922
return 1;
@@ -74,13 +77,17 @@ static int handle_independent(int count, const char **args)
7477
static int handle_octopus(int count, const char **args, int show_all)
7578
{
7679
struct commit_list *revs = NULL;
77-
struct commit_list *result, *rev;
80+
struct commit_list *result = NULL, *rev;
7881
int i;
7982

8083
for (i = count - 1; i >= 0; i--)
8184
commit_list_insert(get_commit_reference(args[i]), &revs);
8285

83-
result = get_octopus_merge_bases(revs);
86+
if (get_octopus_merge_bases(revs, &result) < 0) {
87+
free_commit_list(revs);
88+
free_commit_list(result);
89+
return 128;
90+
}
8491
free_commit_list(revs);
8592
reduce_heads_replace(&result);
8693

@@ -100,12 +107,16 @@ static int handle_octopus(int count, const char **args, int show_all)
100107
static int handle_is_ancestor(int argc, const char **argv)
101108
{
102109
struct commit *one, *two;
110+
int ret;
103111

104112
if (argc != 2)
105113
die("--is-ancestor takes exactly two commits");
106114
one = get_commit_reference(argv[0]);
107115
two = get_commit_reference(argv[1]);
108-
if (repo_in_merge_bases(the_repository, one, two))
116+
ret = repo_in_merge_bases(the_repository, one, two);
117+
if (ret < 0)
118+
exit(128);
119+
if (ret)
109120
return 0;
110121
else
111122
return 1;

builtin/merge-tree.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,9 @@ static int real_merge(struct merge_tree_options *o,
476476
* Get the merge bases, in reverse order; see comment above
477477
* merge_incore_recursive in merge-ort.h
478478
*/
479-
merge_bases = repo_get_merge_bases(the_repository, parent1,
480-
parent2);
479+
if (repo_get_merge_bases(the_repository, parent1,
480+
parent2, &merge_bases) < 0)
481+
exit(128);
481482
if (!merge_bases && !o->allow_unrelated_histories)
482483
die(_("refusing to merge unrelated histories"));
483484
merge_bases = reverse_commit_list(merge_bases);

builtin/merge.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,13 +1513,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
15131513

15141514
if (!remoteheads)
15151515
; /* already up-to-date */
1516-
else if (!remoteheads->next)
1517-
common = repo_get_merge_bases(the_repository, head_commit,
1518-
remoteheads->item);
1519-
else {
1516+
else if (!remoteheads->next) {
1517+
if (repo_get_merge_bases(the_repository, head_commit,
1518+
remoteheads->item, &common) < 0) {
1519+
ret = 2;
1520+
goto done;
1521+
}
1522+
} else {
15201523
struct commit_list *list = remoteheads;
15211524
commit_list_insert(head_commit, &list);
1522-
common = get_octopus_merge_bases(list);
1525+
if (get_octopus_merge_bases(list, &common) < 0) {
1526+
free(list);
1527+
ret = 2;
1528+
goto done;
1529+
}
15231530
free(list);
15241531
}
15251532

@@ -1626,17 +1633,18 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
16261633
struct commit_list *j;
16271634

16281635
for (j = remoteheads; j; j = j->next) {
1629-
struct commit_list *common_one;
1636+
struct commit_list *common_one = NULL;
16301637
struct commit *common_item;
16311638

16321639
/*
16331640
* Here we *have* to calculate the individual
16341641
* merge_bases again, otherwise "git merge HEAD^
16351642
* HEAD^^" would be missed.
16361643
*/
1637-
common_one = repo_get_merge_bases(the_repository,
1638-
head_commit,
1639-
j->item);
1644+
if (repo_get_merge_bases(the_repository, head_commit,
1645+
j->item, &common_one) < 0)
1646+
exit(128);
1647+
16401648
common_item = common_one->item;
16411649
free_commit_list(common_one);
16421650
if (!oideq(&common_item->object.oid, &j->item->object.oid)) {

builtin/pull.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ static int get_octopus_merge_base(struct object_id *merge_base,
815815
const struct object_id *merge_head,
816816
const struct object_id *fork_point)
817817
{
818-
struct commit_list *revs = NULL, *result;
818+
struct commit_list *revs = NULL, *result = NULL;
819819

820820
commit_list_insert(lookup_commit_reference(the_repository, curr_head),
821821
&revs);
@@ -825,7 +825,8 @@ static int get_octopus_merge_base(struct object_id *merge_base,
825825
commit_list_insert(lookup_commit_reference(the_repository, fork_point),
826826
&revs);
827827

828-
result = get_octopus_merge_bases(revs);
828+
if (get_octopus_merge_bases(revs, &result) < 0)
829+
exit(128);
829830
free_commit_list(revs);
830831
reduce_heads_replace(&result);
831832

@@ -926,6 +927,8 @@ static int get_can_ff(struct object_id *orig_head,
926927
merge_head = lookup_commit_reference(the_repository, orig_merge_head);
927928
ret = repo_is_descendant_of(the_repository, merge_head, list);
928929
free_commit_list(list);
930+
if (ret < 0)
931+
exit(128);
929932
return ret;
930933
}
931934

@@ -950,6 +953,8 @@ static int already_up_to_date(struct object_id *orig_head,
950953
commit_list_insert(theirs, &list);
951954
ok = repo_is_descendant_of(the_repository, ours, list);
952955
free_commit_list(list);
956+
if (ok < 0)
957+
exit(128);
953958
if (!ok)
954959
return 0;
955960
}

builtin/rebase.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,8 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
867867
if (!upstream)
868868
goto done;
869869

870-
merge_bases = repo_get_merge_bases(the_repository, upstream, head);
870+
if (repo_get_merge_bases(the_repository, upstream, head, &merge_bases) < 0)
871+
exit(128);
871872
if (!merge_bases || merge_bases->next)
872873
goto done;
873874

@@ -886,8 +887,9 @@ static void fill_branch_base(struct rebase_options *options,
886887
{
887888
struct commit_list *merge_bases = NULL;
888889

889-
merge_bases = repo_get_merge_bases(the_repository, options->onto,
890-
options->orig_head);
890+
if (repo_get_merge_bases(the_repository, options->onto,
891+
options->orig_head, &merge_bases) < 0)
892+
exit(128);
891893
if (!merge_bases || merge_bases->next)
892894
oidcpy(branch_base, null_oid());
893895
else

0 commit comments

Comments
 (0)