checkout: provide better conflict hunk description with detached HEAD
When running 'git checkout -m' and using diff3 style conflict markers,
we want all the conflict hunks (left-side, "common" or "merge base", and
right-side) to have label markers letting the user know where each came
from. The "common" hunk label (o.ancestor) came from
old_branch_info->name, but that is NULL when HEAD is detached, which
resulted in a blank label. Check for that case and provide an
abbreviated commit hash instead.
(Incidentally, this was the only case in the git codebase where
merge_trees() was called with opt->ancestor being NULL. A subsequent
commit will prevent similar problems by enforcing that merge_trees()
always be called with opt->ancestor != NULL.)
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 6123f73..d5b946d 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -713,6 +713,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
struct tree *old_tree;
struct merge_options o;
struct strbuf sb = STRBUF_INIT;
+ struct strbuf old_commit_shortname = STRBUF_INIT;
if (!opts->merge)
return 1;
@@ -768,6 +769,12 @@ static int merge_working_tree(const struct checkout_opts *opts,
if (ret)
return ret;
o.ancestor = old_branch_info->name;
+ if (old_branch_info->name == NULL) {
+ strbuf_add_unique_abbrev(&old_commit_shortname,
+ &old_branch_info->commit->object.oid,
+ DEFAULT_ABBREV);
+ o.ancestor = old_commit_shortname.buf;
+ }
o.branch1 = new_branch_info->name;
o.branch2 = "local";
ret = merge_trees(&o,
@@ -781,6 +788,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
opts, 0,
writeout_error);
strbuf_release(&o.obuf);
+ strbuf_release(&old_commit_shortname);
if (ret)
return ret;
}