commit-reach(repo_get_merge_bases): pass on "missing commits" errors
The `merge_bases_many()` function was just taught to indicate parsing errors, and now the `repo_get_merge_bases()` function (which is also surfaced via the `repo_get_merge_bases()` macro) is aware of that, too. Naturally, there are a lot of callers that need to be adjusted now, too. Next step: adjust the callers of `get_octopus_merge_bases()`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
8226e157a9
commit
76e2a09999
|
@ -1704,11 +1704,11 @@ static struct commit *get_base_commit(const char *base_commit,
|
||||||
*/
|
*/
|
||||||
while (rev_nr > 1) {
|
while (rev_nr > 1) {
|
||||||
for (i = 0; i < rev_nr / 2; i++) {
|
for (i = 0; i < rev_nr / 2; i++) {
|
||||||
struct commit_list *merge_base;
|
struct commit_list *merge_base = NULL;
|
||||||
merge_base = repo_get_merge_bases(the_repository,
|
if (repo_get_merge_bases(the_repository,
|
||||||
rev[2 * i],
|
rev[2 * i],
|
||||||
rev[2 * i + 1]);
|
rev[2 * i + 1], &merge_base) < 0 ||
|
||||||
if (!merge_base || merge_base->next) {
|
!merge_base || merge_base->next) {
|
||||||
if (die_on_failure) {
|
if (die_on_failure) {
|
||||||
die(_("failed to find exact merge base"));
|
die(_("failed to find exact merge base"));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -462,8 +462,9 @@ static int real_merge(struct merge_tree_options *o,
|
||||||
* Get the merge bases, in reverse order; see comment above
|
* Get the merge bases, in reverse order; see comment above
|
||||||
* merge_incore_recursive in merge-ort.h
|
* merge_incore_recursive in merge-ort.h
|
||||||
*/
|
*/
|
||||||
merge_bases = repo_get_merge_bases(the_repository, parent1,
|
if (repo_get_merge_bases(the_repository, parent1,
|
||||||
parent2);
|
parent2, &merge_bases) < 0)
|
||||||
|
exit(128);
|
||||||
if (!merge_bases && !o->allow_unrelated_histories)
|
if (!merge_bases && !o->allow_unrelated_histories)
|
||||||
die(_("refusing to merge unrelated histories"));
|
die(_("refusing to merge unrelated histories"));
|
||||||
merge_bases = reverse_commit_list(merge_bases);
|
merge_bases = reverse_commit_list(merge_bases);
|
||||||
|
|
|
@ -1514,10 +1514,13 @@ 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 = repo_get_merge_bases(the_repository, head_commit,
|
if (repo_get_merge_bases(the_repository, head_commit,
|
||||||
remoteheads->item);
|
remoteheads->item, &common) < 0) {
|
||||||
else {
|
ret = 2;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
struct commit_list *list = remoteheads;
|
struct commit_list *list = remoteheads;
|
||||||
commit_list_insert(head_commit, &list);
|
commit_list_insert(head_commit, &list);
|
||||||
common = get_octopus_merge_bases(list);
|
common = get_octopus_merge_bases(list);
|
||||||
|
@ -1627,7 +1630,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||||
struct commit_list *j;
|
struct commit_list *j;
|
||||||
|
|
||||||
for (j = remoteheads; j; j = j->next) {
|
for (j = remoteheads; j; j = j->next) {
|
||||||
struct commit_list *common_one;
|
struct commit_list *common_one = NULL;
|
||||||
struct commit *common_item;
|
struct commit *common_item;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1635,9 +1638,10 @@ 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 = repo_get_merge_bases(the_repository,
|
if (repo_get_merge_bases(the_repository, head_commit,
|
||||||
head_commit,
|
j->item, &common_one) < 0)
|
||||||
j->item);
|
exit(128);
|
||||||
|
|
||||||
common_item = common_one->item;
|
common_item = common_one->item;
|
||||||
free_commit_list(common_one);
|
free_commit_list(common_one);
|
||||||
if (!oideq(&common_item->object.oid, &j->item->object.oid)) {
|
if (!oideq(&common_item->object.oid, &j->item->object.oid)) {
|
||||||
|
|
|
@ -867,7 +867,8 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
|
||||||
if (!upstream)
|
if (!upstream)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
merge_bases = repo_get_merge_bases(the_repository, upstream, head);
|
if (repo_get_merge_bases(the_repository, upstream, head, &merge_bases) < 0)
|
||||||
|
exit(128);
|
||||||
if (!merge_bases || merge_bases->next)
|
if (!merge_bases || merge_bases->next)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -886,8 +887,9 @@ static void fill_branch_base(struct rebase_options *options,
|
||||||
{
|
{
|
||||||
struct commit_list *merge_bases = NULL;
|
struct commit_list *merge_bases = NULL;
|
||||||
|
|
||||||
merge_bases = repo_get_merge_bases(the_repository, options->onto,
|
if (repo_get_merge_bases(the_repository, options->onto,
|
||||||
options->orig_head);
|
options->orig_head, &merge_bases) < 0)
|
||||||
|
exit(128);
|
||||||
if (!merge_bases || merge_bases->next)
|
if (!merge_bases || merge_bases->next)
|
||||||
oidcpy(branch_base, null_oid());
|
oidcpy(branch_base, null_oid());
|
||||||
else
|
else
|
||||||
|
|
|
@ -297,7 +297,7 @@ static int try_difference(const char *arg)
|
||||||
show_rev(NORMAL, &end_oid, end);
|
show_rev(NORMAL, &end_oid, end);
|
||||||
show_rev(symmetric ? NORMAL : REVERSED, &start_oid, start);
|
show_rev(symmetric ? NORMAL : REVERSED, &start_oid, start);
|
||||||
if (symmetric) {
|
if (symmetric) {
|
||||||
struct commit_list *exclude;
|
struct commit_list *exclude = NULL;
|
||||||
struct commit *a, *b;
|
struct commit *a, *b;
|
||||||
a = lookup_commit_reference(the_repository, &start_oid);
|
a = lookup_commit_reference(the_repository, &start_oid);
|
||||||
b = lookup_commit_reference(the_repository, &end_oid);
|
b = lookup_commit_reference(the_repository, &end_oid);
|
||||||
|
@ -305,7 +305,8 @@ static int try_difference(const char *arg)
|
||||||
*dotdot = '.';
|
*dotdot = '.';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
exclude = repo_get_merge_bases(the_repository, a, b);
|
if (repo_get_merge_bases(the_repository, a, b, &exclude) < 0)
|
||||||
|
exit(128);
|
||||||
while (exclude) {
|
while (exclude) {
|
||||||
struct commit *commit = pop_commit(&exclude);
|
struct commit *commit = pop_commit(&exclude);
|
||||||
show_rev(REVERSED, &commit->object.oid, NULL);
|
show_rev(REVERSED, &commit->object.oid, NULL);
|
||||||
|
|
|
@ -188,9 +188,12 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
|
||||||
struct commit_list *new_commits = NULL, *end = NULL;
|
struct commit_list *new_commits = NULL, *end = NULL;
|
||||||
|
|
||||||
for (j = ret; j; j = j->next) {
|
for (j = ret; j; j = j->next) {
|
||||||
struct commit_list *bases;
|
struct commit_list *bases = NULL;
|
||||||
bases = repo_get_merge_bases(the_repository, i->item,
|
if (repo_get_merge_bases(the_repository, i->item,
|
||||||
j->item);
|
j->item, &bases) < 0) {
|
||||||
|
free_commit_list(bases);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (!new_commits)
|
if (!new_commits)
|
||||||
new_commits = bases;
|
new_commits = bases;
|
||||||
else
|
else
|
||||||
|
@ -482,16 +485,12 @@ struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct commit_list *repo_get_merge_bases(struct repository *r,
|
int repo_get_merge_bases(struct repository *r,
|
||||||
struct commit *one,
|
struct commit *one,
|
||||||
struct commit *two)
|
struct commit *two,
|
||||||
|
struct commit_list **result)
|
||||||
{
|
{
|
||||||
struct commit_list *result = NULL;
|
return get_merge_bases_many_0(r, one, 1, &two, 1, result);
|
||||||
if (get_merge_bases_many_0(r, one, 1, &two, 1, &result) < 0) {
|
|
||||||
free_commit_list(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -9,9 +9,10 @@ struct ref_filter;
|
||||||
struct object_id;
|
struct object_id;
|
||||||
struct object_array;
|
struct object_array;
|
||||||
|
|
||||||
struct commit_list *repo_get_merge_bases(struct repository *r,
|
int repo_get_merge_bases(struct repository *r,
|
||||||
struct commit *rev1,
|
struct commit *rev1,
|
||||||
struct commit *rev2);
|
struct commit *rev2,
|
||||||
|
struct commit_list **result);
|
||||||
struct commit_list *repo_get_merge_bases_many(struct repository *r,
|
struct commit_list *repo_get_merge_bases_many(struct repository *r,
|
||||||
struct commit *one, int n,
|
struct commit *one, int n,
|
||||||
struct commit **twos);
|
struct commit **twos);
|
||||||
|
|
|
@ -570,7 +570,7 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct commit *mb_child[2] = {0};
|
struct commit *mb_child[2] = {0};
|
||||||
struct commit_list *merge_bases;
|
struct commit_list *merge_bases = NULL;
|
||||||
|
|
||||||
for (i = 0; i < revs->pending.nr; i++) {
|
for (i = 0; i < revs->pending.nr; i++) {
|
||||||
struct object *obj = revs->pending.objects[i].item;
|
struct object *obj = revs->pending.objects[i].item;
|
||||||
|
@ -597,7 +597,8 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
|
||||||
mb_child[1] = lookup_commit_reference(the_repository, &oid);
|
mb_child[1] = lookup_commit_reference(the_repository, &oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_bases = repo_get_merge_bases(the_repository, mb_child[0], mb_child[1]);
|
if (repo_get_merge_bases(the_repository, mb_child[0], mb_child[1], &merge_bases) < 0)
|
||||||
|
exit(128);
|
||||||
if (!merge_bases)
|
if (!merge_bases)
|
||||||
die(_("no merge base found"));
|
die(_("no merge base found"));
|
||||||
if (merge_bases->next)
|
if (merge_bases->next)
|
||||||
|
|
|
@ -1011,7 +1011,7 @@ static int do_remerge_diff(struct rev_info *opt,
|
||||||
struct object_id *oid)
|
struct object_id *oid)
|
||||||
{
|
{
|
||||||
struct merge_options o;
|
struct merge_options o;
|
||||||
struct commit_list *bases;
|
struct commit_list *bases = NULL;
|
||||||
struct merge_result res = {0};
|
struct merge_result res = {0};
|
||||||
struct pretty_print_context ctx = {0};
|
struct pretty_print_context ctx = {0};
|
||||||
struct commit *parent1 = parents->item;
|
struct commit *parent1 = parents->item;
|
||||||
|
@ -1036,7 +1036,8 @@ static int do_remerge_diff(struct rev_info *opt,
|
||||||
/* Parse the relevant commits and get the merge bases */
|
/* Parse the relevant commits and get the merge bases */
|
||||||
parse_commit_or_die(parent1);
|
parse_commit_or_die(parent1);
|
||||||
parse_commit_or_die(parent2);
|
parse_commit_or_die(parent2);
|
||||||
bases = repo_get_merge_bases(the_repository, parent1, parent2);
|
if (repo_get_merge_bases(the_repository, parent1, parent2, &bases) < 0)
|
||||||
|
exit(128);
|
||||||
|
|
||||||
/* Re-merge the parents */
|
/* Re-merge the parents */
|
||||||
merge_incore_recursive(&o, bases, parent1, parent2, &res);
|
merge_incore_recursive(&o, bases, parent1, parent2, &res);
|
||||||
|
|
|
@ -5068,7 +5068,11 @@ static void merge_ort_internal(struct merge_options *opt,
|
||||||
struct strbuf merge_base_abbrev = STRBUF_INIT;
|
struct strbuf merge_base_abbrev = STRBUF_INIT;
|
||||||
|
|
||||||
if (!merge_bases) {
|
if (!merge_bases) {
|
||||||
merge_bases = repo_get_merge_bases(the_repository, h1, h2);
|
if (repo_get_merge_bases(the_repository, h1, h2,
|
||||||
|
&merge_bases) < 0) {
|
||||||
|
result->clean = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
|
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
|
||||||
merge_bases = reverse_commit_list(merge_bases);
|
merge_bases = reverse_commit_list(merge_bases);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3633,7 +3633,9 @@ static int merge_recursive_internal(struct merge_options *opt,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!merge_bases) {
|
if (!merge_bases) {
|
||||||
merge_bases = repo_get_merge_bases(the_repository, h1, h2);
|
if (repo_get_merge_bases(the_repository, h1, h2,
|
||||||
|
&merge_bases) < 0)
|
||||||
|
return -1;
|
||||||
merge_bases = reverse_commit_list(merge_bases);
|
merge_bases = reverse_commit_list(merge_bases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,7 +607,8 @@ int notes_merge(struct notes_merge_options *o,
|
||||||
assert(local && remote);
|
assert(local && remote);
|
||||||
|
|
||||||
/* Find merge bases */
|
/* Find merge bases */
|
||||||
bases = repo_get_merge_bases(the_repository, local, remote);
|
if (repo_get_merge_bases(the_repository, local, remote, &bases) < 0)
|
||||||
|
exit(128);
|
||||||
if (!bases) {
|
if (!bases) {
|
||||||
base_oid = null_oid();
|
base_oid = null_oid();
|
||||||
base_tree_oid = the_hash_algo->empty_tree;
|
base_tree_oid = the_hash_algo->empty_tree;
|
||||||
|
|
|
@ -1479,7 +1479,7 @@ int repo_get_oid_mb(struct repository *r,
|
||||||
struct object_id *oid)
|
struct object_id *oid)
|
||||||
{
|
{
|
||||||
struct commit *one, *two;
|
struct commit *one, *two;
|
||||||
struct commit_list *mbs;
|
struct commit_list *mbs = NULL;
|
||||||
struct object_id oid_tmp;
|
struct object_id oid_tmp;
|
||||||
const char *dots;
|
const char *dots;
|
||||||
int st;
|
int st;
|
||||||
|
@ -1507,7 +1507,10 @@ int repo_get_oid_mb(struct repository *r,
|
||||||
two = lookup_commit_reference_gently(r, &oid_tmp, 0);
|
two = lookup_commit_reference_gently(r, &oid_tmp, 0);
|
||||||
if (!two)
|
if (!two)
|
||||||
return -1;
|
return -1;
|
||||||
mbs = repo_get_merge_bases(r, one, two);
|
if (repo_get_merge_bases(r, one, two, &mbs) < 0) {
|
||||||
|
free_commit_list(mbs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (!mbs || mbs->next)
|
if (!mbs || mbs->next)
|
||||||
st = -1;
|
st = -1;
|
||||||
else {
|
else {
|
||||||
|
|
12
revision.c
12
revision.c
|
@ -1963,7 +1963,7 @@ static void add_pending_commit_list(struct rev_info *revs,
|
||||||
|
|
||||||
static void prepare_show_merge(struct rev_info *revs)
|
static void prepare_show_merge(struct rev_info *revs)
|
||||||
{
|
{
|
||||||
struct commit_list *bases;
|
struct commit_list *bases = NULL;
|
||||||
struct commit *head, *other;
|
struct commit *head, *other;
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
const char **prune = NULL;
|
const char **prune = NULL;
|
||||||
|
@ -1978,7 +1978,8 @@ static void prepare_show_merge(struct rev_info *revs)
|
||||||
other = lookup_commit_or_die(&oid, "MERGE_HEAD");
|
other = lookup_commit_or_die(&oid, "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 = repo_get_merge_bases(the_repository, head, other);
|
if (repo_get_merge_bases(the_repository, head, other, &bases) < 0)
|
||||||
|
exit(128);
|
||||||
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);
|
||||||
|
@ -2066,14 +2067,17 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
|
||||||
} else {
|
} else {
|
||||||
/* A...B -- find merge bases between the two */
|
/* A...B -- find merge bases between the two */
|
||||||
struct commit *a, *b;
|
struct commit *a, *b;
|
||||||
struct commit_list *exclude;
|
struct commit_list *exclude = NULL;
|
||||||
|
|
||||||
a = lookup_commit_reference(revs->repo, &a_obj->oid);
|
a = lookup_commit_reference(revs->repo, &a_obj->oid);
|
||||||
b = lookup_commit_reference(revs->repo, &b_obj->oid);
|
b = lookup_commit_reference(revs->repo, &b_obj->oid);
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
return dotdot_missing(arg, dotdot, revs, symmetric);
|
return dotdot_missing(arg, dotdot, revs, symmetric);
|
||||||
|
|
||||||
exclude = repo_get_merge_bases(the_repository, a, b);
|
if (repo_get_merge_bases(the_repository, a, b, &exclude) < 0) {
|
||||||
|
free_commit_list(exclude);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
add_rev_cmdline_list(revs, exclude, REV_CMD_MERGE_BASE,
|
add_rev_cmdline_list(revs, exclude, REV_CMD_MERGE_BASE,
|
||||||
flags_exclude);
|
flags_exclude);
|
||||||
add_pending_commit_list(revs, exclude, flags_exclude);
|
add_pending_commit_list(revs, exclude, flags_exclude);
|
||||||
|
|
|
@ -3908,7 +3908,7 @@ static int do_merge(struct repository *r,
|
||||||
int run_commit_flags = 0;
|
int run_commit_flags = 0;
|
||||||
struct strbuf ref_name = STRBUF_INIT;
|
struct strbuf ref_name = STRBUF_INIT;
|
||||||
struct commit *head_commit, *merge_commit, *i;
|
struct commit *head_commit, *merge_commit, *i;
|
||||||
struct commit_list *bases, *j;
|
struct commit_list *bases = NULL, *j;
|
||||||
struct commit_list *to_merge = NULL, **tail = &to_merge;
|
struct commit_list *to_merge = NULL, **tail = &to_merge;
|
||||||
const char *strategy = !opts->xopts.nr &&
|
const char *strategy = !opts->xopts.nr &&
|
||||||
(!opts->strategy ||
|
(!opts->strategy ||
|
||||||
|
@ -4134,7 +4134,11 @@ static int do_merge(struct repository *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_commit = to_merge->item;
|
merge_commit = to_merge->item;
|
||||||
bases = repo_get_merge_bases(r, head_commit, merge_commit);
|
if (repo_get_merge_bases(r, head_commit, merge_commit, &bases) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto leave_merge;
|
||||||
|
}
|
||||||
|
|
||||||
if (bases && oideq(&merge_commit->object.oid,
|
if (bases && oideq(&merge_commit->object.oid,
|
||||||
&bases->item->object.oid)) {
|
&bases->item->object.oid)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
|
@ -592,7 +592,12 @@ static void show_submodule_header(struct diff_options *o,
|
||||||
(!is_null_oid(two) && !*right))
|
(!is_null_oid(two) && !*right))
|
||||||
message = "(commits not present)";
|
message = "(commits not present)";
|
||||||
|
|
||||||
*merge_bases = repo_get_merge_bases(sub, *left, *right);
|
*merge_bases = NULL;
|
||||||
|
if (repo_get_merge_bases(sub, *left, *right, merge_bases) < 0) {
|
||||||
|
message = "(corrupt repository)";
|
||||||
|
goto output_header;
|
||||||
|
}
|
||||||
|
|
||||||
if (*merge_bases) {
|
if (*merge_bases) {
|
||||||
if ((*merge_bases)->item == *left)
|
if ((*merge_bases)->item == *left)
|
||||||
fast_forward = 1;
|
fast_forward = 1;
|
||||||
|
|
|
@ -945,4 +945,16 @@ test_expect_success 'check the input format when --stdin is passed' '
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'error out on missing commits as well' '
|
||||||
|
git init --bare missing-commit.git &&
|
||||||
|
git rev-list --objects side1 side3 >list-including-initial &&
|
||||||
|
grep -v ^$(git rev-parse side1^) <list-including-initial >list &&
|
||||||
|
git pack-objects missing-commit.git/objects/pack/missing-initial <list &&
|
||||||
|
side1=$(git rev-parse side1) &&
|
||||||
|
side3=$(git rev-parse side3) &&
|
||||||
|
test_must_fail git --git-dir=missing-commit.git \
|
||||||
|
merge-tree --allow-unrelated-histories $side1 $side3 >actual &&
|
||||||
|
test_must_be_empty actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in New Issue