commit-reach(repo_in_merge_bases_many): report missing commits
Some functions in Git's source code follow the convention that returning a negative value indicates a fatal error, e.g. repository corruption. Let's use this convention in `repo_in_merge_bases()` to report when one of the specified commits is missing (i.e. when `repo_parse_commit()` reports an error). Also adjust the callers of `repo_in_merge_bases()` to handle such negative return values. Note: As of this patch, errors are returned only if any of the specified merge heads is missing. Over the course of the next patches, missing commits will also be reported by the `paint_down_to_common()` function, which is called by `repo_in_merge_bases_many()`, and those errors will be properly propagated back to the caller at that stage. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
207c40e1e4
commit
24876ebf68
@ -158,6 +158,8 @@ static int branch_merged(int kind, const char *name,
|
|||||||
|
|
||||||
merged = reference_rev ? repo_in_merge_bases(the_repository, rev,
|
merged = reference_rev ? repo_in_merge_bases(the_repository, rev,
|
||||||
reference_rev) : 0;
|
reference_rev) : 0;
|
||||||
|
if (merged < 0)
|
||||||
|
exit(128);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* After the safety valve is fully redefined to "check with
|
* After the safety valve is fully redefined to "check with
|
||||||
@ -166,9 +168,13 @@ static int branch_merged(int kind, const char *name,
|
|||||||
* any of the following code, but during the transition period,
|
* any of the following code, but during the transition period,
|
||||||
* a gentle reminder is in order.
|
* a gentle reminder is in order.
|
||||||
*/
|
*/
|
||||||
if ((head_rev != reference_rev) &&
|
if (head_rev != reference_rev) {
|
||||||
(head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0) != merged) {
|
int expect = head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0;
|
||||||
if (merged)
|
if (expect < 0)
|
||||||
|
exit(128);
|
||||||
|
if (expect == merged)
|
||||||
|
; /* okay */
|
||||||
|
else if (merged)
|
||||||
warning(_("deleting branch '%s' that has been merged to\n"
|
warning(_("deleting branch '%s' that has been merged to\n"
|
||||||
" '%s', but not yet merged to HEAD"),
|
" '%s', but not yet merged to HEAD"),
|
||||||
name, reference_name);
|
name, reference_name);
|
||||||
|
@ -1625,6 +1625,7 @@ static int update_branch(struct branch *b)
|
|||||||
oidclr(&old_oid);
|
oidclr(&old_oid);
|
||||||
if (!force_update && !is_null_oid(&old_oid)) {
|
if (!force_update && !is_null_oid(&old_oid)) {
|
||||||
struct commit *old_cmit, *new_cmit;
|
struct commit *old_cmit, *new_cmit;
|
||||||
|
int ret;
|
||||||
|
|
||||||
old_cmit = lookup_commit_reference_gently(the_repository,
|
old_cmit = lookup_commit_reference_gently(the_repository,
|
||||||
&old_oid, 0);
|
&old_oid, 0);
|
||||||
@ -1633,7 +1634,10 @@ static int update_branch(struct branch *b)
|
|||||||
if (!old_cmit || !new_cmit)
|
if (!old_cmit || !new_cmit)
|
||||||
return error("Branch %s is missing commits.", b->name);
|
return error("Branch %s is missing commits.", b->name);
|
||||||
|
|
||||||
if (!repo_in_merge_bases(the_repository, old_cmit, new_cmit)) {
|
ret = repo_in_merge_bases(the_repository, old_cmit, new_cmit);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
|
if (!ret) {
|
||||||
warning("Not updating %s"
|
warning("Not updating %s"
|
||||||
" (new tip %s does not contain %s)",
|
" (new tip %s does not contain %s)",
|
||||||
b->name, oid_to_hex(&b->oid),
|
b->name, oid_to_hex(&b->oid),
|
||||||
|
@ -982,6 +982,8 @@ static int update_local_ref(struct ref *ref,
|
|||||||
uint64_t t_before = getnanotime();
|
uint64_t t_before = getnanotime();
|
||||||
fast_forward = repo_in_merge_bases(the_repository, current,
|
fast_forward = repo_in_merge_bases(the_repository, current,
|
||||||
updated);
|
updated);
|
||||||
|
if (fast_forward < 0)
|
||||||
|
exit(128);
|
||||||
forced_updates_ms += (getnanotime() - t_before) / 1000000;
|
forced_updates_ms += (getnanotime() - t_before) / 1000000;
|
||||||
} else {
|
} else {
|
||||||
fast_forward = 1;
|
fast_forward = 1;
|
||||||
|
@ -1625,7 +1625,7 @@ static struct commit *get_base_commit(const char *base_commit,
|
|||||||
{
|
{
|
||||||
struct commit *base = NULL;
|
struct commit *base = NULL;
|
||||||
struct commit **rev;
|
struct commit **rev;
|
||||||
int i = 0, rev_nr = 0, auto_select, die_on_failure;
|
int i = 0, rev_nr = 0, auto_select, die_on_failure, ret;
|
||||||
|
|
||||||
switch (auto_base) {
|
switch (auto_base) {
|
||||||
case AUTO_BASE_NEVER:
|
case AUTO_BASE_NEVER:
|
||||||
@ -1725,7 +1725,10 @@ static struct commit *get_base_commit(const char *base_commit,
|
|||||||
rev_nr = DIV_ROUND_UP(rev_nr, 2);
|
rev_nr = DIV_ROUND_UP(rev_nr, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!repo_in_merge_bases(the_repository, base, rev[0])) {
|
ret = repo_in_merge_bases(the_repository, base, rev[0]);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
|
if (!ret) {
|
||||||
if (die_on_failure) {
|
if (die_on_failure) {
|
||||||
die(_("base commit should be the ancestor of revision list"));
|
die(_("base commit should be the ancestor of revision list"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,12 +100,16 @@ static int handle_octopus(int count, const char **args, int show_all)
|
|||||||
static int handle_is_ancestor(int argc, const char **argv)
|
static int handle_is_ancestor(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct commit *one, *two;
|
struct commit *one, *two;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
die("--is-ancestor takes exactly two commits");
|
die("--is-ancestor takes exactly two commits");
|
||||||
one = get_commit_reference(argv[0]);
|
one = get_commit_reference(argv[0]);
|
||||||
two = get_commit_reference(argv[1]);
|
two = get_commit_reference(argv[1]);
|
||||||
if (repo_in_merge_bases(the_repository, one, two))
|
ret = repo_in_merge_bases(the_repository, one, two);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
|
if (ret)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -926,6 +926,8 @@ static int get_can_ff(struct object_id *orig_head,
|
|||||||
merge_head = lookup_commit_reference(the_repository, orig_merge_head);
|
merge_head = lookup_commit_reference(the_repository, orig_merge_head);
|
||||||
ret = repo_is_descendant_of(the_repository, merge_head, list);
|
ret = repo_is_descendant_of(the_repository, merge_head, list);
|
||||||
free_commit_list(list);
|
free_commit_list(list);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,6 +952,8 @@ static int already_up_to_date(struct object_id *orig_head,
|
|||||||
commit_list_insert(theirs, &list);
|
commit_list_insert(theirs, &list);
|
||||||
ok = repo_is_descendant_of(the_repository, ours, list);
|
ok = repo_is_descendant_of(the_repository, ours, list);
|
||||||
free_commit_list(list);
|
free_commit_list(list);
|
||||||
|
if (ok < 0)
|
||||||
|
exit(128);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1526,6 +1526,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||||||
starts_with(name, "refs/heads/")) {
|
starts_with(name, "refs/heads/")) {
|
||||||
struct object *old_object, *new_object;
|
struct object *old_object, *new_object;
|
||||||
struct commit *old_commit, *new_commit;
|
struct commit *old_commit, *new_commit;
|
||||||
|
int ret2;
|
||||||
|
|
||||||
old_object = parse_object(the_repository, old_oid);
|
old_object = parse_object(the_repository, old_oid);
|
||||||
new_object = parse_object(the_repository, new_oid);
|
new_object = parse_object(the_repository, new_oid);
|
||||||
@ -1539,7 +1540,10 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||||||
}
|
}
|
||||||
old_commit = (struct commit *)old_object;
|
old_commit = (struct commit *)old_object;
|
||||||
new_commit = (struct commit *)new_object;
|
new_commit = (struct commit *)new_object;
|
||||||
if (!repo_in_merge_bases(the_repository, old_commit, new_commit)) {
|
ret2 = repo_in_merge_bases(the_repository, old_commit, new_commit);
|
||||||
|
if (ret2 < 0)
|
||||||
|
exit(128);
|
||||||
|
if (!ret2) {
|
||||||
rp_error("denying non-fast-forward %s"
|
rp_error("denying non-fast-forward %s"
|
||||||
" (you should pull first)", name);
|
" (you should pull first)", name);
|
||||||
ret = "non-fast-forward";
|
ret = "non-fast-forward";
|
||||||
|
@ -463,11 +463,13 @@ int repo_is_descendant_of(struct repository *r,
|
|||||||
} else {
|
} else {
|
||||||
while (with_commit) {
|
while (with_commit) {
|
||||||
struct commit *other;
|
struct commit *other;
|
||||||
|
int ret;
|
||||||
|
|
||||||
other = with_commit->item;
|
other = with_commit->item;
|
||||||
with_commit = with_commit->next;
|
with_commit = with_commit->next;
|
||||||
if (repo_in_merge_bases_many(r, other, 1, &commit, 0))
|
ret = repo_in_merge_bases_many(r, other, 1, &commit, 0);
|
||||||
return 1;
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -597,6 +599,8 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
|
|||||||
commit_list_insert(old_commit, &old_commit_list);
|
commit_list_insert(old_commit, &old_commit_list);
|
||||||
ret = repo_is_descendant_of(the_repository,
|
ret = repo_is_descendant_of(the_repository,
|
||||||
new_commit, old_commit_list);
|
new_commit, old_commit_list);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
free_commit_list(old_commit_list);
|
free_commit_list(old_commit_list);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1575,8 +1575,11 @@ static int verify_merge_base(struct object_id *head_oid, struct ref *remote)
|
|||||||
struct commit *head = lookup_commit_or_die(head_oid, "HEAD");
|
struct commit *head = lookup_commit_or_die(head_oid, "HEAD");
|
||||||
struct commit *branch = lookup_commit_or_die(&remote->old_oid,
|
struct commit *branch = lookup_commit_or_die(&remote->old_oid,
|
||||||
remote->name);
|
remote->name);
|
||||||
|
int ret = repo_in_merge_bases(the_repository, branch, head);
|
||||||
|
|
||||||
return repo_in_merge_bases(the_repository, branch, head);
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int delete_remote_branch(const char *pattern, int force)
|
static int delete_remote_branch(const char *pattern, int force)
|
||||||
|
77
merge-ort.c
77
merge-ort.c
@ -542,6 +542,7 @@ enum conflict_and_info_types {
|
|||||||
CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE,
|
CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE,
|
||||||
CONFLICT_SUBMODULE_MAY_HAVE_REWINDS,
|
CONFLICT_SUBMODULE_MAY_HAVE_REWINDS,
|
||||||
CONFLICT_SUBMODULE_NULL_MERGE_BASE,
|
CONFLICT_SUBMODULE_NULL_MERGE_BASE,
|
||||||
|
CONFLICT_SUBMODULE_CORRUPT,
|
||||||
|
|
||||||
/* Keep this entry _last_ in the list */
|
/* Keep this entry _last_ in the list */
|
||||||
NB_CONFLICT_TYPES,
|
NB_CONFLICT_TYPES,
|
||||||
@ -594,7 +595,9 @@ static const char *type_short_descriptions[] = {
|
|||||||
[CONFLICT_SUBMODULE_MAY_HAVE_REWINDS] =
|
[CONFLICT_SUBMODULE_MAY_HAVE_REWINDS] =
|
||||||
"CONFLICT (submodule may have rewinds)",
|
"CONFLICT (submodule may have rewinds)",
|
||||||
[CONFLICT_SUBMODULE_NULL_MERGE_BASE] =
|
[CONFLICT_SUBMODULE_NULL_MERGE_BASE] =
|
||||||
"CONFLICT (submodule lacks merge base)"
|
"CONFLICT (submodule lacks merge base)",
|
||||||
|
[CONFLICT_SUBMODULE_CORRUPT] =
|
||||||
|
"CONFLICT (submodule corrupt)"
|
||||||
};
|
};
|
||||||
|
|
||||||
struct logical_conflict_info {
|
struct logical_conflict_info {
|
||||||
@ -1708,7 +1711,14 @@ static int find_first_merges(struct repository *repo,
|
|||||||
die("revision walk setup failed");
|
die("revision walk setup failed");
|
||||||
while ((commit = get_revision(&revs)) != NULL) {
|
while ((commit = get_revision(&revs)) != NULL) {
|
||||||
struct object *o = &(commit->object);
|
struct object *o = &(commit->object);
|
||||||
if (repo_in_merge_bases(repo, b, commit))
|
int ret = repo_in_merge_bases(repo, b, commit);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
object_array_clear(&merges);
|
||||||
|
release_revisions(&revs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret > 0)
|
||||||
add_object_array(o, NULL, &merges);
|
add_object_array(o, NULL, &merges);
|
||||||
}
|
}
|
||||||
reset_revision_walk();
|
reset_revision_walk();
|
||||||
@ -1723,11 +1733,19 @@ static int find_first_merges(struct repository *repo,
|
|||||||
contains_another = 0;
|
contains_another = 0;
|
||||||
for (j = 0; j < merges.nr; j++) {
|
for (j = 0; j < merges.nr; j++) {
|
||||||
struct commit *m2 = (struct commit *) merges.objects[j].item;
|
struct commit *m2 = (struct commit *) merges.objects[j].item;
|
||||||
if (i != j && repo_in_merge_bases(repo, m2, m1)) {
|
if (i != j) {
|
||||||
|
int ret = repo_in_merge_bases(repo, m2, m1);
|
||||||
|
if (ret < 0) {
|
||||||
|
object_array_clear(&merges);
|
||||||
|
release_revisions(&revs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret > 0) {
|
||||||
contains_another = 1;
|
contains_another = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!contains_another)
|
if (!contains_another)
|
||||||
add_object_array(merges.objects[i].item, NULL, result);
|
add_object_array(merges.objects[i].item, NULL, result);
|
||||||
@ -1747,7 +1765,7 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
{
|
{
|
||||||
struct repository subrepo;
|
struct repository subrepo;
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
int ret = 0;
|
int ret = 0, ret2;
|
||||||
struct commit *commit_o, *commit_a, *commit_b;
|
struct commit *commit_o, *commit_a, *commit_b;
|
||||||
int parent_count;
|
int parent_count;
|
||||||
struct object_array merges;
|
struct object_array merges;
|
||||||
@ -1794,8 +1812,26 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check whether both changes are forward */
|
/* check whether both changes are forward */
|
||||||
if (!repo_in_merge_bases(&subrepo, commit_o, commit_a) ||
|
ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_a);
|
||||||
!repo_in_merge_bases(&subrepo, commit_o, commit_b)) {
|
if (ret2 < 0) {
|
||||||
|
path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
|
||||||
|
path, NULL, NULL, NULL,
|
||||||
|
_("Failed to merge submodule %s "
|
||||||
|
"(repository corrupt)"),
|
||||||
|
path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2 > 0)
|
||||||
|
ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_b);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
|
||||||
|
path, NULL, NULL, NULL,
|
||||||
|
_("Failed to merge submodule %s "
|
||||||
|
"(repository corrupt)"),
|
||||||
|
path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!ret2) {
|
||||||
path_msg(opt, CONFLICT_SUBMODULE_MAY_HAVE_REWINDS, 0,
|
path_msg(opt, CONFLICT_SUBMODULE_MAY_HAVE_REWINDS, 0,
|
||||||
path, NULL, NULL, NULL,
|
path, NULL, NULL, NULL,
|
||||||
_("Failed to merge submodule %s "
|
_("Failed to merge submodule %s "
|
||||||
@ -1805,7 +1841,16 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Case #1: a is contained in b or vice versa */
|
/* Case #1: a is contained in b or vice versa */
|
||||||
if (repo_in_merge_bases(&subrepo, commit_a, commit_b)) {
|
ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
|
||||||
|
path, NULL, NULL, NULL,
|
||||||
|
_("Failed to merge submodule %s "
|
||||||
|
"(repository corrupt)"),
|
||||||
|
path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2 > 0) {
|
||||||
oidcpy(result, b);
|
oidcpy(result, b);
|
||||||
path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
|
path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
|
||||||
path, NULL, NULL, NULL,
|
path, NULL, NULL, NULL,
|
||||||
@ -1814,7 +1859,16 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (repo_in_merge_bases(&subrepo, commit_b, commit_a)) {
|
ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
|
||||||
|
path, NULL, NULL, NULL,
|
||||||
|
_("Failed to merge submodule %s "
|
||||||
|
"(repository corrupt)"),
|
||||||
|
path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2 > 0) {
|
||||||
oidcpy(result, a);
|
oidcpy(result, a);
|
||||||
path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
|
path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
|
||||||
path, NULL, NULL, NULL,
|
path, NULL, NULL, NULL,
|
||||||
@ -1839,6 +1893,13 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
parent_count = find_first_merges(&subrepo, path, commit_a, commit_b,
|
parent_count = find_first_merges(&subrepo, path, commit_a, commit_b,
|
||||||
&merges);
|
&merges);
|
||||||
switch (parent_count) {
|
switch (parent_count) {
|
||||||
|
case -1:
|
||||||
|
path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
|
||||||
|
path, NULL, NULL, NULL,
|
||||||
|
_("Failed to merge submodule %s "
|
||||||
|
"(repository corrupt)"),
|
||||||
|
path);
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
path_msg(opt, CONFLICT_SUBMODULE_FAILED_TO_MERGE, 0,
|
path_msg(opt, CONFLICT_SUBMODULE_FAILED_TO_MERGE, 0,
|
||||||
path, NULL, NULL, NULL,
|
path, NULL, NULL, NULL,
|
||||||
|
@ -1139,7 +1139,13 @@ static int find_first_merges(struct repository *repo,
|
|||||||
die("revision walk setup failed");
|
die("revision walk setup failed");
|
||||||
while ((commit = get_revision(&revs)) != NULL) {
|
while ((commit = get_revision(&revs)) != NULL) {
|
||||||
struct object *o = &(commit->object);
|
struct object *o = &(commit->object);
|
||||||
if (repo_in_merge_bases(repo, b, commit))
|
int ret = repo_in_merge_bases(repo, b, commit);
|
||||||
|
if (ret < 0) {
|
||||||
|
object_array_clear(&merges);
|
||||||
|
release_revisions(&revs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
add_object_array(o, NULL, &merges);
|
add_object_array(o, NULL, &merges);
|
||||||
}
|
}
|
||||||
reset_revision_walk();
|
reset_revision_walk();
|
||||||
@ -1154,11 +1160,19 @@ static int find_first_merges(struct repository *repo,
|
|||||||
contains_another = 0;
|
contains_another = 0;
|
||||||
for (j = 0; j < merges.nr; j++) {
|
for (j = 0; j < merges.nr; j++) {
|
||||||
struct commit *m2 = (struct commit *) merges.objects[j].item;
|
struct commit *m2 = (struct commit *) merges.objects[j].item;
|
||||||
if (i != j && repo_in_merge_bases(repo, m2, m1)) {
|
if (i != j) {
|
||||||
|
int ret = repo_in_merge_bases(repo, m2, m1);
|
||||||
|
if (ret < 0) {
|
||||||
|
object_array_clear(&merges);
|
||||||
|
release_revisions(&revs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret > 0) {
|
||||||
contains_another = 1;
|
contains_another = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!contains_another)
|
if (!contains_another)
|
||||||
add_object_array(merges.objects[i].item, NULL, result);
|
add_object_array(merges.objects[i].item, NULL, result);
|
||||||
@ -1192,7 +1206,7 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
const struct object_id *b)
|
const struct object_id *b)
|
||||||
{
|
{
|
||||||
struct repository subrepo;
|
struct repository subrepo;
|
||||||
int ret = 0;
|
int ret = 0, ret2;
|
||||||
struct commit *commit_base, *commit_a, *commit_b;
|
struct commit *commit_base, *commit_a, *commit_b;
|
||||||
int parent_count;
|
int parent_count;
|
||||||
struct object_array merges;
|
struct object_array merges;
|
||||||
@ -1229,14 +1243,29 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check whether both changes are forward */
|
/* check whether both changes are forward */
|
||||||
if (!repo_in_merge_bases(&subrepo, commit_base, commit_a) ||
|
ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_a);
|
||||||
!repo_in_merge_bases(&subrepo, commit_base, commit_b)) {
|
if (ret2 < 0) {
|
||||||
|
output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2 > 0)
|
||||||
|
ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_b);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!ret2) {
|
||||||
output(opt, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path);
|
output(opt, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Case #1: a is contained in b or vice versa */
|
/* Case #1: a is contained in b or vice versa */
|
||||||
if (repo_in_merge_bases(&subrepo, commit_a, commit_b)) {
|
ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2) {
|
||||||
oidcpy(result, b);
|
oidcpy(result, b);
|
||||||
if (show(opt, 3)) {
|
if (show(opt, 3)) {
|
||||||
output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
|
output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
|
||||||
@ -1249,7 +1278,12 @@ static int merge_submodule(struct merge_options *opt,
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (repo_in_merge_bases(&subrepo, commit_b, commit_a)) {
|
ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a);
|
||||||
|
if (ret2 < 0) {
|
||||||
|
output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (ret2) {
|
||||||
oidcpy(result, a);
|
oidcpy(result, a);
|
||||||
if (show(opt, 3)) {
|
if (show(opt, 3)) {
|
||||||
output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
|
output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
|
||||||
@ -1397,6 +1431,8 @@ static int merge_mode_and_contents(struct merge_options *opt,
|
|||||||
&o->oid,
|
&o->oid,
|
||||||
&a->oid,
|
&a->oid,
|
||||||
&b->oid);
|
&b->oid);
|
||||||
|
if (result->clean < 0)
|
||||||
|
return -1;
|
||||||
} else if (S_ISLNK(a->mode)) {
|
} else if (S_ISLNK(a->mode)) {
|
||||||
switch (opt->recursive_variant) {
|
switch (opt->recursive_variant) {
|
||||||
case MERGE_VARIANT_NORMAL:
|
case MERGE_VARIANT_NORMAL:
|
||||||
|
10
shallow.c
10
shallow.c
@ -794,14 +794,18 @@ static void post_assign_shallow(struct shallow_info *info,
|
|||||||
if (!*bitmap)
|
if (!*bitmap)
|
||||||
continue;
|
continue;
|
||||||
for (j = 0; j < bitmap_nr; j++)
|
for (j = 0; j < bitmap_nr; j++)
|
||||||
if (bitmap[0][j] &&
|
if (bitmap[0][j]) {
|
||||||
/* Step 7, reachability test at commit level */
|
/* Step 7, reachability test at commit level */
|
||||||
!repo_in_merge_bases_many(the_repository, c, ca.nr, ca.commits, 1)) {
|
int ret = repo_in_merge_bases_many(the_repository, c, ca.nr, ca.commits, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
exit(128);
|
||||||
|
if (!ret) {
|
||||||
update_refstatus(ref_status, info->ref->nr, *bitmap);
|
update_refstatus(ref_status, info->ref->nr, *bitmap);
|
||||||
dst++;
|
dst++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
info->nr_ours = dst;
|
info->nr_ours = dst;
|
||||||
|
|
||||||
free(ca.commits);
|
free(ca.commits);
|
||||||
@ -829,6 +833,8 @@ int delayed_reachability_test(struct shallow_info *si, int c)
|
|||||||
si->nr_commits,
|
si->nr_commits,
|
||||||
si->commits,
|
si->commits,
|
||||||
1);
|
1);
|
||||||
|
if (si->reachable[c] < 0)
|
||||||
|
exit(128);
|
||||||
si->need_reachability_test[c] = 0;
|
si->need_reachability_test[c] = 0;
|
||||||
}
|
}
|
||||||
return si->reachable[c];
|
return si->reachable[c];
|
||||||
|
Reference in New Issue
Block a user