mirror of https://github.com/git/git.git
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>
This commit is contained in:
parent
8226e157a9
commit
76e2a09999
|
@ -1704,11 +1704,11 @@ static struct commit *get_base_commit(const char *base_commit,
|
|||
*/
|
||||
while (rev_nr > 1) {
|
||||
for (i = 0; i < rev_nr / 2; i++) {
|
||||
struct commit_list *merge_base;
|
||||
merge_base = repo_get_merge_bases(the_repository,
|
||||
rev[2 * i],
|
||||
rev[2 * i + 1]);
|
||||
if (!merge_base || merge_base->next) {
|
||||
struct commit_list *merge_base = NULL;
|
||||
if (repo_get_merge_bases(the_repository,
|
||||
rev[2 * i],
|
||||
rev[2 * i + 1], &merge_base) < 0 ||
|
||||
!merge_base || merge_base->next) {
|
||||
if (die_on_failure) {
|
||||
die(_("failed to find exact merge base"));
|
||||
} else {
|
||||
|
|
|
@ -462,8 +462,9 @@ static int real_merge(struct merge_tree_options *o,
|
|||
* Get the merge bases, in reverse order; see comment above
|
||||
* merge_incore_recursive in merge-ort.h
|
||||
*/
|
||||
merge_bases = repo_get_merge_bases(the_repository, parent1,
|
||||
parent2);
|
||||
if (repo_get_merge_bases(the_repository, parent1,
|
||||
parent2, &merge_bases) < 0)
|
||||
exit(128);
|
||||
if (!merge_bases && !o->allow_unrelated_histories)
|
||||
die(_("refusing to merge unrelated histories"));
|
||||
merge_bases = reverse_commit_list(merge_bases);
|
||||
|
|
|
@ -1514,10 +1514,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||
|
||||
if (!remoteheads)
|
||||
; /* already up-to-date */
|
||||
else if (!remoteheads->next)
|
||||
common = repo_get_merge_bases(the_repository, head_commit,
|
||||
remoteheads->item);
|
||||
else {
|
||||
else if (!remoteheads->next) {
|
||||
if (repo_get_merge_bases(the_repository, head_commit,
|
||||
remoteheads->item, &common) < 0) {
|
||||
ret = 2;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
struct commit_list *list = remoteheads;
|
||||
commit_list_insert(head_commit, &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;
|
||||
|
||||
for (j = remoteheads; j; j = j->next) {
|
||||
struct commit_list *common_one;
|
||||
struct commit_list *common_one = NULL;
|
||||
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^
|
||||
* HEAD^^" would be missed.
|
||||
*/
|
||||
common_one = repo_get_merge_bases(the_repository,
|
||||
head_commit,
|
||||
j->item);
|
||||
if (repo_get_merge_bases(the_repository, head_commit,
|
||||
j->item, &common_one) < 0)
|
||||
exit(128);
|
||||
|
||||
common_item = common_one->item;
|
||||
free_commit_list(common_one);
|
||||
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)
|
||||
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)
|
||||
goto done;
|
||||
|
||||
|
@ -886,8 +887,9 @@ static void fill_branch_base(struct rebase_options *options,
|
|||
{
|
||||
struct commit_list *merge_bases = NULL;
|
||||
|
||||
merge_bases = repo_get_merge_bases(the_repository, options->onto,
|
||||
options->orig_head);
|
||||
if (repo_get_merge_bases(the_repository, options->onto,
|
||||
options->orig_head, &merge_bases) < 0)
|
||||
exit(128);
|
||||
if (!merge_bases || merge_bases->next)
|
||||
oidcpy(branch_base, null_oid());
|
||||
else
|
||||
|
|
|
@ -297,7 +297,7 @@ static int try_difference(const char *arg)
|
|||
show_rev(NORMAL, &end_oid, end);
|
||||
show_rev(symmetric ? NORMAL : REVERSED, &start_oid, start);
|
||||
if (symmetric) {
|
||||
struct commit_list *exclude;
|
||||
struct commit_list *exclude = NULL;
|
||||
struct commit *a, *b;
|
||||
a = lookup_commit_reference(the_repository, &start_oid);
|
||||
b = lookup_commit_reference(the_repository, &end_oid);
|
||||
|
@ -305,7 +305,8 @@ static int try_difference(const char *arg)
|
|||
*dotdot = '.';
|
||||
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) {
|
||||
struct commit *commit = pop_commit(&exclude);
|
||||
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;
|
||||
|
||||
for (j = ret; j; j = j->next) {
|
||||
struct commit_list *bases;
|
||||
bases = repo_get_merge_bases(the_repository, i->item,
|
||||
j->item);
|
||||
struct commit_list *bases = NULL;
|
||||
if (repo_get_merge_bases(the_repository, i->item,
|
||||
j->item, &bases) < 0) {
|
||||
free_commit_list(bases);
|
||||
return NULL;
|
||||
}
|
||||
if (!new_commits)
|
||||
new_commits = bases;
|
||||
else
|
||||
|
@ -482,16 +485,12 @@ struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
|
|||
return result;
|
||||
}
|
||||
|
||||
struct commit_list *repo_get_merge_bases(struct repository *r,
|
||||
struct commit *one,
|
||||
struct commit *two)
|
||||
int repo_get_merge_bases(struct repository *r,
|
||||
struct commit *one,
|
||||
struct commit *two,
|
||||
struct commit_list **result)
|
||||
{
|
||||
struct commit_list *result = NULL;
|
||||
if (get_merge_bases_many_0(r, one, 1, &two, 1, &result) < 0) {
|
||||
free_commit_list(result);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
return get_merge_bases_many_0(r, one, 1, &two, 1, result);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -9,9 +9,10 @@ struct ref_filter;
|
|||
struct object_id;
|
||||
struct object_array;
|
||||
|
||||
struct commit_list *repo_get_merge_bases(struct repository *r,
|
||||
struct commit *rev1,
|
||||
struct commit *rev2);
|
||||
int repo_get_merge_bases(struct repository *r,
|
||||
struct commit *rev1,
|
||||
struct commit *rev2,
|
||||
struct commit_list **result);
|
||||
struct commit_list *repo_get_merge_bases_many(struct repository *r,
|
||||
struct commit *one, int n,
|
||||
struct commit **twos);
|
||||
|
|
|
@ -570,7 +570,7 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
|
|||
{
|
||||
int i;
|
||||
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++) {
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
die(_("no merge base found"));
|
||||
if (merge_bases->next)
|
||||
|
|
|
@ -1011,7 +1011,7 @@ static int do_remerge_diff(struct rev_info *opt,
|
|||
struct object_id *oid)
|
||||
{
|
||||
struct merge_options o;
|
||||
struct commit_list *bases;
|
||||
struct commit_list *bases = NULL;
|
||||
struct merge_result res = {0};
|
||||
struct pretty_print_context ctx = {0};
|
||||
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_commit_or_die(parent1);
|
||||
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 */
|
||||
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;
|
||||
|
||||
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 */
|
||||
merge_bases = reverse_commit_list(merge_bases);
|
||||
}
|
||||
|
|
|
@ -3633,7 +3633,9 @@ static int merge_recursive_internal(struct merge_options *opt,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -607,7 +607,8 @@ int notes_merge(struct notes_merge_options *o,
|
|||
assert(local && remote);
|
||||
|
||||
/* 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) {
|
||||
base_oid = null_oid();
|
||||
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 commit *one, *two;
|
||||
struct commit_list *mbs;
|
||||
struct commit_list *mbs = NULL;
|
||||
struct object_id oid_tmp;
|
||||
const char *dots;
|
||||
int st;
|
||||
|
@ -1507,7 +1507,10 @@ int repo_get_oid_mb(struct repository *r,
|
|||
two = lookup_commit_reference_gently(r, &oid_tmp, 0);
|
||||
if (!two)
|
||||
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)
|
||||
st = -1;
|
||||
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)
|
||||
{
|
||||
struct commit_list *bases;
|
||||
struct commit_list *bases = NULL;
|
||||
struct commit *head, *other;
|
||||
struct object_id oid;
|
||||
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");
|
||||
add_pending_object(revs, &head->object, "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_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM);
|
||||
free_commit_list(bases);
|
||||
|
@ -2066,14 +2067,17 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
|
|||
} else {
|
||||
/* A...B -- find merge bases between the two */
|
||||
struct commit *a, *b;
|
||||
struct commit_list *exclude;
|
||||
struct commit_list *exclude = NULL;
|
||||
|
||||
a = lookup_commit_reference(revs->repo, &a_obj->oid);
|
||||
b = lookup_commit_reference(revs->repo, &b_obj->oid);
|
||||
if (!a || !b)
|
||||
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,
|
||||
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;
|
||||
struct strbuf ref_name = STRBUF_INIT;
|
||||
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;
|
||||
const char *strategy = !opts->xopts.nr &&
|
||||
(!opts->strategy ||
|
||||
|
@ -4134,7 +4134,11 @@ static int do_merge(struct repository *r,
|
|||
}
|
||||
|
||||
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,
|
||||
&bases->item->object.oid)) {
|
||||
ret = 0;
|
||||
|
|
|
@ -592,7 +592,12 @@ static void show_submodule_header(struct diff_options *o,
|
|||
(!is_null_oid(two) && !*right))
|
||||
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)->item == *left)
|
||||
fast_forward = 1;
|
||||
|
|
|
@ -945,4 +945,16 @@ test_expect_success 'check the input format when --stdin is passed' '
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue