]> git.ipfire.org Git - thirdparty/git.git/commitdiff
checkout: provide better conflict hunk description with detached HEAD
authorElijah Newren <newren@gmail.com>
Thu, 15 Aug 2019 21:40:31 +0000 (14:40 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 16 Aug 2019 19:47:20 +0000 (12:47 -0700)
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>
builtin/checkout.c

index 6123f732a2c84f975c576e7077a0c6da369e6b31..d5b946dc3af73e2a35af69a4669206164ffc5ef8 100644 (file)
@@ -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;
                }