{"thread":{"id":"41910","subject":"[sort-of-BUG] merge-resolve cannot resolve \"content/mode\" conflict","startedAt":"2016-04-03T05:26:28Z","lastAt":"2016-05-19T01:03:18Z","messageCount":3,"participants":["Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"282552","messageId":"20160403052627.GA10487@sigill.intra.peff.net","threadId":"41910","inReplyTo":null,"subject":"[sort-of-BUG] merge-resolve cannot resolve \"content/mode\" conflict","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-04-03T05:26:28Z","receivedAt":"2016-04-03T05:26:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Imagine a merge where one side changes the content of a path and the\nother changes the mode. Here's a minimal reproduction:\n\n  git init repo && cd repo &&\n\n  echo base >file &&\n  git add file &&\n  git commit -m base &&\n\n  echo changed >file &&\n  git commit -am content &&\n\n  git checkout -b side HEAD^\n  chmod +x file &&\n  git commit -am mode\n\nIf I merge that with merge-recursive, I get what you'd expect: mode\n10755, and content \"changed\".\n\nHowever, with merge-resolve, I get a conflict:\n\n  $ git merge -s resolve master\n  Trying really trivial in-index merge...\n  error: Merge requires file-level merging\n  Nope.\n  Trying simple merge.\n  Simple merge failed, trying Automatic merge.\n  Auto-merging file\n  ERROR: permissions conflict: 100644->100755,100644 in file\n  fatal: merge program failed\n  Automatic merge failed; fix conflicts and then commit the result.\n\nI think this is only a half-bug, really. It's definitely a funny\nsituation, and it's not unreasonable for a merge driver to punt on a\nfunny situation rather than resolving it. But I would say:\n\n  - it would probably be a nice improvement to resolve this as\n    merge-recursive does\n\n  - the \"ERROR\" message is silly and misleading; the permissions resolve\n    just fine, it is only that the combination with the content-level\n    change confuses the script (but the output does not mention that).\n\nThis is a leftover from my experiments with merge-resolve versus\nmerge-recursive last fall, which resulted in a few actual bug-fixes. I\nlooked into fixing this case, too, at that time. It seemed possible, but\na little more involved than you might think (because the logic is driven\nby a bunch of case statements, and this adds a multiplicative layer to\nthe cases; we might need to resolve the permissions, and _then_ see if\nthe content can be resolved).\n\nSo I didn't actually come up with a patch, but I figured I'd write it up\nhere for posterity. And just didn't get around to it until now.\n\n-Peff\n"},{"id":"282629","messageId":"xmqqh9fh5lcl.fsf@gitster.mtv.corp.google.com","threadId":"41910","inReplyTo":"20160403052627.GA10487@sigill.intra.peff.net","subject":"Re: [sort-of-BUG] merge-resolve cannot resolve \"content/mode\" conflict","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-04-04T17:34:34Z","receivedAt":"2016-04-04T17:34:34Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Imagine a merge where one side changes the content of a path and the\n> other changes the mode. Here's a minimal reproduction:\n>\n>   git init repo && cd repo &&\n>\n>   echo base >file &&\n>   git add file &&\n>   git commit -m base &&\n>\n>   echo changed >file &&\n>   git commit -am content &&\n>\n>   git checkout -b side HEAD^\n>   chmod +x file &&\n>   git commit -am mode\n> ...\n> This is a leftover from my experiments with merge-resolve versus\n> merge-recursive last fall, which resulted in a few actual bug-fixes. I\n> looked into fixing this case, too, at that time. It seemed possible, but\n> a little more involved than you might think (because the logic is driven\n> by a bunch of case statements, and this adds a multiplicative layer to\n> the cases; we might need to resolve the permissions, and _then_ see if\n> the content can be resolved).\n\nPerhaps I am missing some other codepath in the \"multiplicative\"\nlayer, but is this not sufficient?\n\nThe convoluted \"update-index/chmod\" dance is to help those on\nfilesystems that lack proper executable bits.  Otherwise the last\n\"update-index --chmod\" is not needed.\n\n\n git-merge-one-file.sh | 25 +++++++++++++++++++++++--\n 1 file changed, 23 insertions(+), 2 deletions(-)\n\ndiff --git a/git-merge-one-file.sh b/git-merge-one-file.sh\nindex 424b034..36bcdcc 100755\n--- a/git-merge-one-file.sh\n+++ b/git-merge-one-file.sh\n@@ -142,8 +142,19 @@ case \"${1:-.}${2:-.}${3:-.}\" in\n \tgit checkout-index -f --stage=2 -- \"$4\" && cat \"$src1\" >\"$4\" || exit 1\n \trm -f -- \"$orig\" \"$src1\" \"$src2\"\n \n-\tif test \"$6\" != \"$7\"\n+\t# Three-way merge of the permissions\n+\tperm= ;# assume the result is the same from stage #2, i.e. $6\n+\tif test \"$6\" = \"$7\" || test \"$5\" = \"$7\"\n+\tthen\n+\t\t: nothing\n+\telif test \"$5\" = \"$6\"\n \tthen\n+\t\tcase \"$7\" in\n+\t\t100644)\tperm=-x ;;\n+\t\t100755) perm=+x ;;\n+\t\t*) echo \"ERROR: $7: funny filemode not handled.\" >&2 ;;\n+\t\tesac\n+\telse\n \t\tif test -n \"$msg\"\n \t\tthen\n \t\t\tmsg=\"$msg, \"\n@@ -157,7 +168,17 @@ case \"${1:-.}${2:-.}${3:-.}\" in\n \t\techo \"ERROR: $msg in $4\" >&2\n \t\texit 1\n \tfi\n-\texec git update-index -- \"$4\"\n+\n+\tif test -n \"$perm\"\n+\tthen\n+\t\tchmod \"$perm\" -- \"$4\"\n+\tfi &&\n+\tgit update-index -- \"$4\" &&\n+\tif test -n \"$perm\"\n+\tthen\n+\t\tgit update-index --chmod=\"$perm\" -- \"$4\"\n+\tfi\n+\texit\n \t;;\n \n *)\n"},{"id":"286952","messageId":"20160519010318.GA23155@sigill.intra.peff.net","threadId":"41910","inReplyTo":"xmqqh9fh5lcl.fsf@gitster.mtv.corp.google.com","subject":"Re: [sort-of-BUG] merge-resolve cannot resolve \"content/mode\" conflict","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-05-19T01:03:18Z","receivedAt":"2016-05-19T01:03:18Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 04, 2016 at 10:34:34AM -0700, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > Imagine a merge where one side changes the content of a path and the\n> > other changes the mode. Here's a minimal reproduction:\n> >\n> >   git init repo && cd repo &&\n> >\n> >   echo base >file &&\n> >   git add file &&\n> >   git commit -m base &&\n> >\n> >   echo changed >file &&\n> >   git commit -am content &&\n> >\n> >   git checkout -b side HEAD^\n> >   chmod +x file &&\n> >   git commit -am mode\n> > ...\n> > This is a leftover from my experiments with merge-resolve versus\n> > merge-recursive last fall, which resulted in a few actual bug-fixes. I\n> > looked into fixing this case, too, at that time. It seemed possible, but\n> > a little more involved than you might think (because the logic is driven\n> > by a bunch of case statements, and this adds a multiplicative layer to\n> > the cases; we might need to resolve the permissions, and _then_ see if\n> > the content can be resolved).\n> \n> Perhaps I am missing some other codepath in the \"multiplicative\"\n> layer, but is this not sufficient?\n\nSorry for the super-slow reply; just cleaning out my \"to respond to\"\npile, which has gotten pretty deep.\n\nLooking at it again, I think you are right. I seemed to recall that\nthere were multiple case arms where we dealt with the permissions, but I\ncannot find such a spot now. So I think the solution you outlined looks\ngood.\n\n> -\tif test \"$6\" != \"$7\"\n> +\t# Three-way merge of the permissions\n> +\tperm= ;# assume the result is the same from stage #2, i.e. $6\n> +\tif test \"$6\" = \"$7\" || test \"$5\" = \"$7\"\n> +\tthen\n> +\t\t: nothing\n> +\telif test \"$5\" = \"$6\"\n>  \tthen\n> +\t\tcase \"$7\" in\n> +\t\t100644)\tperm=-x ;;\n> +\t\t100755) perm=+x ;;\n> +\t\t*) echo \"ERROR: $7: funny filemode not handled.\" >&2 ;;\n> +\t\tesac\n\nWe reject symlinks and submodules earlier, so I think this \"funny\nfilemode\" error really should only be truly-funny entries. Good.\n\n-Peff\n"}]}