{"thread":{"id":"56041","subject":"Logical bug during MERGE or REBASE","startedAt":"2021-07-02T16:32:58Z","lastAt":"2021-07-04T06:31:08Z","messageCount":6,"participants":["skottkuk@wp.pl","Atharva Raykar","Ævar Arnfjörð Bjarmason","martin","Bagas Sanjaya"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"429062","messageId":"1932019063.20210702192555@wp.pl","threadId":"56041","inReplyTo":null,"subject":"Logical bug during MERGE or REBASE","fromName":"","fromEmail":"skottkuk@wp.pl","sentAt":"2021-07-02T16:25:55Z","receivedAt":"2021-07-02T16:32:58Z","isPatch":false,"sender":{"key":"skottkuk@wp.pl","avatar":null},"body":"Hello.\n\nI got a strange result in the process of \"merge\" and/or \"rebase\".\n\nI'm not a git professional, so maybe this is not a bug, but a feature.\nBut as for me, it would be logical to consider the construction inside {} as something whole, and not just put all the changes into one heap with notification what all OK, no conflicts.\n\nAll the details are inside the git-bugreport-2021-07-02-1737.txt.\nI hope this log will be useful. Feel free to write me for extra details.  \n\nBest regards,\nSkott\n\nThank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\nI did:\n$git init\n$git add Program.cs\nInside:\n{\n Console.Writeline(\"1\");\n Console.Readline();\n}\n$git commit -m \"Init commit\"\n\n$git checkout -b dev\nDid this changes in Program.cs:\n{\n Console.Writeline(\"1\");\n Console.Readline();\n Console.Readline();\n Console.Readline();\n}\n$git commit -a -m \"dev commit\"\n\n$git checkout master\nDid this changes in Program.cs:\n{\n Console.Writeline(\"1\");\n Console.Writeline(\"2\");\n Console.Readline();\n Console.Readline();\n}\n$git commit -a -m \"master commit\"\n\nAnd I get a logical bug inside Program.cs when I want merge or rebase:\n1)git merge dev\nOR\n2)git rebase dev\n \nWhat did you expect to happen? (Expected behavior)\nI expected conflict in my Program.cs like:\n{\n Console.Writeline(\"1\");\n<<<<<<< HEAD\n Console.Writeline(\"2\");\n=======\n Console.Readline();\n>>>>>>> dev\n Console.Readline();\n Console.Readline();\n}\n\nWhat happened instead? (Actual behavior)\nJust sum of 2 commits without any conflicts:\n{\n Console.Writeline(\"1\");\n Console.Writeline(\"2\");\n Console.Readline();\n Console.Readline();\n Console.Readline();\n Console.Readline();\n}\n\nWhat's different between what you expected and what actually happened?\nExtra lines was added in \"silent\" mode without any notification.\n\nAnything else you want to add:\nNow necessary to revice all lines, even if there are no any conflicts :(\n\n[System Info]\ngit version:\ngit version 2.32.0.windows.1\ncpu: x86_64\nbuilt from commit: 4c204998d0e156d13d81abe1d1963051b1418fc0\nsizeof-long: 4\nsizeof-size_t: 8\nshell-path: /bin/sh\nfeature: fsmonitor--daemon\nuname: Windows 6.1 7601 \ncompiler info: gnuc: 10.3\nlibc info: no libc information available\n$SHELL (typically, interactive shell): <unset>\n\n\n[Enabled Hooks]\n"},{"id":"429104","messageId":"3CD890FA-7A99-4DDC-9691-80D1ED6BD51B@gmail.com","threadId":"56041","inReplyTo":"1932019063.20210702192555@wp.pl","subject":"Re: Logical bug during MERGE or REBASE","fromName":"Atharva Raykar","fromEmail":"raykar.ath@gmail.com","sentAt":"2021-07-03T07:57:51Z","receivedAt":"2021-07-03T07:58:00Z","isPatch":false,"sender":{"key":"raykar.ath@gmail.com","avatar":"https://avatars.githubusercontent.com/u/24277692?v=4"},"body":"On 02-Jul-2021, at 21:55, skottkuk@wp.pl wrote:\n> \n> Hello.\n> \n> I got a strange result in the process of \"merge\" and/or \"rebase\".\n> \n> I'm not a git professional, so maybe this is not a bug, but a feature.\n> But as for me, it would be logical to consider the construction inside {}\n> as something whole, and not just put all the changes into one heap with\n> notification what all OK, no conflicts.\n> \n> All the details are inside the git-bugreport-2021-07-02-1737.txt.\n> I hope this log will be useful. Feel free to write me for extra details.  \n> \n> Best regards,\n> Skott<git-bugreport-2021-07-02-1737.txt>\n\nLet's look at the diffs (I have annotated this with arrows):\n\n$ # common ancestor, ie, the first commit\n$ initial=$(git merge-base master dev)\n\n$ git diff $initial master\n\ndiff --git a/program.cs b/program.cs\nindex 8bc1a4d..93f872f 100644\n--- a/program.cs\n+++ b/program.cs\n@@ -1,4 +1,6 @@\n {\n  Console.Writeline(\"1\");\n+ Console.Writeline(\"2\");\n+ Console.Readline();\n  Console.Readline();     <--- X\n }\n\n$ git diff $initial dev\n\ndiff --git a/program.cs b/program.cs\nindex 8bc1a4d..eb91c97 100644\n--- a/program.cs\n+++ b/program.cs\n@@ -1,4 +1,6 @@\n {\n  Console.Writeline(\"1\");\n  Console.Readline();     <--- X\n+ Console.Readline();\n+ Console.Readline();\n }\n\nAs you can tell, on the master branch, Git sees the changes as\n\"lines were added above the line labeled X\",\nand on the dev branch, Git sees the changes as\n\"lines were added below the line labeled X\".\n\nThus when a 3-way merge is performed, it sees no conflicting changes.\nAdding lines above X does not conflict with adding lines below X.\n\nI do agree the result does look surprising at first. If in the dev\nbranch, git had assumed the \"Readline()s\" to be added in between,\nrather than at the bottom, you would have ended up with a conflict,\nbut that did not happen.\n\n---\nAtharva Raykar\nಅಥರ್ವ ರಾಯ್ಕರ್\nअथर्व रायकर\n\n"},{"id":"429112","messageId":"871r8fab7e.fsf@evledraar.gmail.com","threadId":"56041","inReplyTo":"1932019063.20210702192555@wp.pl","subject":"Re: Logical bug during MERGE or REBASE","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-07-03T11:03:50Z","receivedAt":"2021-07-03T11:28:14Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Jul 02 2021, skottkuk@wp.pl wrote:\n\n> Hello.\n>\n> I got a strange result in the process of \"merge\" and/or \"rebase\".\n\nAtharva already replied to most of this, just adding on this point:\n\n> [...]\n> But as for me, it would be logical to consider the construction inside\n> {} as something whole, and not just put all the changes into one heap\n> with notification what all OK, no conflicts.\n\nGit in general is not aware that your programming language considers {}\nto be special, we don't try to do language detection, or to semantically\nparse the program.\n\nIt's a general merge driver on text lines that works the same whether\nyou have a language like C# that uses {} braces, or a language like\nEmacs Lisp which does not.\n\nThere's particular common cases where this logic goes \"wrong\", I've run\ninto it the most with repetitive declarations like:\n\n    {\n        {\n            description => \"some thingy\",\n            callback    => function { foo },\n            strict      => 1,\n            warn        => 1,\n        },\n        [... lots of these omitted ... ]\n        {\n            description => \"other thingy\",\n            callback    => function { bar },\n            strict      => 1,\n            warn        => 1,\n        },\n    },\n\nI didn't bother to check this specific example, but in cases *like that*\nthe merge driver will often append \"duplicates\" when two branches added\nthe same \"other thingy\", since the boilerplate at the end (or beginning,\ndepending) is repetitive, so a duplication becomes indistinguishable\nfrom an addition for a naïve merge driver).\n\nYou can define your own merge driver that's aware of your language, I\nthink this is probably a too complex and Bad Idea in general.\n\nCustom merge drivers are very useful for e.g. the git-annex case, which\nends up merging really simple \"log\" files. merges there are always\nequivalent to basically a \"sort -u\". I.e. keep all lines added, remove\nduplicates.\n\nBut for a programming language a \"smart merge\" is, I'd like to submit,\nsimply an impossible task. Even if you had perfect AI you couldn't do\nit, even if I had a clone of myself from yesterday we probably couldn't\nagree on how to solve all merges.\n\nThat's because once you get past the simple cases a merge resolution is\nsomething that requires judgement calls from the programmer. E.g. I\nworked on a topic branch, and now I've got a conflict because someone\nchanged the function signature. I can either do the bare minimum and use\nsome compatibility interface today, or convert all my work to the \"new\nAPI\" and not have to convert from the legacy API in the future.\n\nEither one would be a valid resolution, which the perfect AI, or even my\nclone from yesterday might do differently.\n\nBut most importantly having a textual conflict in a program when you\nmerge/rebase is almost always the trivial case, having a semantic\nconflict is something you always need to check for.\n\nGit (or merge tools in general) can't help you with that, because your\n\"conflict\" is in a conflict between the expectations of your topic\nbranch, and whether or not they hold given whatever's happened on an\nadvancing upstream.\n\nSo whether you have textual conflicts on merge/rebase from git or not,\nyour workflow really should be to always assume that you have a semantic\nconflict, unless you're already completely familiar with the new code\nyou're merging into your branch.\n\nI.e. after a merge/rebase look at your patches again to see if they make\nsense given what changed on the upstream, compile, run the tests you\nhave etc.\n\n\n\n"},{"id":"429114","messageId":"4bae5d01-fa6d-7216-55cf-fa7003f5c75c@mfriebe.de","threadId":"56041","inReplyTo":"1932019063.20210702192555@wp.pl","subject":"Re: Logical bug during MERGE or REBASE","fromName":"martin","fromEmail":"test2@mfriebe.de","sentAt":"2021-07-03T09:07:25Z","receivedAt":"2021-07-03T11:36:13Z","isPatch":false,"sender":{"key":"test2@mfriebe.de","avatar":null},"body":"On 02/07/2021 18:25, skottkuk@wp.pl wrote:\n> But as for me, it would be logical to consider the construction inside {} as something whole,\nFor git the {} are just text, like anything else in your file.\n\nAlso, seeing the function as a whole, i.e. always give a conflict for \nany 2 changes within one function, is not wanted.\nThere a plenty of cases where 2 or more changes within the same (bigger) \nfunction are merged together, and expected to be merged.\n\nFor all else see the reply from Atharva Raykar.\n"},{"id":"429149","messageId":"3f09d890-e9b7-0e54-0d03-2ed7609cb448@gmail.com","threadId":"56041","inReplyTo":"3CD890FA-7A99-4DDC-9691-80D1ED6BD51B@gmail.com","subject":"Re: Logical bug during MERGE or REBASE","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-07-04T06:12:08Z","receivedAt":"2021-07-04T06:12:22Z","isPatch":false,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 03/07/21 14.57, Atharva Raykar wrote:\n> Let's look at the diffs (I have annotated this with arrows):\n> \n> $ # common ancestor, ie, the first commit\n> $ initial=$(git merge-base master dev)\n> \n> $ git diff $initial master\n> \n> diff --git a/program.cs b/program.cs\n> index 8bc1a4d..93f872f 100644\n> --- a/program.cs\n> +++ b/program.cs\n> @@ -1,4 +1,6 @@\n>   {\n>    Console.Writeline(\"1\");\n> + Console.Writeline(\"2\");\n> + Console.Readline();\n>    Console.Readline();     <--- X\n>   }\n> \n> $ git diff $initial dev\n> \n> diff --git a/program.cs b/program.cs\n> index 8bc1a4d..eb91c97 100644\n> --- a/program.cs\n> +++ b/program.cs\n> @@ -1,4 +1,6 @@\n>   {\n>    Console.Writeline(\"1\");\n>    Console.Readline();     <--- X\n> + Console.Readline();\n> + Console.Readline();\n>   }\n> \n> As you can tell, on the master branch, Git sees the changes as\n> \"lines were added above the line labeled X\",\n> and on the dev branch, Git sees the changes as\n> \"lines were added below the line labeled X\".\n\nWhat's the purpose of \"X-labeled line\" above?\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"429150","messageId":"928F285A-4F5B-48BA-A817-EE809FD16E16@gmail.com","threadId":"56041","inReplyTo":"3f09d890-e9b7-0e54-0d03-2ed7609cb448@gmail.com","subject":"Re: Logical bug during MERGE or REBASE","fromName":"Atharva Raykar","fromEmail":"raykar.ath@gmail.com","sentAt":"2021-07-04T06:30:59Z","receivedAt":"2021-07-04T06:31:08Z","isPatch":false,"sender":{"key":"raykar.ath@gmail.com","avatar":"https://avatars.githubusercontent.com/u/24277692?v=4"},"body":"On 04-Jul-2021, at 11:42, Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n> \n> On 03/07/21 14.57, Atharva Raykar wrote:\n>> Let's look at the diffs (I have annotated this with arrows):\n>> $ # common ancestor, ie, the first commit\n>> $ initial=$(git merge-base master dev)\n>> $ git diff $initial master\n>> diff --git a/program.cs b/program.cs\n>> index 8bc1a4d..93f872f 100644\n>> --- a/program.cs\n>> +++ b/program.cs\n>> @@ -1,4 +1,6 @@\n>>  {\n>>   Console.Writeline(\"1\");\n>> + Console.Writeline(\"2\");\n>> + Console.Readline();\n>>   Console.Readline();     <--- X\n>>  }\n>> $ git diff $initial dev\n>> diff --git a/program.cs b/program.cs\n>> index 8bc1a4d..eb91c97 100644\n>> --- a/program.cs\n>> +++ b/program.cs\n>> @@ -1,4 +1,6 @@\n>>  {\n>>   Console.Writeline(\"1\");\n>>   Console.Readline();     <--- X\n>> + Console.Readline();\n>> + Console.Readline();\n>>  }\n>> As you can tell, on the master branch, Git sees the changes as\n>> \"lines were added above the line labeled X\",\n>> and on the dev branch, Git sees the changes as\n>> \"lines were added below the line labeled X\".\n> \n> What's the purpose of \"X-labeled line\" above?\n\nIt was just something I manually annotated on the output to keep a track\nof which 'Console.Readline()' line I was referring to.\n\nIt is less tedious for to say \"line labeled X\" than, \"the second line in\nthe code block in the initial commit\".\n\nIf it has made my explanation a little unclear, I don't mind having a\nsecond attempt at it :)\n\n"}]}