{"thread":{"id":"22920","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","startedAt":"2010-03-05T22:19:50Z","lastAt":"2010-03-15T13:18:32Z","messageCount":23,"participants":["Jonathan Nieder","Junio C Hamano","Stefan Monnier","Bert Wesarg"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"136222","messageId":"20100305221950.GB5083@progeny.tock","threadId":"22920","inReplyTo":"20100305215253.364.63583.reportbug@localhost","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-05T22:19:50Z","receivedAt":"2010-03-05T22:19:50Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi gitsters,\n\nStefan Monnier wrote [1]:\n\n> I can't live without conflictstyle=diff3m and I'm very happy it exists.\n> But it has a little problem: it uses \"|||||||\\n\" as a separator for the\n> ancestor version of the text, whereas diff3 uses \"||||||| <ancestorname>\\n\".\n> The difference is harmless for a human (tho the <ancestorname> can sometimes\n> be useful, assuming it's meaningful), but it makes some tools fail to\n> recognize the conflict markers properly.\n> So please add a \" BASE\" or \" ANCESTOR\" after the \"|||||||\".\n\nNo opinion on this myself.  I’d be interested to hear from xdiff people\nwhether it should be easy to add the ancestor name to the output.\n\n>\n> \tStefan\n>\n> PS: I intended to report this bug directly to the Git bug-tracker, but I was\n> simply unable to find it.  I know I'm sometimes dense, but I did make an\n> honest effort to look for it.\n\nSee http://thread.gmane.org/gmane.comp.version-control.git/136500\n\nShort answer: the usual method is to report bugs to the list, preferably\nwith a patch for t/ or even better, a fix. ;-)\n\nJonathan\n\n[1] http://bugs.debian.org/572720\n"},{"id":"136224","messageId":"7vpr3itn89.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"20100305221950.GB5083@progeny.tock","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-05T22:31:02Z","receivedAt":"2010-03-05T22:31:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n>> I can't live without conflictstyle=diff3m and I'm very happy it exists.\n>> But it has a little problem: it uses \"|||||||\\n\" as a separator for the\n>> ancestor version of the text, whereas diff3 uses \"||||||| <ancestorname>\\n\".\n>> The difference is harmless for a human (tho the <ancestorname> can sometimes\n>> be useful, assuming it's meaningful), but it makes some tools fail to\n>> recognize the conflict markers properly.\n>> So please add a \" BASE\" or \" ANCESTOR\" after the \"|||||||\".\n>\n> No opinion on this myself.  I’d be interested to hear from xdiff people\n> whether it should be easy to add the ancestor name to the output.\n\nI don't think there was any xdiff people involved in this area.\n\nI suspect that our tools actually rely on the common ancestor markers not\nhaving any extra cruft after them, so it would be introducing a bug if you\nchange this output without changing the places that read them (I know\nabout \"rerere\", but there may be others).\n"},{"id":"299173","messageId":"36ca99e91003060457s6417f800uc7a3e126ee6b7d6f@mail.gmail.com","threadId":"22920","inReplyTo":"7vpr3itn89.fsf@alter.siamese.dyndns.org","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-03-06T12:57:32Z","receivedAt":"2010-03-06T12:57:32Z","isPatch":false,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"On Fri, Mar 5, 2010 at 23:31, Junio C Hamano <gitster@pobox.com> wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n>\n>>> I can't live without conflictstyle=diff3m and I'm very happy it exists.\n>>> But it has a little problem: it uses \"|||||||\\n\" as a separator for the\n>>> ancestor version of the text, whereas diff3 uses \"||||||| <ancestorname>\\n\".\n>>> The difference is harmless for a human (tho the <ancestorname> can sometimes\n>>> be useful, assuming it's meaningful), but it makes some tools fail to\n>>> recognize the conflict markers properly.\n>>> So please add a \" BASE\" or \" ANCESTOR\" after the \"|||||||\".\n>>\n>> No opinion on this myself.  I’d be interested to hear from xdiff people\n>> whether it should be easy to add the ancestor name to the output.\n>\n> I don't think there was any xdiff people involved in this area.\n>\n> I suspect that our tools actually rely on the common ancestor markers not\n> having any extra cruft after them, so it would be introducing a bug if you\n> change this output without changing the places that read them (I know\n> about \"rerere\", but there may be others).\n\nrerere needs an isspace() after the specified marker length. So I\nassume it could live with extra cruft after the | marker and a space.\n\nBTW: Am I right, that rerere would need to handle my new conflict style too?\n\nBert\n"},{"id":"136318","messageId":"7vvdd9gtmy.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"36ca99e91003060457s6417f800uc7a3e126ee6b7d6f@mail.gmail.com","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-06T19:03:17Z","receivedAt":"2010-03-06T19:03:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bert Wesarg <bert.wesarg@googlemail.com> writes:\n\n> rerere needs an isspace() after the specified marker length. So I\n> assume it could live with extra cruft after the | marker and a space.\n\nis_cmarker() is called with want_sp = 0 for '=======' and '|||||||', so\nthe current code accepts both \"||||||| rubbish\\n\" and \"|||||||\\n\".\n\nAlso, rerere sanitizes a diff3 style conflict into a merge style conflict\nbefore writing a preimage to rr-cache for later comparison [*1*], so it\nprobably is Ok even if we changed it in a way that it no longer reads the\ncurrent output without \" rubbish\" after the marker.  It appears that it is\nalready prepared to take either form, so we are probably safe here.\n\nBut I didn't check subcommands other than rerere that may read and act on\nthe conflict markers.\n\n> BTW: Am I right, that rerere would need to handle my new conflict style too?\n\nIf we were to change the output, git needs to be prepared to see both the\noutput before and after the change and behave sensibly; it is not limited\nto rerere.\n\nFor the reverse combined diff format, rerere probably needs to be taught\nhow to convert it as merge style conflict before computing the conflict\nidentifier and write it out in the preimage file, I think.\n\n[Footnote]\n\n*1* See 387c9d4 (rerere: understand \"diff3 -m\" style conflicts with the\noriginal, 2008-08-29).\n"},{"id":"136374","messageId":"20100308045454.GA22672@progeny.tock","threadId":"22920","inReplyTo":"7vpr3itn89.fsf@alter.siamese.dyndns.org","subject":"Re: git-core: conflictstyle=diff3 doesn't actually use diff3 compatible format","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-08T04:54:54Z","receivedAt":"2010-03-08T04:54:54Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n\n>> I’d be interested to hear from xdiff people\n>> whether it should be easy to add the ancestor name to the output.\n>\n> I don't think there was any xdiff people involved in this area.\n> \n> I suspect that our tools actually rely on the common ancestor markers not\n> having any extra cruft after them, so it would be introducing a bug if you\n> change this output without changing the places that read them (I know\n> about \"rerere\", but there may be others).\n\nI guess the relevant xdiff person was you. ;-)\n\nThank you for the quick response.  On the xdiff level, it looks like\nall that is needed is to pass the ancestor label as a member of struct\ns_xmparam, and then fill_conflict_hunk() could respect that.  Not\ncomplicated at all.\n\nFor merge_trees() users, the ancestor label could be passed with\nbranch1 and branch2 in struct merge_options.\n\nThat leaves the question of merge_recursive().  With merge_recursive(),\nthere is more than one ancestor, so it is not completely clear what the\ndiff3 merge should do.  Currently it writes something like this:\n\n <<<<<<< HEAD\n Conflict resolution is hard;\n let's go shopping.\n |||||||\n <<<<<<< Temporary merge branch 1\n Who knows whose this is?\n |||||||\n Ancient history.\n =======\n Another intermediate result.\n >>>>>>> Temporary merge branch 2\n =======\n Git makes conflict resolution easy.\n >>>>>>> topic\n\nwhich is hard to read [1].  Probably it would be better to use a consolidated\ncommon ancestor, by cocatenating the internal common ancestors; in this\nsimple case, that would look like this:\n\n <<<<<<< HEAD\n Conflict resolution is hard;\n let's go shopping.\n ||||||||\n Ancient history.\n ========\n Git makes conflict resolution easy.\n >>>>>>>> topic\n\nWhat should be the label of this possibly fictional merge base?\n\nJonathan\n\n[1] For people and for rerere.  See http://bugs.debian.org/569645\n"},{"id":"136798","messageId":"20100315074748.GA28827@progeny.tock","threadId":"22920","inReplyTo":"20100305221950.GB5083@progeny.tock","subject":"[PATCH/RFC 0/10] Add label for common ancestor to conflictstyle=diff3","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:47:48Z","receivedAt":"2010-03-15T07:47:48Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jonathan Nieder wrote:\n> Stefan Monnier wrote [1]:\n\n>> I can't live without conflictstyle=diff3m and I'm very happy it exists.\n>> But it has a little problem: it uses \"|||||||\\n\" as a separator for the\n>> ancestor version of the text, whereas diff3 uses \"||||||| <ancestorname>\\n\".\n>> The difference is harmless for a human (tho the <ancestorname> can sometimes\n>> be useful, assuming it's meaningful), but it makes some tools fail to\n>> recognize the conflict markers properly.\n>> So please add a \" BASE\" or \" ANCESTOR\" after the \"|||||||\".\n>\n> No opinion on this myself.\n\nI changed my mind; it looked like a useful and fun thing to do, so\nhere it is.\n\nThe bad news is that sometimes the labels for the ancestor are kind of\npointless, as in “merged common ancestors” for merge-recursive.  I am\nnot planning to improve this soon.  I’d be thrilled if someone changes\nit to something like “merge of ac76d, 8d7ca9, and 81873”.\n\nThis patch series adds a label for the common ancestor to various\nplaces git outputs conflict hunks:\n\n <<<<<<< ours\n Text from the current branch\n ||||||| original\n Text from the merge base\n =======\n Text from the remote branch\n >>>>>>> theirs\n\nI am hoping this output will be more self explanatory, especially in\ncases where it is not completely obvious to a naïve user what the\ncommon ancestor would be, such as cherry-pick.\n\nThis passes all tests here and I tried to find any untested in-tree\nconsumers of conflict hunks that would be affected to make sure it\nwould be safe.  I would like to see it get some testing on other\nmachines, especially by people using merge tools and other programs\nthat parse conflicts.\n\nThoughts?\nJonathan Nieder (10):\n  xdl_merge(): add optional ancestor label to diff3-style output\n  merge-file --diff3: add a label for ancestor\n  ll_merge(): add ancestor label parameter for diff3-style output\n  checkout --conflict=diff3: add a label for ancestor\n  merge_file(): add comment explaining behavior wrt conflict style\n  merge_trees(): add ancestor label parameter for diff3-style output\n  tests: document format of conflicts from checkout -m\n  checkout -m --conflict=diff3: add a label for ancestor\n  cherry-pick: add a label for ancestor\n  merge-recursive: add a label for ancestor\n\n builtin/checkout.c    |    3 +-\n builtin/merge-file.c  |    1 +\n builtin/revert.c      |    1 +\n ll-merge.c            |   20 ++++++++------\n ll-merge.h            |    2 +-\n merge-file.c          |    8 +++++-\n merge-recursive.c     |   12 ++++++--\n merge-recursive.h     |    1 +\n rerere.c              |    4 +-\n t/t6023-merge-file.sh |    2 +-\n t/t7201-co.sh         |   69 ++++++++++++++++++++++++++++++++++++++++++++----\n xdiff/xdiff.h         |    1 +\n xdiff/xmerge.c        |   16 ++++++++++-\n 13 files changed, 114 insertions(+), 26 deletions(-)\n\n[1] http://bugs.debian.org/572720\n"},{"id":"136799","messageId":"20100315074909.GA8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 01/10] xdl_merge(): add optional ancestor label to diff3-style output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:49:09Z","receivedAt":"2010-03-15T07:49:09Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The ‘git checkout --conflict=diff3’ command can be used to\npresent conflicts hunks including text from the common ancestor:\n\n\t<<<<<<< ours\n\tourside\n\t|||||||\n\toriginal\n\t=======\n\ttheirside\n\t>>>>>>> theirs\n\nThe added information is helpful for resolving merges by hand, and\nmerge tools can usually grok it because it is very similar to the\noutput from diff3 -m.\n\nA subtle change can help more tools to understand the output.  ‘diff3’\nincludes the name of the merge base on the ||||||| line of the output,\nand some tools misparse the conflict hunks without it.  Add a new\nxmp->ancestor parameter to xdl_merge() for use with conflict style\nXDL_MERGE_DIFF3 as a label on the ||||||| line for any conflict hunks.\n\nIf xmp->ancestor is NULL, the output format is unchanged.  ‘git\ncheckout’ and other users within git all use NULL for this parameter,\nso this change only provides unexposed plumbing for a fix: it does not\naffect the outward behavior of git in any way.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n xdiff/xdiff.h  |    1 +\n xdiff/xmerge.c |   16 ++++++++++++++--\n 2 files changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/xdiff/xdiff.h b/xdiff/xdiff.h\nindex 3f6229e..abaf960 100644\n--- a/xdiff/xdiff.h\n+++ b/xdiff/xdiff.h\n@@ -117,6 +117,7 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,\n typedef struct s_xmparam {\n \txpparam_t xpp;\n \tint marker_size;\n+\tconst char *ancestor;\n } xmparam_t;\n \n #define DEFAULT_CONFLICT_MARKER_SIZE 7\ndiff --git a/xdiff/xmerge.c b/xdiff/xmerge.c\nindex 8cbe45e..3a0ae14 100644\n--- a/xdiff/xmerge.c\n+++ b/xdiff/xmerge.c\n@@ -144,11 +144,13 @@ static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int add_nl, char *dest)\n \n static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,\n \t\t\t      xdfenv_t *xe2, const char *name2,\n+\t\t\t      const char *name3,\n \t\t\t      int size, int i, int style,\n \t\t\t      xdmerge_t *m, char *dest, int marker_size)\n {\n \tint marker1_size = (name1 ? strlen(name1) + 1 : 0);\n \tint marker2_size = (name2 ? strlen(name2) + 1 : 0);\n+\tint marker3_size = (name3 ? strlen(name3) + 1 : 0);\n \tint j;\n \n \tif (marker_size <= 0)\n@@ -178,10 +180,15 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,\n \tif (style == XDL_MERGE_DIFF3) {\n \t\t/* Shared preimage */\n \t\tif (!dest) {\n-\t\t\tsize += marker_size + 1;\n+\t\t\tsize += marker_size + 1 + marker3_size;\n \t\t} else {\n \t\t\tfor (j = 0; j < marker_size; j++)\n \t\t\t\tdest[size++] = '|';\n+\t\t\tif (marker3_size) {\n+\t\t\t\tdest[size] = ' ';\n+\t\t\t\tmemcpy(dest + size + 1, name3, marker3_size - 1);\n+\t\t\t\tsize += marker3_size;\n+\t\t\t}\n \t\t\tdest[size++] = '\\n';\n \t\t}\n \t\tsize += xdl_orig_copy(xe1, m->i0, m->chg0, 1,\n@@ -216,6 +223,7 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,\n \n static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,\n \t\t\t\t xdfenv_t *xe2, const char *name2,\n+\t\t\t\t const char *ancestor_name,\n \t\t\t\t int favor,\n \t\t\t\t xdmerge_t *m, char *dest, int style,\n \t\t\t\t int marker_size)\n@@ -228,6 +236,7 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,\n \n \t\tif (m->mode == 0)\n \t\t\tsize = fill_conflict_hunk(xe1, name1, xe2, name2,\n+\t\t\t\t\t\t  ancestor_name,\n \t\t\t\t\t\t  size, i, style, m, dest,\n \t\t\t\t\t\t  marker_size);\n \t\telse if (m->mode == 1)\n@@ -397,6 +406,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,\n \t\tint flags, xmparam_t const *xmp, mmbuffer_t *result) {\n \txdmerge_t *changes, *c;\n \txpparam_t const *xpp = &xmp->xpp;\n+\tconst char * const ancestor_name = xmp->ancestor;\n \tint i0, i1, i2, chg0, chg1, chg2;\n \tint level = flags & XDL_MERGE_LEVEL_MASK;\n \tint style = flags & XDL_MERGE_STYLE_MASK;\n@@ -534,6 +544,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,\n \tif (result) {\n \t\tint marker_size = xmp->marker_size;\n \t\tint size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,\n+\t\t\t\t\t\t ancestor_name,\n \t\t\t\t\t\t favor, changes, NULL, style,\n \t\t\t\t\t\t marker_size);\n \t\tresult->ptr = xdl_malloc(size);\n@@ -542,7 +553,8 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,\n \t\t\treturn -1;\n \t\t}\n \t\tresult->size = size;\n-\t\txdl_fill_merge_buffer(xe1, name1, xe2, name2, favor, changes,\n+\t\txdl_fill_merge_buffer(xe1, name1, xe2, name2,\n+\t\t\t\t      ancestor_name, favor, changes,\n \t\t\t\t      result->ptr, style, marker_size);\n \t}\n \treturn xdl_cleanup_merge(changes);\n-- \n1.7.0\n"},{"id":"136800","messageId":"20100315075121.GB8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 02/10] merge-file --diff3: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:51:21Z","receivedAt":"2010-03-15T07:51:21Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git merge-file --diff3 can be used to present conflicts hunks\nincluding text from the common ancestor.\n\nThe added information can be very helpful for resolving a merge by\nhand, and merge tools can usually grok it because it looks like output\nfrom diff3 -m.  Unfortunately, some cannot reportedly, because ‘diff3’\nincludes a label for the merge base on the ||||||| line and some tools\ncannot parse conflict hunks without such a label.  So write the\nbase-name as passed in a -L option (or the name of the “ancestor” file\nby default) on that line.\n\ngit rerere will not have trouble parsing this output, since instead of\nlooking for a newline, it looks for whitespace after the |||||||\nmarker.  No other code in git tries to parse conflict hunks.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThis requires a slight change when merging with next.  A test was\nadded to t6023-merge-file.sh for the longer conflict markers;\nthe corresponding line in that new test needs to have new5.txt\nadded as well.\n\n builtin/merge-file.c  |    1 +\n t/t6023-merge-file.sh |    2 +-\n 2 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/merge-file.c b/builtin/merge-file.c\nindex 1e70073..0ff8b03 100644\n--- a/builtin/merge-file.c\n+++ b/builtin/merge-file.c\n@@ -72,6 +72,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t\t\t\t\targv[i]);\n \t}\n \n+\txmp.ancestor = names[1];\n \tret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],\n \t\t\t&xmp, XDL_MERGE_FLAGS(level, style, favor), &result);\n \ndiff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh\nindex d605024..16c3c69 100755\n--- a/t/t6023-merge-file.sh\n+++ b/t/t6023-merge-file.sh\n@@ -181,7 +181,7 @@ et nihil mihi deerit;\n \n In loco pascuae ibi me collocavit;\n super aquam refectionis educavit me.\n-|||||||\n+||||||| new5.txt\n et nihil mihi deerit.\n In loco pascuae ibi me collocavit,\n super aquam refectionis educavit me;\n-- \n1.7.0\n"},{"id":"136801","messageId":"20100315075237.GC8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 03/10] ll_merge(): add ancestor label parameter for diff3-style output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:52:37Z","receivedAt":"2010-03-15T07:52:37Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Various commands using the ll_merge() function present conflict hunks\nin output something like what ‘diff3 -m’ produces if the\nmerge.conflictstyle configuration option is set to diff3.\n\nUnfortunately, the format is not fully compatible yet.  ‘diff3’\nincludes the name of the merge base on the ||||||| line of the output,\nand some tools are reported to misparse the conflict hunks without it.\n\nAdd a new ancestor_label parameter to ll_merge() to give callers the\npower to rectify this situation.  Let all callers pass NULL as that\nparameter for now to avoid distracting changes in behavior when\ntesting this interface change.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nA change to unexposed plumbing only.\n\n builtin/checkout.c |    2 +-\n ll-merge.c         |   20 +++++++++++---------\n ll-merge.h         |    2 +-\n merge-file.c       |    2 +-\n merge-recursive.c  |    2 +-\n rerere.c           |    4 ++--\n 6 files changed, 17 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex acefaaf..d67f809 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -149,7 +149,7 @@ static int checkout_merged(int pos, struct checkout *state)\n \tread_mmblob(&ours, active_cache[pos+1]->sha1);\n \tread_mmblob(&theirs, active_cache[pos+2]->sha1);\n \n-\tstatus = ll_merge(&result_buf, path, &ancestor,\n+\tstatus = ll_merge(&result_buf, path, &ancestor, NULL,\n \t\t\t  &ours, \"ours\", &theirs, \"theirs\", 0);\n \tfree(ancestor.ptr);\n \tfree(ours.ptr);\ndiff --git a/ll-merge.c b/ll-merge.c\nindex 4c7f11b..68fa1e6 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -15,7 +15,7 @@ struct ll_merge_driver;\n typedef int (*ll_merge_fn)(const struct ll_merge_driver *,\n \t\t\t   mmbuffer_t *result,\n \t\t\t   const char *path,\n-\t\t\t   mmfile_t *orig,\n+\t\t\t   mmfile_t *orig, const char *orig_name,\n \t\t\t   mmfile_t *src1, const char *name1,\n \t\t\t   mmfile_t *src2, const char *name2,\n \t\t\t   int flag,\n@@ -36,7 +36,7 @@ struct ll_merge_driver {\n static int ll_binary_merge(const struct ll_merge_driver *drv_unused,\n \t\t\t   mmbuffer_t *result,\n \t\t\t   const char *path_unused,\n-\t\t\t   mmfile_t *orig,\n+\t\t\t   mmfile_t *orig, const char *orig_name,\n \t\t\t   mmfile_t *src1, const char *name1,\n \t\t\t   mmfile_t *src2, const char *name2,\n \t\t\t   int flag, int marker_size)\n@@ -57,7 +57,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,\n static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n \t\t\tmmbuffer_t *result,\n \t\t\tconst char *path,\n-\t\t\tmmfile_t *orig,\n+\t\t\tmmfile_t *orig, const char *orig_name,\n \t\t\tmmfile_t *src1, const char *name1,\n \t\t\tmmfile_t *src2, const char *name2,\n \t\t\tint flag, int marker_size)\n@@ -73,12 +73,14 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n \t\t\tpath, name1, name2);\n \t\treturn ll_binary_merge(drv_unused, result,\n \t\t\t\t       path,\n-\t\t\t\t       orig, src1, name1,\n+\t\t\t\t       orig, orig_name,\n+\t\t\t\t       src1, name1,\n \t\t\t\t       src2, name2,\n \t\t\t\t       flag, marker_size);\n \t}\n \n \tmemset(&xmp, 0, sizeof(xmp));\n+\txmp.ancestor = orig_name;\n \tif (git_xmerge_style >= 0)\n \t\tstyle = git_xmerge_style;\n \tif (marker_size > 0)\n@@ -93,7 +95,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n static int ll_union_merge(const struct ll_merge_driver *drv_unused,\n \t\t\t  mmbuffer_t *result,\n \t\t\t  const char *path_unused,\n-\t\t\t  mmfile_t *orig,\n+\t\t\t  mmfile_t *orig, const char *orig_name,\n \t\t\t  mmfile_t *src1, const char *name1,\n \t\t\t  mmfile_t *src2, const char *name2,\n \t\t\t  int flag, int marker_size)\n@@ -106,7 +108,7 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,\n \tsaved_style = git_xmerge_style;\n \tgit_xmerge_style = 0;\n \tstatus = ll_xdl_merge(drv_unused, result, path_unused,\n-\t\t\t      orig, src1, NULL, src2, NULL,\n+\t\t\t      orig, orig_name, src1, NULL, src2, NULL,\n \t\t\t      flag, marker_size);\n \tgit_xmerge_style = saved_style;\n \tif (status <= 0)\n@@ -165,7 +167,7 @@ static void create_temp(mmfile_t *src, char *path)\n static int ll_ext_merge(const struct ll_merge_driver *fn,\n \t\t\tmmbuffer_t *result,\n \t\t\tconst char *path,\n-\t\t\tmmfile_t *orig,\n+\t\t\tmmfile_t *orig, const char *orig_name,\n \t\t\tmmfile_t *src1, const char *name1,\n \t\t\tmmfile_t *src2, const char *name2,\n \t\t\tint flag, int marker_size)\n@@ -356,7 +358,7 @@ static int git_path_check_merge(const char *path, struct git_attr_check check[2]\n \n int ll_merge(mmbuffer_t *result_buf,\n \t     const char *path,\n-\t     mmfile_t *ancestor,\n+\t     mmfile_t *ancestor, const char *ancestor_label,\n \t     mmfile_t *ours, const char *our_label,\n \t     mmfile_t *theirs, const char *their_label,\n \t     int flag)\n@@ -378,7 +380,7 @@ int ll_merge(mmbuffer_t *result_buf,\n \tdriver = find_ll_merge_driver(ll_driver_name);\n \tif (virtual_ancestor && driver->recursive)\n \t\tdriver = find_ll_merge_driver(driver->recursive);\n-\treturn driver->fn(driver, result_buf, path, ancestor,\n+\treturn driver->fn(driver, result_buf, path, ancestor, ancestor_label,\n \t\t\t  ours, our_label, theirs, their_label,\n \t\t\t  flag, marker_size);\n }\ndiff --git a/ll-merge.h b/ll-merge.h\nindex 5788922..57754cc 100644\n--- a/ll-merge.h\n+++ b/ll-merge.h\n@@ -7,7 +7,7 @@\n \n int ll_merge(mmbuffer_t *result_buf,\n \t     const char *path,\n-\t     mmfile_t *ancestor,\n+\t     mmfile_t *ancestor, const char *ancestor_label,\n \t     mmfile_t *ours, const char *our_label,\n \t     mmfile_t *theirs, const char *their_label,\n \t     int flag);\ndiff --git a/merge-file.c b/merge-file.c\nindex fd34d76..07cc0c9 100644\n--- a/merge-file.c\n+++ b/merge-file.c\n@@ -30,7 +30,7 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our\n \tint merge_status;\n \tmmbuffer_t res;\n \n-\tmerge_status = ll_merge(&res, path, base,\n+\tmerge_status = ll_merge(&res, path, base, NULL,\n \t\t\t\tour, \".our\", their, \".their\", 0);\n \tif (merge_status < 0)\n \t\treturn NULL;\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 195ebf9..3b2cc9d 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -640,7 +640,7 @@ static int merge_3way(struct merge_options *o,\n \tread_mmblob(&src1, a->sha1);\n \tread_mmblob(&src2, b->sha1);\n \n-\tmerge_status = ll_merge(result_buf, a->path, &orig,\n+\tmerge_status = ll_merge(result_buf, a->path, &orig, NULL,\n \t\t\t\t&src1, name1, &src2, name2,\n \t\t\t\t(!!o->call_depth) | (favor << 1));\n \ndiff --git a/rerere.c b/rerere.c\nindex a59f74f..f221bed 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -319,7 +319,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu\n \t\tif (!mmfile[i].ptr && !mmfile[i].size)\n \t\t\tmmfile[i].ptr = xstrdup(\"\");\n \t}\n-\tll_merge(&result, path, &mmfile[0],\n+\tll_merge(&result, path, &mmfile[0], NULL,\n \t\t &mmfile[1], \"ours\",\n \t\t &mmfile[2], \"theirs\", 0);\n \tfor (i = 0; i < 3; i++)\n@@ -376,7 +376,7 @@ static int merge(const char *name, const char *path)\n \t\tret = 1;\n \t\tgoto out;\n \t}\n-\tret = ll_merge(&result, path, &base, &cur, \"\", &other, \"\", 0);\n+\tret = ll_merge(&result, path, &base, NULL, &cur, \"\", &other, \"\", 0);\n \tif (!ret) {\n \t\tFILE *f = fopen(path, \"w\");\n \t\tif (!f)\n-- \n1.7.0\n"},{"id":"136802","messageId":"20100315075509.GD8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 04/10] checkout --conflict=diff3: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:55:09Z","receivedAt":"2010-03-15T07:55:09Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git checkout --conflict=diff3 can be used to present conflicts hunks\nincluding text from the common ancestor:\n\n\t<<<<<<< ours\n\tourside\n\t|||||||\n\toriginal\n\t=======\n\ttheirside\n\t>>>>>>> theirs\n\nThe added information can be very helpful for resolving a merge by\nhand, and merge tools can usually understand it without trouble\nbecause it looks like output from ‘diff3 -m’.\n\nUnfortunately, not all can: ‘diff3’ includes a label for the merge\nbase on the ||||||| line and it seems some tools cannot parse conflict\nhunks without such a label.  Humans could use help in interpreting the\noutput, too.  So mark the start of the text from the common ancestor\nwith the label “||||||| original”.\n\ngit rerere will not have trouble parsing this output, since instead of\nlooking for a newline, it looks for whitespace after the |||||||\nmarker.  No other code in git tries to parse conflict hunks.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nSince “original” a good name for the common ancestor?  I also\nconsidered “base” and “ancestor”; the latter is too jargon-y for my\ntaste, but “base” seems all right.\n\n builtin/checkout.c |    2 +-\n t/t7201-co.sh      |    4 ++--\n 2 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex d67f809..c60c3e0 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -149,7 +149,7 @@ static int checkout_merged(int pos, struct checkout *state)\n \tread_mmblob(&ours, active_cache[pos+1]->sha1);\n \tread_mmblob(&theirs, active_cache[pos+2]->sha1);\n \n-\tstatus = ll_merge(&result_buf, path, &ancestor, NULL,\n+\tstatus = ll_merge(&result_buf, path, &ancestor, \"original\",\n \t\t\t  &ours, \"ours\", &theirs, \"theirs\", 0);\n \tfree(ancestor.ptr);\n \tfree(ours.ptr);\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex d20ed61..ebfa5ca 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -481,7 +481,7 @@ test_expect_success 'checkout with --merge, in diff3 -m style' '\n \t(\n \t\techo \"<<<<<<< ours\"\n \t\techo ourside\n-\t\techo \"|||||||\"\n+\t\techo \"||||||| original\"\n \t\techo original\n \t\techo \"=======\"\n \t\techo theirside\n@@ -525,7 +525,7 @@ test_expect_success 'checkout --conflict=diff3' '\n \t(\n \t\techo \"<<<<<<< ours\"\n \t\techo ourside\n-\t\techo \"|||||||\"\n+\t\techo \"||||||| original\"\n \t\techo original\n \t\techo \"=======\"\n \t\techo theirside\n-- \n1.7.0\n"},{"id":"136806","messageId":"20100315075637.GE8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 05/10] merge_file(): add comment explaining behavior wrt conflict style","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T07:56:37Z","receivedAt":"2010-03-15T07:56:37Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The merge_file() function is a helper for ‘git read-tree’, which does\nnot respect the merge.conflictstyle option, so there is no need to\nworry about its ancestor_name parameter for ll_merge().  Add a comment\nto this effect.\n\nSigned-off-by: Jonathan Nieder <jrnieder@mgila.com>\n---\nThere are more non-changes (e.g., in builtin/merge-tree.c), but none\nof them seemed nonobvious like this one.\n\n merge-file.c |    6 ++++++\n 1 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/merge-file.c b/merge-file.c\nindex 07cc0c9..c336c93 100644\n--- a/merge-file.c\n+++ b/merge-file.c\n@@ -30,6 +30,12 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our\n \tint merge_status;\n \tmmbuffer_t res;\n \n+\t/*\n+\t * This function is only used by cmd_merge_tree, which\n+\t * does not respect the merge.conflictstyle option.\n+\t * There is no need to worry about a label for the\n+\t * common ancestor.\n+\t */\n \tmerge_status = ll_merge(&res, path, base, NULL,\n \t\t\t\tour, \".our\", their, \".their\", 0);\n \tif (merge_status < 0)\n-- \n1.7.0\n"},{"id":"136803","messageId":"20100315080032.GF8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 06/10] merge_trees(): add ancestor label parameter for diff3-style output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:00:32Z","receivedAt":"2010-03-15T08:00:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Commands using the merge_trees() machinery will present conflict hunks\nin output something like what ‘diff3 -m’ produces if the\nmerge.conflictstyle configuration option is set to diff3.\n\nUnfortunately, the format is not fully compatible yet.  ‘diff3’\nincludes the name of the merge base on the ||||||| line of the output,\nand tools can misparse the conflict hunks without it.  Add a new\no->ancestor parameter to merge_trees() for use as a label for the\nancestor in conflict hunks to give callers the power to rectify this\nsituation.\n\nIf o->ancestor is NULL, the output format is as before.  All callers\npass NULL, so this patch does not affect the outward behavior of git.\n\nIf o->ancestor is non-NULL and both branches renamed the base file\nto the same name, that name is included in the conflict hunk labels.\nEven if o->ancestor is NULL I think this would be a good change, but\nthis patch only does it in the non-NULL case to ensure the output\nformat does not change where it might matter.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nAnother no-op.\n\n merge-recursive.c |   11 ++++++++---\n merge-recursive.h |    1 +\n 2 files changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 3b2cc9d..017cafd 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -608,7 +608,7 @@ static int merge_3way(struct merge_options *o,\n \t\t      const char *branch2)\n {\n \tmmfile_t orig, src1, src2;\n-\tchar *name1, *name2;\n+\tchar *base_name, *name1, *name2;\n \tint merge_status;\n \tint favor;\n \n@@ -628,10 +628,15 @@ static int merge_3way(struct merge_options *o,\n \t\t}\n \t}\n \n-\tif (strcmp(a->path, b->path)) {\n+\tif (strcmp(a->path, b->path) ||\n+\t    (o->ancestor != NULL && strcmp(a->path, one->path) != 0)) {\n+\t\tbase_name = o->ancestor == NULL ? NULL :\n+\t\t\txstrdup(mkpath(\"%s:%s\", o->ancestor, one->path));\n \t\tname1 = xstrdup(mkpath(\"%s:%s\", branch1, a->path));\n \t\tname2 = xstrdup(mkpath(\"%s:%s\", branch2, b->path));\n \t} else {\n+\t\tbase_name = o->ancestor == NULL ? NULL :\n+\t\t\txstrdup(mkpath(\"%s\", o->ancestor));\n \t\tname1 = xstrdup(mkpath(\"%s\", branch1));\n \t\tname2 = xstrdup(mkpath(\"%s\", branch2));\n \t}\n@@ -640,7 +645,7 @@ static int merge_3way(struct merge_options *o,\n \tread_mmblob(&src1, a->sha1);\n \tread_mmblob(&src2, b->sha1);\n \n-\tmerge_status = ll_merge(result_buf, a->path, &orig, NULL,\n+\tmerge_status = ll_merge(result_buf, a->path, &orig, base_name,\n \t\t\t\t&src1, name1, &src2, name2,\n \t\t\t\t(!!o->call_depth) | (favor << 1));\n \ndiff --git a/merge-recursive.h b/merge-recursive.h\nindex be8410a..d1192f5 100644\n--- a/merge-recursive.h\n+++ b/merge-recursive.h\n@@ -4,6 +4,7 @@\n #include \"string-list.h\"\n \n struct merge_options {\n+\tconst char *ancestor;\n \tconst char *branch1;\n \tconst char *branch2;\n \tenum {\n-- \n1.7.0\n"},{"id":"136804","messageId":"20100315080058.GG8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 07/10] tests: document format of conflicts from checkout -m","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:00:58Z","receivedAt":"2010-03-15T08:00:58Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"We are about to change the format of the conflict hunks that ‘checkout\n--merge’ writes.  Add tests checking the current behavior first.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7201-co.sh |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 61 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex ebfa5ca..970a460 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -11,10 +11,12 @@ Test switching across them.\n   ! [master] Initial A one, A two\n    * [renamer] Renamer R one->uno, M two\n     ! [side] Side M one, D two, A three\n-  ---\n-    + [side] Side M one, D two, A three\n-   *  [renamer] Renamer R one->uno, M two\n-  +*+ [master] Initial A one, A two\n+     ! [simple] Simple D one, M two\n+  ----\n+     + [simple] Simple D one, M two\n+    +  [side] Side M one, D two, A three\n+   *   [renamer] Renamer R one->uno, M two\n+  +*++ [master] Initial A one, A two\n \n '\n \n@@ -52,6 +54,11 @@ test_expect_success setup '\n \tgit update-index --add --remove one two three &&\n \tgit commit -m \"Side M one, D two, A three\" &&\n \n+\tgit checkout -b simple master &&\n+\trm -f one &&\n+\tfill a c e > two &&\n+\tgit commit -a -m \"Simple D one, M two\" &&\n+\n \tgit checkout master\n '\n \n@@ -166,6 +173,56 @@ test_expect_success 'checkout -m with merge conflict' '\n \t! test -s current\n '\n \n+test_expect_success 'format of merge conflict from checkout -m' '\n+\n+\tgit checkout -f master && git clean -f &&\n+\n+\tfill b d > two &&\n+\tgit checkout -m simple &&\n+\n+\tgit ls-files >current &&\n+\tfill same two two two >expect &&\n+\ttest_cmp current expect &&\n+\n+\tcat <<-EOF >expect &&\n+\t<<<<<<< simple\n+\ta\n+\tc\n+\te\n+\t=======\n+\tb\n+\td\n+\t>>>>>>> local\n+\tEOF\n+\ttest_cmp two expect\n+'\n+\n+test_expect_success 'checkout --merge --conflict=diff3 <branch>' '\n+\n+\tgit checkout -f master && git reset --hard && git clean -f &&\n+\n+\tfill b d > two &&\n+\tgit checkout --merge --conflict=diff3 simple &&\n+\n+\tcat <<-EOF >expect &&\n+\t<<<<<<< simple\n+\ta\n+\tc\n+\te\n+\t|||||||\n+\ta\n+\tb\n+\tc\n+\td\n+\te\n+\t=======\n+\tb\n+\td\n+\t>>>>>>> local\n+\tEOF\n+\ttest_cmp two expect\n+'\n+\n test_expect_success 'checkout to detach HEAD (with advice declined)' '\n \n \tgit config advice.detachedHead false &&\n-- \n1.7.0\n"},{"id":"136805","messageId":"20100315080134.GH8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 08/10] checkout -m --conflict=diff3: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:01:34Z","receivedAt":"2010-03-15T08:01:34Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git checkout --merge --conflict=diff3 can be used to present conflicts\nhunks including text from the common ancestor.\n\nThe added information can be very helpful for resolving a merge by\nhand, and many merge tools can usually grok it because it is very\nsimilar to the output from ‘diff3 -m’.\n\nUnfortunately, some tools reportedly cannot parse the conflict hunks\nbecause of a small difference from diff3: diff3 -m includes a label\nfor the merge base on the ||||||| line.  Humans can benefit from a\ncue when learning to interpreting the format, too.  So mark the start\nof the text from the old branch with a label based on the branch’s\nname.\n\ngit rerere will not have trouble parsing this output, since instead of\nlooking for a newline, it looks for whitespace after the |||||||\nmarker.  No other code in git tries to parse conflict hunks.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/checkout.c |    1 +\n t/t7201-co.sh      |    2 +-\n 2 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex c60c3e0..ebc5891 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -439,6 +439,7 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\t\tret = reset_tree(new->commit->tree, opts, 1);\n \t\t\tif (ret)\n \t\t\t\treturn ret;\n+\t\t\to.ancestor = old->name;\n \t\t\to.branch1 = new->name;\n \t\t\to.branch2 = \"local\";\n \t\t\tmerge_trees(&o, new->commit->tree, work,\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex 970a460..ae14b19 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -209,7 +209,7 @@ test_expect_success 'checkout --merge --conflict=diff3 <branch>' '\n \ta\n \tc\n \te\n-\t|||||||\n+\t||||||| master\n \ta\n \tb\n \tc\n-- \n1.7.0\n"},{"id":"136807","messageId":"20100315080501.GI8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 09/10] cherry-pick: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:05:01Z","receivedAt":"2010-03-15T08:05:01Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git cherry-pick and git revert will present conflict hunks in output\nsomething like what ‘diff3 -m’ produces if the merge.conflictstyle\nconfiguration option is set to diff3.\n\nUnfortunately, some tools reportedly cannot parse the conflict hunks\nbecause of a small difference from diff3: diff3 -m includes a label\nfor the merge base on the ||||||| line.  Humans parsing the conflict\nhunks by hand might want to know what the common ancestor represents,\ntoo.  So mark the start of the text from the parent of the commit\nbeing cherrypicked (resp. from the commit being reverted) with the\nlabel \"parent\".\n\nIt would be nicer to use a more informative label, and that might\nhappen in the future.\n\ngit rerere will not have trouble parsing this output, since instead of\nlooking for a newline, it looks for whitespace after the |||||||\nmarker.  No other code in git tries to parse conflict hunks.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nIn the revert case, this gives\n\n <<<<<<< HEAD\n foo\n ||||||| parent\n bar\n =======\n baz\n >>>>>>> ab78c93 \"Make some change we would like to revert\"\n\nThis is a bit misleading, since actually “baz” is from the commit\nto revert’s parent and “bar” is from the commit to revert.\n\nProbably the labels should be switched.  I didn’t do this because\nit is late and it would have been a larger change from the current\nbehavior.\n\nIt also would be nice to suppress the ancestor and do a two-way\nmerge when cherry-picking a root commit.  I haven’t yet looked into\nhow hard this would be.\n\n builtin/revert.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex eff5268..a61dd9a 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -372,6 +372,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \n \tread_cache();\n \tinit_merge_options(&o);\n+\to.ancestor = base ? \"parent\" : \"(empty tree)\";\n \to.branch1 = \"HEAD\";\n \to.branch2 = oneline;\n \n-- \n1.7.0\n"},{"id":"136808","messageId":"20100315080703.GJ8824@progeny.tock","threadId":"22920","inReplyTo":"20100315074748.GA28827@progeny.tock","subject":"[PATCH 10/10] merge-recursive: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:07:04Z","receivedAt":"2010-03-15T08:07:04Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git merge-recursive (and hence git merge) will present conflict hunks\nin output something like what ‘diff3 -m’ produces if the\nmerge.conflictstyle configuration option is set to diff3.\n\nUnfortunately, some tools reportedly cannot parse the conflict hunks\nbecause of a small difference from diff3: diff3 -m includes a label\nfor the merge base on the ||||||| line.  Humans unfamiliar with the\nformat would do a better job with a label, too.  Mark the start of the\ntext from the merge bases with the heading \"||||||| merged common\nancestors\".\n\nIt would be nicer to use a more informative label, and that might\nhappen in the future.\n\ngit rerere does not have trouble parsing this output, since instead of\nlooking for a newline, it looks for whitespace after the |||||||\nmarker.  No other code in git tries to parse conflict hunks.\n\nReported-by: Stefan Monnier <monnier@iro.umontreal.ca>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nI would be interested to know which merge tool chokes on |||||||. ;)\nAs it is, since I haven’t experienced the mechanical misbehavior, I\nam targetting humans.\n\nThat’s the end of the series.  Thanks for reading.\n\nGood night,\nJonathan\n\n merge-recursive.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 017cafd..917397c 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -1347,6 +1347,7 @@ int merge_recursive(struct merge_options *o,\n \tif (!o->call_depth)\n \t\tread_cache();\n \n+\to->ancestor = \"merged common ancestors\";\n \tclean = merge_trees(o, h1->tree, h2->tree, merged_common_ancestors->tree,\n \t\t\t    &mrtree);\n \n-- \n1.7.0\n"},{"id":"136809","messageId":"7vzl2a0zud.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"20100315074909.GA8824@progeny.tock","subject":"Re: [PATCH 01/10] xdl_merge(): add optional ancestor label to diff3-style output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-15T08:10:50Z","receivedAt":"2010-03-15T08:10:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I think this patch itself makes sense, but if you were to add one name to\nxmparam structure, wouldn't it make sense to store all three names in\nthere?\n"},{"id":"136810","messageId":"7vvdcy0zf3.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"20100315075509.GD8824@progeny.tock","subject":"Re: [PATCH 04/10] checkout --conflict=diff3: add a label for ancestor","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-15T08:20:00Z","receivedAt":"2010-03-15T08:20:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> git checkout --conflict=diff3 can be used to present conflicts hunks\n> including text from the common ancestor:\n>\n> \t<<<<<<< ours\n> \tourside\n> \t|||||||\n> \toriginal\n> \t=======\n> \ttheirside\n> \t>>>>>>> theirs\n>\n> The added information can be very helpful for resolving a merge by\n> hand, and merge tools can usually understand it without trouble\n> because it looks like output from ‘diff3 -m’.\n>\n> Unfortunately, not all can: ‘diff3’ includes a label for the merge\n> base on the ||||||| line and it seems some tools cannot parse conflict\n> hunks without such a label.  Humans could use help in interpreting the\n> output, too.  So mark the start of the text from the common ancestor\n> with the label “||||||| original”.\n>\n> git rerere will not have trouble parsing this output, since instead of\n> looking for a newline, it looks for whitespace after the |||||||\n> marker.\n\nMissing:\n\n    \"... and adding the extra label will not affect the computed the conflict\n    identifier, so existing rerere database will not be invalidated with this\n    change either\".\n\nI didn't verified the above claim, but if it does not hold true, then we\nneed to think the transition strategy.  I don't expect a problem, though.\n\n> Reported-by: Stefan Monnier <monnier@iro.umontreal.ca>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n\nThis \"Reported\" feels very odd for a feature enhancement (\"Requested\"\nwould be more appropriate) not a bugfix.\n\n> ---\n> Since “original” a good name for the common ancestor?  I also\n> considered “base” and “ancestor”; the latter is too jargon-y for my\n> taste, but “base” seems all right.\n\nYeah, base sounds good.  Even though at the lowest level, a merge is a\nmerge between two equals, people tend to think of the contents of their\nown side \"original\" (vs the merge outcome \"result\").\n"},{"id":"136812","messageId":"7vr5nm0yzb.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"20100315080703.GJ8824@progeny.tock","subject":"Re: [PATCH 10/10] merge-recursive: add a label for ancestor","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-15T08:29:28Z","receivedAt":"2010-03-15T08:29:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> I would be interested to know which merge tool chokes on |||||||. ;)\n> As it is, since I haven’t experienced the mechanical misbehavior, I\n> am targetting humans.\n\nEven if there weren't any broken tools, I think targetting humans is a\ngood thing to do, as long as we don't break ourselves (including old\nrerere database).\n\n> That’s the end of the series.  Thanks for reading.\n\nThanks for writing.  I think this is generally a good thing to have,\nand from my cursory look I didn't see anything glaringly wrong except for\nthe one I already commented on the first patch.\n"},{"id":"136813","messageId":"20100315083238.GA10068@progeny.tock","threadId":"22920","inReplyTo":"7vvdcy0zf3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 04/10] checkout --conflict=diff3: add a label for ancestor","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:32:38Z","receivedAt":"2010-03-15T08:32:38Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n\n>> git rerere will not have trouble parsing this output, since instead of\n>> looking for a newline, it looks for whitespace after the |||||||\n>> marker.\n>\n> Missing:\n> \n>     \"... and adding the extra label will not affect the computed the conflict\n>     identifier, so existing rerere database will not be invalidated with this\n>     change either\".\n> \n> I didn't verified the above claim, but if it does not hold true, then we\n> need to think the transition strategy.  I don't expect a problem, though.\n\nIt holds.  handle_path() in rerere.c actually recreates the conflict hunk\nafter parsing it:\n\n\trerere_io_putconflict('<', marker_size, io);\n\trerere_io_putmem(one.buf, one.len, io);\n\trerere_io_putconflict('=', marker_size, io);\n\trerere_io_putmem(two.buf, two.len, io);\n\trerere_io_putconflict('>', marker_size, io);\n\nThis is a piece of defensive programing by Dscho that has lasted since\nrerere was first made builtin.  It shelters rerere from changes in the\nformat of the conflict markers.\n\n>> Reported-by: Stefan Monnier <monnier@iro.umontreal.ca>\n>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n>\n> This \"Reported\" feels very odd for a feature enhancement (\"Requested\"\n> would be more appropriate) not a bugfix.\n\nMakes sense, thanks.\n\n>> ---\n>> Since “original” a good name for the common ancestor?  I also\n>> considered “base” and “ancestor”; the latter is too jargon-y for my\n>> taste, but “base” seems all right.\n>\n> Yeah, base sounds good.  Even though at the lowest level, a merge is a\n> merge between two equals, people tend to think of the contents of their\n> own side \"original\" (vs the merge outcome \"result\").\n\nSound good.  “base” it is, then.\n\nThanks,\nJonathan\n"},{"id":"136814","messageId":"20100315083521.GB10068@progeny.tock","threadId":"22920","inReplyTo":"7vzl2a0zud.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 01/10] xdl_merge(): add optional ancestor label to diff3-style output","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-03-15T08:35:21Z","receivedAt":"2010-03-15T08:35:21Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n> I think this patch itself makes sense, but if you were to add one name to\n> xmparam structure, wouldn't it make sense to store all three names in\n> there?\n\nGood idea.  Will do.\n\nCiao,\nJonathan\n"},{"id":"136815","messageId":"7v7hpeyo8x.fsf@alter.siamese.dyndns.org","threadId":"22920","inReplyTo":"20100315083521.GB10068@progeny.tock","subject":"Re: [PATCH 01/10] xdl_merge(): add optional ancestor label to diff3-style output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-15T08:37:18Z","receivedAt":"2010-03-15T08:37:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>\n>> I think this patch itself makes sense, but if you were to add one name to\n>> xmparam structure, wouldn't it make sense to store all three names in\n>> there?\n>\n> Good idea.  Will do.\n\nThat would also mean that existing name1 and name2 arguments many\nfunctions (starting from xdl_merge()) have will go.\n"},{"id":"136831","messageId":"jwvd3z5d8u0.fsf-monnier+inbox@gnu.org","threadId":"22920","inReplyTo":"20100315080703.GJ8824@progeny.tock","subject":"Re: [PATCH 10/10] merge-recursive: add a label for ancestor","fromName":"Stefan Monnier","fromEmail":"monnier@iro.umontreal.ca","sentAt":"2010-03-15T13:18:32Z","receivedAt":"2010-03-15T13:18:32Z","isPatch":true,"sender":{"key":"monnier@iro.umontreal.ca","avatar":null},"body":"> I would be interested to know which merge tool chokes on |||||||. ;)\n\nIn my case, it was smerge-mode.el (a minor mode included in Emacs since\nEmacs-22, which highlights such conflicts and tries to help you resolve\nthem).\n\n\n        Stefan\n\n\nPS: As you may have guessed, I'm the primary author of this\nEmacs package.\n"}]}