{"thread":{"id":"56828","subject":"Possible merge bug","startedAt":"2021-11-02T06:26:14Z","lastAt":"2021-11-13T07:11:55Z","messageCount":5,"participants":["Michael Schiff","Saksham Mittal","Philippe Blain","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"440288","messageId":"CAJcz5TVsv20+FmHR67_UhL_7rhEGvfPHeP3RMiRtnSGAEKiwBg@mail.gmail.com","threadId":"56828","inReplyTo":null,"subject":"Possible merge bug","fromName":"Michael Schiff","fromEmail":"schiff.michael@gmail.com","sentAt":"2021-11-02T06:26:00Z","receivedAt":"2021-11-02T06:26:14Z","isPatch":false,"sender":{"key":"schiff.michael@gmail.com","avatar":null},"body":"[Summary]\nIssue occurs when two branches reorder lines of the same file and are\nthen merged back to the base branch. Instead of getting a content\nmerge conflict, the branches are merged successfully and a line in the\nfile is duplicated.\n\n\n[Steps to Reproduce]\n1. initialize a new repository and create a file with three lines of content:\n```\na\nb\nc\n```\nand commit the result\n\n2. branch from this commit and modify the contents of the file to be:\n```\nb\na\nc\n```\nand commit the results\n\n3. checkout master at commit from step one\n\n4. branch from this commit and modify the contents of the file to be:\n```\nb\nc\na\n```\nand commit the results\n\n5. checkout master at the commit from step one\n\n6. merge the first branch (results in ff-merge)\n\n7. merge the second branch (results in auto merge_3way)\n\n8. examine file contents:\n```\nb\na\nc\na\n```\n\n[Expected Behavior]\nI expected to get a content merge conflict when attempting to merge\nthe second branch.  If the example is changed to be a file starting\n```\na\nb\nc\nd\n```\nwith two branches that change it to\n```\nc\na\nb\nd\n```\nand\n```\nc\nd\na\nb\n```\nrespectively, and then the same sequence of merges, this is detected\nas a merge conflict as I would expect the single line case to be.\n\n[What Happened Instead]\nInstead merge succeeds without conflict and results in duplication of\na line in the file\n\n\n[System Info]\ngit version:\ngit version 2.34.0.rc0.377.g6d82a21a3b\ncpu: x86_64\nbuilt from commit: 6d82a21a3b699caf378cb0f89b6b0e803fc58480\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Darwin 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:31\nPDT 2021; root:xnu-7195.141.2~5/RELEASE_X86_64 x86_64\ncompiler info: clang: 13.0.0 (clang-1300.0.29.3)\nlibc info: no libc information available\n$SHELL (typically, interactive shell): /bin/zsh\n\n\n[Enabled Hooks]\n\n[Other Details]\nI tried this experiment with a few different merge strategies and got\nthe same result regardless of which I picked.  I did some rudimentary\ndebugging and tracked handling of the merge for this file through\nmerge-ort.c -> merge_3way -> ll_merge -> xdiff/xmerge.c -- It seems\nxdiff/xmerge is responsible for attempting the actual merge, deciding\nif there are conflicts and dropping the usual markers, or successfully\nauto-merging the changes.  Wasn't sure of the testing process for\nxdiff and figured I would put this to the mailing list for feedback.\n"},{"id":"440905","messageId":"5aa1fb67-6bd8-6de3-8271-369722b6ebef@gmail.com","threadId":"56828","inReplyTo":"CAJcz5TVsv20+FmHR67_UhL_7rhEGvfPHeP3RMiRtnSGAEKiwBg@mail.gmail.com","subject":"Re: Possible merge bug","fromName":"Saksham Mittal","fromEmail":"saksham.mittal000@gmail.com","sentAt":"2021-11-11T11:20:44Z","receivedAt":"2021-11-11T11:20:58Z","isPatch":false,"sender":{"key":"saksham.mittal000@gmail.com","avatar":null},"body":"Hello there,\n\nI wrote a small script as well that automates testing this use case as well, but I don't really know what the policy is on attachments in git, seeing as how it's my first time contributing to git.\n\nI am on git version 2.33.1 on Fedora 35, but I am not seeing the bug while running the script. So, I grabbed the git source code and built it. This version is 2.34.0.rc2.9.g4d53e91c6b, not quite your version but I tried to go back to the commit you mentioned and build it, but I faced some errors and no binary would build.\n\nAnyway, the version I built and tested also did not permit auto merge and required me to manually make changes as well, so the issue seems to have been fixed.\n\nYou can take a look at my script as well, I followed your instructions as best I could and built this:\n\n#!/bin/bash\n\ngit --version\n\nmkdir sample\ncd sample\ngit init\necho -e \"a\\nb\\nc\\n\" > test\ngit add .\ngit commit -m \"abc\"\n\ngit branch b1\ngit switch b1\n\necho -e \"b\\na\\nc\" > test\ngit add .\ngit commit -m \"bac\"\n\ngit switch main\ngit branch b2\ngit switch b2\n\necho -e \"b\\nc\\na\" > test\ngit add .\ngit commit -m \"bca\"\n\ngit switch main\ngit merge b1\ngit merge b2\n\ngit log --graph --oneline --all\n\n\nCheers,\n\nSaksham Mittal\n\n\n\n"},{"id":"440911","messageId":"da873a08-c73a-cc30-6b7d-dd5cd3bacb22@gmail.com","threadId":"56828","inReplyTo":"5aa1fb67-6bd8-6de3-8271-369722b6ebef@gmail.com","subject":"Re: Possible merge bug","fromName":"Philippe Blain","fromEmail":"levraiphilippeblain@gmail.com","sentAt":"2021-11-11T14:28:42Z","receivedAt":"2021-11-11T14:28:49Z","isPatch":false,"sender":{"key":"levraiphilippeblain@gmail.com","avatar":"https://avatars.githubusercontent.com/u/44212482?v=4"},"body":"Hi Michael,\n\nLe 2021-11-11 à 06:20, Saksham Mittal a écrit :\n> Hello there,\n> \n> I wrote a small script as well that automates testing this use case as well, but I don't really know what the policy is on attachments in git, seeing as how it's my first time contributing to git.\n\nI used the script from Saksham (slightly modified to not depend on any Git configuration)\nand could not reproduce either with Git built from the same commit as you.\nMaybe some setting in your ~/.gitconfig is at play ?\n\nFor the record, my edited version of the reproducer:\n\n--- 8< ---\n#!/bin/sh\n\nexport PATH=\"/path/to/built/git/bin-wrappers:$PATH\"\nexport GIT_AUTHOR_NAME=J\nexport GIT_AUTHOR_EMAIL=j@l.com\nexport GIT_COMMITTER_NAME=J\nexport GIT_COMMITTER_EMAIL=j@l.com\nexport HOME=\n\ngit --version --build-options\n\nrm -rf sample\nmkdir sample\ncd sample\ngit init\necho -e \"a\\nb\\nc\\n\" > test\ngit add .\ngit commit -m \"abc\"\n\ngit branch b1\ngit switch b1\n\necho -e \"b\\na\\nc\" > test\ngit add .\ngit commit -m \"bac\"\n\ngit switch master\ngit branch b2\ngit switch b2\n\necho -e \"b\\nc\\na\" > test\ngit add .\ngit commit -m \"bca\"\n\ngit switch master\necho \"----- Merging b1 -----\"\ngit merge b1\ncat test\necho \"----- Merging b2 -----\"\ngit merge b2\necho \"----- Content of test -----\"\ncat test\n--- 8< ---\n\n\nRunning it ends with this output:\n\n\n----- Merging b1 -----\nUpdating 5e00de3..02910cf\nFast-forward\n  test | 3 +--\n  1 file changed, 1 insertion(+), 2 deletions(-)\nb\na\nc\n----- Merging b2 -----\nAuto-merging test\nCONFLICT (content): Merge conflict in test\nAutomatic merge failed; fix conflicts and then commit the result.\n----- Content of test -----\nb\na\nc\n<<<<<<< HEAD\n=======\na\n>>>>>>> b2\n\n\nCheers,\nPhilippe.\n\n"},{"id":"441051","messageId":"CAJcz5TXy37s=Ez-SwKHGS6ps_+oGSsyjXSVCC0=qnoPx2BE1QA@mail.gmail.com","threadId":"56828","inReplyTo":"da873a08-c73a-cc30-6b7d-dd5cd3bacb22@gmail.com","subject":"Re: Possible merge bug","fromName":"Michael Schiff","fromEmail":"schiff.michael@gmail.com","sentAt":"2021-11-13T03:49:47Z","receivedAt":"2021-11-13T03:50:02Z","isPatch":false,"sender":{"key":"schiff.michael@gmail.com","avatar":null},"body":"This script includes an extra new-line, turing the final change into a\n2 line diff, which is caught correctly.  Modified to:\n--- 8< ---\ngit --version --build-options\n\nrm -rf sample\nmkdir sample\ncd sample\ngit init\necho -e \"a\\nb\\nc\" > test\ngit add .\ngit commit -m \"abc\"\n\ngit branch b1\ngit switch b1\n\necho -e \"b\\na\\nc\" > test\ngit add .\ngit commit -m \"bac\"\n\ngit switch master\ngit branch b2\ngit switch b2\n\necho -e \"b\\nc\\na\" > test\ngit add .\ngit commit -m \"bca\"\n\ngit switch master\necho \"----- Merging b1 -----\"\ngit merge b1\ncat test\necho \"----- Merging b2 -----\"\ngit merge b2\necho \"----- Content of test -----\"\ncat test\n--- 8< ---\n\nThe only meaningful difference being the removal of the trailing \\n\nfrom the first echo.  Running it produces the output:\n\ngit version 2.34.0.rc0.377.g6d82a21a3b\ncpu: x86_64\nbuilt from commit: 6d82a21a3b699caf378cb0f89b6b0e803fc58480\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nhint: Using 'master' as the name for the initial branch. This default\nbranch name\nhint: is subject to change. To configure the initial branch name to use in all\nhint: of your new repositories, which will suppress this warning, call:\nhint:\nhint: git config --global init.defaultBranch <name>\nhint:\nhint: Names commonly chosen instead of 'master' are 'main', 'trunk' and\nhint: 'development'. The just-created branch can be renamed via this command:\nhint:\nhint: git branch -m <name>\nInitialized empty Git repository in /Users/michaelschiff/Desktop/sample/.git/\n[master (root-commit) 8d6bc12] abc\n 1 file changed, 3 insertions(+)\n create mode 100644 test\nSwitched to branch 'b1'\n[b1 b5328d8] bac\n 1 file changed, 1 insertion(+), 1 deletion(-)\nSwitched to branch 'master'\nSwitched to branch 'b2'\n[b2 98603f6] bca\n 1 file changed, 1 insertion(+), 1 deletion(-)\nSwitched to branch 'master'\n----- Merging b1 -----\nUpdating 8d6bc12..b5328d8\nFast-forward\n test | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\nb\na\nc\n----- Merging b2 -----\nAuto-merging test\nMerge made by the 'ort' strategy.\n test | 1 +\n 1 file changed, 1 insertion(+)\n----- Content of test -----\nb\na\nc\na\n\n\n\nHappy to provide any other info that helps\n\nOn Thu, Nov 11, 2021 at 6:28 AM Philippe Blain\n<levraiphilippeblain@gmail.com> wrote:\n>\n> Hi Michael,\n>\n> Le 2021-11-11 à 06:20, Saksham Mittal a écrit :\n> > Hello there,\n> >\n> > I wrote a small script as well that automates testing this use case as well, but I don't really know what the policy is on attachments in git, seeing as how it's my first time contributing to git.\n>\n> I used the script from Saksham (slightly modified to not depend on any Git configuration)\n> and could not reproduce either with Git built from the same commit as you.\n> Maybe some setting in your ~/.gitconfig is at play ?\n>\n> For the record, my edited version of the reproducer:\n>\n> --- 8< ---\n> #!/bin/sh\n>\n> export PATH=\"/path/to/built/git/bin-wrappers:$PATH\"\n> export GIT_AUTHOR_NAME=J\n> export GIT_AUTHOR_EMAIL=j@l.com\n> export GIT_COMMITTER_NAME=J\n> export GIT_COMMITTER_EMAIL=j@l.com\n> export HOME=\n>\n> git --version --build-options\n>\n> rm -rf sample\n> mkdir sample\n> cd sample\n> git init\n> echo -e \"a\\nb\\nc\\n\" > test\n> git add .\n> git commit -m \"abc\"\n>\n> git branch b1\n> git switch b1\n>\n> echo -e \"b\\na\\nc\" > test\n> git add .\n> git commit -m \"bac\"\n>\n> git switch master\n> git branch b2\n> git switch b2\n>\n> echo -e \"b\\nc\\na\" > test\n> git add .\n> git commit -m \"bca\"\n>\n> git switch master\n> echo \"----- Merging b1 -----\"\n> git merge b1\n> cat test\n> echo \"----- Merging b2 -----\"\n> git merge b2\n> echo \"----- Content of test -----\"\n> cat test\n> --- 8< ---\n>\n>\n> Running it ends with this output:\n>\n>\n> ----- Merging b1 -----\n> Updating 5e00de3..02910cf\n> Fast-forward\n>   test | 3 +--\n>   1 file changed, 1 insertion(+), 2 deletions(-)\n> b\n> a\n> c\n> ----- Merging b2 -----\n> Auto-merging test\n> CONFLICT (content): Merge conflict in test\n> Automatic merge failed; fix conflicts and then commit the result.\n> ----- Content of test -----\n> b\n> a\n> c\n> <<<<<<< HEAD\n> =======\n> a\n> >>>>>>> b2\n>\n>\n> Cheers,\n> Philippe.\n>\n"},{"id":"441054","messageId":"5079b568-d86d-97a9-2561-25cafc6a490f@kdbg.org","threadId":"56828","inReplyTo":"CAJcz5TXy37s=Ez-SwKHGS6ps_+oGSsyjXSVCC0=qnoPx2BE1QA@mail.gmail.com","subject":"Re: Possible merge bug","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2021-11-13T07:11:51Z","receivedAt":"2021-11-13T07:11:55Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 13.11.21 um 04:49 schrieb Michael Schiff:\n> This script includes an extra new-line, turing the final change into a\n> 2 line diff, which is caught correctly.  Modified to:\n> --- 8< ---\n> git --version --build-options\n> \n> rm -rf sample\n> mkdir sample\n> cd sample\n> git init\n> echo -e \"a\\nb\\nc\" > test\n> git add .\n> git commit -m \"abc\"\n> \n> git branch b1\n> git switch b1\n> \n> echo -e \"b\\na\\nc\" > test\n> git add .\n> git commit -m \"bac\"\n> \n> git switch master\n> git branch b2\n> git switch b2\n> \n> echo -e \"b\\nc\\na\" > test\n> git add .\n> git commit -m \"bca\"\n> \n> git switch master\n> echo \"----- Merging b1 -----\"\n> git merge b1\n> cat test\n> echo \"----- Merging b2 -----\"\n> git merge b2\n> echo \"----- Content of test -----\"\n> cat test\n> --- 8< ---\n> \n> The only meaningful difference being the removal of the trailing \\n\n> from the first echo.  Running it produces the output:\n> \n> git version 2.34.0.rc0.377.g6d82a21a3b\n> cpu: x86_64\n> built from commit: 6d82a21a3b699caf378cb0f89b6b0e803fc58480\n> sizeof-long: 8\n> sizeof-size_t: 8\n> shell-path: /bin/sh\n> hint: Using 'master' as the name for the initial branch. This default\n> branch name\n> hint: is subject to change. To configure the initial branch name to use in all\n> hint: of your new repositories, which will suppress this warning, call:\n> hint:\n> hint: git config --global init.defaultBranch <name>\n> hint:\n> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and\n> hint: 'development'. The just-created branch can be renamed via this command:\n> hint:\n> hint: git branch -m <name>\n> Initialized empty Git repository in /Users/michaelschiff/Desktop/sample/.git/\n> [master (root-commit) 8d6bc12] abc\n>  1 file changed, 3 insertions(+)\n>  create mode 100644 test\n> Switched to branch 'b1'\n> [b1 b5328d8] bac\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> Switched to branch 'master'\n> Switched to branch 'b2'\n> [b2 98603f6] bca\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> Switched to branch 'master'\n> ----- Merging b1 -----\n> Updating 8d6bc12..b5328d8\n> Fast-forward\n>  test | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> b\n> a\n> c\n> ----- Merging b2 -----\n> Auto-merging test\n> Merge made by the 'ort' strategy.\n>  test | 1 +\n>  1 file changed, 1 insertion(+)\n> ----- Content of test -----\n> b\n> a\n> c\n> a\n\nThere is no bug.\n\nBefore the merge, the diff on our side is\n\n@@ -1,3 +1,3 @@\n-a\n b\n+a\n c\n\nand the diff on their side is\n\n@@ -1,3 +1,3 @@\n-a\n b\n c\n+a\n\nNotice how both sides remove the first line, '-a'. The diff algorithm\ntreats this identical change on both sides not as a conflict, but simply\nas \"both sides did the same thing, so let's take it\". This leaves two\nchanges: our side added 'a' in the middle and their side added 'a' at\nthe end. Both changes are separated by a common context, 'c', which does\nnot produce a conflict as desired. Hence, no conflict in total.\n\nThere is one thing to notice, though. Our side turns 'abc' into 'bac',\ni.e., swaps the first two lines. There is no unique \"true\" patch text\nthat represents a change that swaps two regions of code. It could be\n\n@@ -1,3 +1,3 @@\n-a\n b\n+a\n c\n\nor\n\n@@ -1,3 +1,3 @@\n+b\n a\n-b\n c\n\nGit's diff algrithm (and henceforth merge algorithm) happens to pick the\nfirst one in this case. Had it picked the second option, there would\nhave been a conflict, I think ('-a' vs. '+b').\n\n-- Hannes\n"}]}