git cherry-pick and git revert will write conflict hunks something like what ‘diff3 -m’ produces if the merge.conflictstyle configuration option is set to diff3. Unlike ‘diff3 -m’, though, the output lacks a label for the merge base on the ||||||| line of the output. Some tools can misparse the conflict hunks without such a label. Especially in a cherry-pick, humans parsing the conflict hunks by hand might want to know what the common ancestor represents, too. Add a label. Example: <<<<<<< HEAD Something old. Something new. Something rotten. Something blue. ||||||| parent of 387924c... Remove something rotten Something old. Something rotten. Something blue. ======= Something old. something blue. >>>>>>> 387924c... Remove something rotten git rerere does not have trouble parsing the new output, and its preimage ids are unchanged since it includes its own code for recreating conflict hunks. No other code in git parses conflict hunks. Requested-by: Stefan Monnier <monnier@xxxxxxxxxxxxxxxx> Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- Hopefully the new labels clearer, especially when reverting a commit. Thoughts? builtin/revert.c | 27 ++++++++++++++++----------- t/t3507-cherry-pick-conflict.sh | 4 ++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/builtin/revert.c b/builtin/revert.c index 56f2947..7a39b52 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -73,11 +73,11 @@ static void parse_args(int argc, const char **argv) exit(1); } -static char *get_oneline(const char *message, int revert, char **body) +static char *get_oneline(const char *message, char **body, char **parent) { char *result, *q; - const char *p = message, *prefix, *abbrev, *eol; - int prefix_len, abbrev_len, oneline_len; + const char *p = message, *abbrev, *eol; + int abbrev_len, oneline_len; if (!p) die ("Could not read commit message of %s", @@ -91,14 +91,12 @@ static char *get_oneline(const char *message, int revert, char **body) ; /* do nothing */ } else eol = p; - prefix = revert ? "parent of " : ""; - prefix_len = revert ? strlen("parent of ") : 0; abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV); abbrev_len = strlen(abbrev); oneline_len = eol - p; - q = result = xmalloc(prefix_len + abbrev_len + - strlen("... ") + oneline_len + 1); - q = mempcpy(q, prefix, prefix_len); + *parent = q = xmalloc(strlen("parent of ") + abbrev_len + + strlen("... ") + oneline_len + 1); + result = q = mempcpy(q, "parent of ", strlen("parent of ")); q = mempcpy(q, abbrev, abbrev_len); *body = q = mempcpy(q, "... ", strlen("... ")); q = mempcpy(q, p, oneline_len); @@ -252,8 +250,10 @@ static int revert_or_cherry_pick(int argc, const char **argv) { unsigned char head[20]; struct commit *base, *next, *parent; + const char *base_label, *next_label; int i, index_fd, clean; - char *oneline, *oneline_body, *reencoded_message = NULL; + char *oneline, *oneline_body, *parent_label; + char *reencoded_message = NULL; const char *message, *encoding; char *defmsg = git_pathdup("MERGE_MSG"); struct merge_options o; @@ -345,11 +345,13 @@ static int revert_or_cherry_pick(int argc, const char **argv) git_commit_encoding, encoding))) message = reencoded_message; - oneline = get_oneline(message, action == REVERT, &oneline_body); + oneline = get_oneline(message, &oneline_body, &parent_label); if (action == REVERT) { base = commit; + base_label = oneline; next = parent; + next_label = parent_label; add_to_msg("Revert \""); add_to_msg(oneline_body); add_to_msg("\"\n\nThis reverts commit "); @@ -362,7 +364,9 @@ static int revert_or_cherry_pick(int argc, const char **argv) add_to_msg(".\n"); } else { base = parent; + base_label = parent_label; next = commit; + next_label = oneline; set_author_ident_env(message); add_message_to_msg(message); if (no_replay) { @@ -374,8 +378,9 @@ static int revert_or_cherry_pick(int argc, const char **argv) read_cache(); init_merge_options(&o); + o.ancestor = base ? base_label : "(empty tree)"; o.branch1 = "HEAD"; - o.branch2 = oneline; + o.branch2 = next ? next_label : "(empty tree)"; head_tree = parse_tree_indirect(head); next_tree = next ? next->tree : empty_tree(); diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 6a20817..e25cf80 100644 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -112,7 +112,7 @@ test_expect_success 'diff3 -m style' ' cat <<-EOF > expected && <<<<<<< HEAD a - ||||||| + ||||||| parent of objid picked b ======= c @@ -179,7 +179,7 @@ test_expect_success 'revert conflict, diff3 -m style' ' cat <<-EOF > expected && <<<<<<< HEAD a - ||||||| + ||||||| objid picked c ======= b -- 1.7.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html