merge-ort: copy and adapt merge_submodule() from merge-recursive.c
Take merge_submodule() from merge-recursive.c and make slight adjustments, predominantly around deferring output using path_msg() instead of using merge-recursive's output() and show() functions. There's also a fix for recursive cases (when call_depth > 0) and a slight change to argument order for find_first_merges(). find_first_merges() and format_commit() are left unimplemented for now, but will be added by subsequent commits. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
f591c47246
commit
c73cda76b1
126
merge-ort.c
126
merge-ort.c
@ -26,6 +26,7 @@
|
||||
#include "ll-merge.h"
|
||||
#include "object-store.h"
|
||||
#include "strmap.h"
|
||||
#include "submodule.h"
|
||||
#include "tree.h"
|
||||
#include "unpack-trees.h"
|
||||
#include "xdiff-interface.h"
|
||||
@ -323,6 +324,13 @@ static int err(struct merge_options *opt, const char *err, ...)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void format_commit(struct strbuf *sb,
|
||||
int indent,
|
||||
struct commit *commit)
|
||||
{
|
||||
die("Not yet implemented.");
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 4, 5)))
|
||||
static void path_msg(struct merge_options *opt,
|
||||
const char *path,
|
||||
@ -632,6 +640,15 @@ static int collect_merge_info(struct merge_options *opt,
|
||||
|
||||
/*** Function Grouping: functions related to threeway content merges ***/
|
||||
|
||||
static int find_first_merges(struct repository *repo,
|
||||
const char *path,
|
||||
struct commit *a,
|
||||
struct commit *b,
|
||||
struct object_array *result)
|
||||
{
|
||||
die("Not yet implemented.");
|
||||
}
|
||||
|
||||
static int merge_submodule(struct merge_options *opt,
|
||||
const char *path,
|
||||
const struct object_id *o,
|
||||
@ -639,7 +656,114 @@ static int merge_submodule(struct merge_options *opt,
|
||||
const struct object_id *b,
|
||||
struct object_id *result)
|
||||
{
|
||||
die("Not yet implemented.");
|
||||
struct commit *commit_o, *commit_a, *commit_b;
|
||||
int parent_count;
|
||||
struct object_array merges;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
int i;
|
||||
int search = !opt->priv->call_depth;
|
||||
|
||||
/* store fallback answer in result in case we fail */
|
||||
oidcpy(result, opt->priv->call_depth ? o : a);
|
||||
|
||||
/* we can not handle deletion conflicts */
|
||||
if (is_null_oid(o))
|
||||
return 0;
|
||||
if (is_null_oid(a))
|
||||
return 0;
|
||||
if (is_null_oid(b))
|
||||
return 0;
|
||||
|
||||
if (add_submodule_odb(path)) {
|
||||
path_msg(opt, path, 0,
|
||||
_("Failed to merge submodule %s (not checked out)"),
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(commit_o = lookup_commit_reference(opt->repo, o)) ||
|
||||
!(commit_a = lookup_commit_reference(opt->repo, a)) ||
|
||||
!(commit_b = lookup_commit_reference(opt->repo, b))) {
|
||||
path_msg(opt, path, 0,
|
||||
_("Failed to merge submodule %s (commits not present)"),
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check whether both changes are forward */
|
||||
if (!in_merge_bases(commit_o, commit_a) ||
|
||||
!in_merge_bases(commit_o, commit_b)) {
|
||||
path_msg(opt, path, 0,
|
||||
_("Failed to merge submodule %s "
|
||||
"(commits don't follow merge-base)"),
|
||||
path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Case #1: a is contained in b or vice versa */
|
||||
if (in_merge_bases(commit_a, commit_b)) {
|
||||
oidcpy(result, b);
|
||||
path_msg(opt, path, 1,
|
||||
_("Note: Fast-forwarding submodule %s to %s"),
|
||||
path, oid_to_hex(b));
|
||||
return 1;
|
||||
}
|
||||
if (in_merge_bases(commit_b, commit_a)) {
|
||||
oidcpy(result, a);
|
||||
path_msg(opt, path, 1,
|
||||
_("Note: Fast-forwarding submodule %s to %s"),
|
||||
path, oid_to_hex(a));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case #2: There are one or more merges that contain a and b in
|
||||
* the submodule. If there is only one, then present it as a
|
||||
* suggestion to the user, but leave it marked unmerged so the
|
||||
* user needs to confirm the resolution.
|
||||
*/
|
||||
|
||||
/* Skip the search if makes no sense to the calling context. */
|
||||
if (!search)
|
||||
return 0;
|
||||
|
||||
/* find commit which merges them */
|
||||
parent_count = find_first_merges(opt->repo, path, commit_a, commit_b,
|
||||
&merges);
|
||||
switch (parent_count) {
|
||||
case 0:
|
||||
path_msg(opt, path, 0, _("Failed to merge submodule %s"), path);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
format_commit(&sb, 4,
|
||||
(struct commit *)merges.objects[0].item);
|
||||
path_msg(opt, path, 0,
|
||||
_("Failed to merge submodule %s, but a possible merge "
|
||||
"resolution exists:\n%s\n"),
|
||||
path, sb.buf);
|
||||
path_msg(opt, path, 1,
|
||||
_("If this is correct simply add it to the index "
|
||||
"for example\n"
|
||||
"by using:\n\n"
|
||||
" git update-index --cacheinfo 160000 %s \"%s\"\n\n"
|
||||
"which will accept this suggestion.\n"),
|
||||
oid_to_hex(&merges.objects[0].item->oid), path);
|
||||
strbuf_release(&sb);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < merges.nr; i++)
|
||||
format_commit(&sb, 4,
|
||||
(struct commit *)merges.objects[i].item);
|
||||
path_msg(opt, path, 0,
|
||||
_("Failed to merge submodule %s, but multiple "
|
||||
"possible merges exist:\n%s"), path, sb.buf);
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
|
||||
object_array_clear(&merges);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int merge_3way(struct merge_options *opt,
|
||||
|
Loading…
x
Reference in New Issue
Block a user