{"thread":{"id":"52114","subject":"conflict markers on recursive strategy with diff3 enabled","startedAt":"2019-10-25T00:15:58Z","lastAt":"2019-10-29T01:32:01Z","messageCount":4,"participants":["Edmundo Carmona Antoranz","Elijah Newren","Philip Oakley","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"384820","messageId":"CAOc6etaQvNChdRZ70xsYQxqtgmZVxaKV9K7_zZeET3JuQ4HEXg@mail.gmail.com","threadId":"52114","inReplyTo":null,"subject":"conflict markers on recursive strategy with diff3 enabled","fromName":"Edmundo Carmona Antoranz","fromEmail":"eantoranz@gmail.com","sentAt":"2019-10-25T00:13:57Z","receivedAt":"2019-10-25T00:15:58Z","isPatch":false,"sender":{"key":"eantoranz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1491018?v=4"},"body":"Hi!\n\nI'm sitting down hunting for conflict examples and while looking\nthrough past conflicts in git I found one that has a format that I\nhadn't seen before. When merging the parents of 8b79343fc0 we get\nthis:\n\n<<<<<<< HEAD\n\n/*\n* Unlink the .pack and associated extension files.\n* Does not unlink if 'force_delete' is false and the pack-file is\n* marked as \".keep\".\n*/\nextern void unlink_pack_path(const char *pack_name, int force_delete);\n||||||| merged common ancestors\n>>>>>>>>> Temporary merge branch 2\n=======\n>>>>>>> 8b79343fc0^2\n\nThat is with merge.conflictStyle set to diff3. What I would like to\nknow is if the details about how the additional information that is\nnot normally seen on a conflict has to be interpreted (to be read as\n\"the part about the temporary branches\"). I see some explanation about\nit in [1] but when checking inside \"git help merge\" all I see is that\nwhen you are using diff3 you will get the content of the parent but\nthere's more stuff than just that. Is it documented somewhere?\n\nThanks!\n\n[1]https://stackoverflow.com/questions/31392513/git-diff3-conflict-style-temporary-merge-branch\n"},{"id":"385018","messageId":"CABPp-BFWKJGiuRiE71yaLGfaOO3zobg4Hammyr37BZMghyXzgA@mail.gmail.com","threadId":"52114","inReplyTo":"CAOc6etaQvNChdRZ70xsYQxqtgmZVxaKV9K7_zZeET3JuQ4HEXg@mail.gmail.com","subject":"Re: conflict markers on recursive strategy with diff3 enabled","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2019-10-28T21:58:39Z","receivedAt":"2019-10-28T21:58:52Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi Edmundo,\n\nOn Fri, Oct 25, 2019 at 12:19 PM Edmundo Carmona Antoranz\n<eantoranz@gmail.com> wrote:\n>\n> Hi!\n>\n> I'm sitting down hunting for conflict examples and while looking\n> through past conflicts in git I found one that has a format that I\n> hadn't seen before. When merging the parents of 8b79343fc0 we get\n> this:\n>\n> <<<<<<< HEAD\n>\n> /*\n> * Unlink the .pack and associated extension files.\n> * Does not unlink if 'force_delete' is false and the pack-file is\n> * marked as \".keep\".\n> */\n> extern void unlink_pack_path(const char *pack_name, int force_delete);\n> ||||||| merged common ancestors\n> >>>>>>>>> Temporary merge branch 2\n> =======\n> >>>>>>> 8b79343fc0^2\n>\n> That is with merge.conflictStyle set to diff3. What I would like to\n> know is if the details about how the additional information that is\n> not normally seen on a conflict has to be interpreted (to be read as\n> \"the part about the temporary branches\"). I see some explanation about\n> it in [1] but when checking inside \"git help merge\" all I see is that\n> when you are using diff3 you will get the content of the parent but\n> there's more stuff than just that. Is it documented somewhere?\n\nThe \"||||||| merged common ancestors\" section shows the content of the\nmerge base, which itself contained conflict markers.\n\nThe way the merge base can itself have conflict markers is as follows:\nwhen you go to merge your two branches, git finds that there isn't a\nunique merge base for doing the three-way merge.  You, in fact, have\nmore than one merge base.  And so, it first merges those (and if those\ndon't have a unique merge base, then their merge bases must first be\nmerged...and so on -- thus the name of \"recursive\" for the merge\nalgorithm).  When the algorithm runs into conflicts while merging the\nmerge bases, it simply accepts the version of the file with the\nconflict markers as the correct resolution (because it has to pick\nsomething, and that is unlikely to erroneously match the outer\ncontents on either side).\n\nThus when using diff3 conflict style, you can sometimes see nested\nconflict markers.  And technically you can construct weird histories\nwhere you have arbitrarily deeply nested conflict markers as well, but\nit certainly isn't very common.\n\n\nHope that helps,\nElijah\n"},{"id":"385021","messageId":"e26d24b2-6fca-8546-f2b3-bf4660db8184@iee.email","threadId":"52114","inReplyTo":"CAOc6etaQvNChdRZ70xsYQxqtgmZVxaKV9K7_zZeET3JuQ4HEXg@mail.gmail.com","subject":"Re: conflict markers on recursive strategy with diff3 enabled","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2019-10-28T22:13:02Z","receivedAt":"2019-10-28T22:13:05Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"Hi Edmundo ,\n\nOn 25/10/2019 01:13, Edmundo Carmona Antoranz wrote:\n> Hi!\n>\n> I'm sitting down hunting for conflict examples and while looking\n> through past conflicts in git I found one that has a format that I\n> hadn't seen before. When merging the parents of 8b79343fc0 we get\n> this:\n>\n> <<<<<<< HEAD\n>\n> /*\n> * Unlink the .pack and associated extension files.\n> * Does not unlink if 'force_delete' is false and the pack-file is\n> * marked as \".keep\".\n> */\n> extern void unlink_pack_path(const char *pack_name, int force_delete);\n> ||||||| merged common ancestors\n>>>>>>>>>> Temporary merge branch 2\n> =======\n>>>>>>>> 8b79343fc0^2\n> That is with merge.conflictStyle set to diff3. What I would like to\n> know is if the details about how the additional information that is\n> not normally seen on a conflict has to be interpreted (to be read as\n> \"the part about the temporary branches\").\n- \"Temporary merge branch\"\n\nI believe this happens when no merge-base is found between the two lines \nof development that are being merged, so a fake merge-base is created to \nallow the regular 3-way merge to occur.\n\nIt may be described in the technical section of the Documentation.\n\n>   I see some explanation about\n> it in [1] but when checking inside \"git help merge\" all I see is that\n> when you are using diff3 you will get the content of the parent but\n> there's more stuff than just that. Is it documented somewhere?\n>\n> Thanks!\n>\n> [1]https://stackoverflow.com/questions/31392513/git-diff3-conflict-style-temporary-merge-branch\n\nPhilip\n"},{"id":"385030","messageId":"xmqqlft48hgz.fsf@gitster-ct.c.googlers.com","threadId":"52114","inReplyTo":"e26d24b2-6fca-8546-f2b3-bf4660db8184@iee.email","subject":"Re: conflict markers on recursive strategy with diff3 enabled","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-10-29T01:31:56Z","receivedAt":"2019-10-29T01:32:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Philip Oakley <philipoakley@iee.email> writes:\n\n> I believe this happens when no merge-base is found between the two\n> lines of development that are being merged, so a fake merge-base is\n> created to allow the regular 3-way merge to occur.\n\ns/no merge-base is/more than one merge-base are/; then a synthetic\nmerge base is computed in order to perform the merge the end-user\nrequested first, and the computation of that synthetic merge base\nmay involve merge conflicts.  After that, the merge logic pretends\nthat the two versions being merged both derived from such a common\nancestor version _with_ conflict markers in it, and may conflict\nwith each other around that existing (inner) conflict markers to\nleave a rather messy result.  It is particularly bad when both\nbranches did the same thing only on one side the inner merge\nconflicted but not on the other side---one side of inner conflict\nmarker (say \"<<<<<<<<\") may disappear when the merged branches made\nthe same change (so \"both side changed identically, resolve to their\nsame result\" 3-way merge rule would apply) and around that area the\nresult will not have the conflict marker from the inner merge, and\nthe other side will say \"one side made into this shape, the other\nside made into that shape, from this common ancestor version\" in the\ndiff3 format, which would mean that we would see conflict marker\nlines from the inner merge between \"|||||\" and \"=====\" lines in the\nouter merge (i.e. the common ancestor version).  The conflict\nmarkers of the inner merge are longer than those of the outermost\nmerge, so you could sift them by careful eyeballing, but it is\nrather hard to read.\n\n"}]}