{"thread":{"id":"30835","subject":"Re: MERGE_RR droppings","startedAt":"2012-06-18T22:41:05Z","lastAt":"2012-07-02T19:36:32Z","messageCount":11,"participants":["Phil Hord","Junio C Hamano","David Aguilar"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"193816","messageId":"CABURp0os2no40BW0P-biG_fXyi7MHRcLLYWmCbLTdBv1o1OXcg@mail.gmail.com","threadId":"30835","inReplyTo":"CABURp0omkVoLrz29GeOjjoZOpN238Rm6Nu5aOKQyVxFVnPihsw@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-18T22:41:05Z","receivedAt":"2012-06-18T22:41:05Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"git mergetool decides to use rerere-remaining based on the existence\nof the .git/MERGE_RR file:\n\n    if test -e \"$GIT_DIR/MERGE_RR\"\n    then\n        files=$(git rerere remaining)\n    else\n        files=$(git ls-files -u | sed -e 's/^[^ ]*      //' | sort -u)\n    fi\n\nBut when I disabled rerere, I still had MERGE_RR files left over in my\n.git directory.   This causes git-mergetool to do the wrong thing.\n\nI do not know if the correct fix for this is to check rerere.enabled instead.\n\nIs MERGE_RR leaking somewhere it should have been cleaned up?  I often\nsee leftover MERGE_RR files even though I am certain the project is\nnot in the middle of a merge.\n\nIs this a bad semaphore to check?  I do not see it being used this way\nanywhere else.\n\n\nPhil\n"},{"id":"193818","messageId":"7v8vfk2pby.fsf@alter.siamese.dyndns.org","threadId":"30835","inReplyTo":"CABURp0os2no40BW0P-biG_fXyi7MHRcLLYWmCbLTdBv1o1OXcg@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T23:05:37Z","receivedAt":"2012-06-18T23:05:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phil Hord <phil.hord@gmail.com> writes:\n\n> git mergetool decides to use rerere-remaining based on the existence\n> of the .git/MERGE_RR file:\n>\n>     if test -e \"$GIT_DIR/MERGE_RR\"\n\nThis is correct, I would probably write it with \"test -f\" if I were\nwriting this line today, though.  After you commit to conclude the\nmerge, the MERGE_RR marker should disappear.  Isn't it happening for\nyou?\n"},{"id":"194221","messageId":"CABURp0rBRnFjJaXO3BUYWcyXEAsLZeEv05z-hMi8aW9SPTCPqA@mail.gmail.com","threadId":"30835","inReplyTo":"7v8vfk2pby.fsf@alter.siamese.dyndns.org","subject":"Re: MERGE_RR droppings","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-25T18:36:39Z","receivedAt":"2012-06-25T18:36:39Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Mon, Jun 18, 2012 at 7:05 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Phil Hord <phil.hord@gmail.com> writes:\n>\n>> git mergetool decides to use rerere-remaining based on the existence\n>> of the .git/MERGE_RR file:\n>>\n>>     if test -e \"$GIT_DIR/MERGE_RR\"\n>\n> This is correct, I would probably write it with \"test -f\" if I were\n> writing this line today, though.  After you commit to conclude the\n> merge, the MERGE_RR marker should disappear.  Isn't it happening for\n> you?\n\nI was able to isolate this today to cherry-pick.\n\nWhen I successfully cherry-pick a change (no conflicts, no merges), I\nget a .git/MERGE_RR file left over.  After this happens, git-mergetool\nwill think there are no unresolved conflicts unless git (or I) first\nremoves the .git/MERGE_RR.\n\nMaybe this only causes trouble for 'git stash apply' since it does not\nemploy rerere machinery, or because it takes some other code path\nwhich does not begin by removing .git/MERGE_RR.\n\nA naive fix would be to remove MERGE_RR at the conclusion of\n'stash-apply', but I do not think that is the right place for it to\ngo.\n\nSuggestions?\n\nPhil\n"},{"id":"194222","messageId":"7vwr2vfc1c.fsf@alter.siamese.dyndns.org","threadId":"30835","inReplyTo":"7v8vfk2pby.fsf@alter.siamese.dyndns.org","subject":"Re: MERGE_RR droppings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-25T19:04:47Z","receivedAt":"2012-06-25T19:04:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Phil Hord <phil.hord@gmail.com> writes:\n>\n>> git mergetool decides to use rerere-remaining based on the existence\n>> of the .git/MERGE_RR file:\n>>\n>>     if test -e \"$GIT_DIR/MERGE_RR\"\n>\n> This is correct, I would probably write it with \"test -f\" if I were\n> writing this line today, though.  After you commit to conclude the\n> merge, the MERGE_RR marker should disappear.  Isn't it happening for\n> you?\n\nOops.  It actually does not happen for _me_. An empty MERGE_RR is\nleft in the working tree after rerere has dealt with the conflicts.\nThere seems to be only three codepaths that explicitly remove\nMERGE_RR that is stale:\n\n - (obviously) \"rerere clear\"\n - \"git reset\"\n - \"git checkout otherbranch\"\n\nPerhaps mergetool should consider a missing MERGE_RR and an empty\none the same way?\n"},{"id":"194260","messageId":"CAJDDKr7Hj4f-Gww4j89kppR8g1vzmhmydsFnG0ecjzL5WrRP4g@mail.gmail.com","threadId":"30835","inReplyTo":"7vwr2vfc1c.fsf@alter.siamese.dyndns.org","subject":"Re: MERGE_RR droppings","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2012-06-26T04:31:16Z","receivedAt":"2012-06-26T04:31:16Z","isPatch":false,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On Mon, Jun 25, 2012 at 12:04 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Phil Hord <phil.hord@gmail.com> writes:\n>>\n>>> git mergetool decides to use rerere-remaining based on the existence\n>>> of the .git/MERGE_RR file:\n>>>\n>>>     if test -e \"$GIT_DIR/MERGE_RR\"\n>>\n>> This is correct, I would probably write it with \"test -f\" if I were\n>> writing this line today, though.  After you commit to conclude the\n>> merge, the MERGE_RR marker should disappear.  Isn't it happening for\n>> you?\n>\n> Oops.  It actually does not happen for _me_. An empty MERGE_RR is\n> left in the working tree after rerere has dealt with the conflicts.\n> There seems to be only three codepaths that explicitly remove\n> MERGE_RR that is stale:\n>\n>  - (obviously) \"rerere clear\"\n>  - \"git reset\"\n>  - \"git checkout otherbranch\"\n>\n> Perhaps mergetool should consider a missing MERGE_RR and an empty\n> one the same way?\n\nWould that test look (roughly) like this?\n\n    if test -f \"$GIT_DIR/MERGE_RR\" && test -n \"$(cat \"$GIT_DIR/MERGE_RR\")\"\n    then\n\tfiles=$(git rerere remaining)\n    else\n\tfiles=$(git ls-files -u | sed -e 's/^[^\t]*\t//' | sort -u)\n    fi\n    ...\n\nIf so I'll throw together a patch.\n-- \nDavid\n"},{"id":"194262","messageId":"7vtxxyd4hz.fsf@alter.siamese.dyndns.org","threadId":"30835","inReplyTo":"CAJDDKr7Hj4f-Gww4j89kppR8g1vzmhmydsFnG0ecjzL5WrRP4g@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-26T05:30:32Z","receivedAt":"2012-06-26T05:30:32Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Aguilar <davvid@gmail.com> writes:\n\n>> Perhaps mergetool should consider a missing MERGE_RR and an empty\n>> one the same way?\n>\n> Would that test look (roughly) like this?\n>\n>     if test -f \"$GIT_DIR/MERGE_RR\" && test -n \"$(cat \"$GIT_DIR/MERGE_RR\")\"\n\nHrm, would \"test -s $that_file\" be simpler?\n\n\n>     then\n> \tfiles=$(git rerere remaining)\n>     else\n> \tfiles=$(git ls-files -u | sed -e 's/^[^\t]*\t//' | sort -u)\n>     fi\n>     ...\n>\n> If so I'll throw together a patch.\n"},{"id":"194294","messageId":"7v395ic5kq.fsf@alter.siamese.dyndns.org","threadId":"30835","inReplyTo":"CABURp0os2no40BW0P-biG_fXyi7MHRcLLYWmCbLTdBv1o1OXcg@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-26T18:04:53Z","receivedAt":"2012-06-26T18:04:53Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phil Hord <phil.hord@gmail.com> writes:\n\n> git mergetool decides to use rerere-remaining based on the existence\n> of the .git/MERGE_RR file:\n>\n>     if test -e \"$GIT_DIR/MERGE_RR\"\n>     then\n>         files=$(git rerere remaining)\n>     else\n>         files=$(git ls-files -u | sed -e 's/^[^ ]*      //' | sort -u)\n>     fi\n>\n> But when I disabled rerere, I still had MERGE_RR files left over in my\n> .git directory.   This causes git-mergetool to do the wrong thing.\n>\n> I do not know if the correct fix for this is to check rerere.enabled instead.\n\nI do not think basing the decision to use \"ls-files -u\" output upon\nthe use of \"rerere\" is a good thing for this script to do in the\nfirst place.  Doesn't it close the door to future enhancements and\nthird-party mechanisms that do better job than rerere to help the\nusers auto-resolve conflicted merges?  They certainly do not have to\nuse GIT_DIR/MERGE_RR nor GIT_DIR/rr-cache, and \"rerere remaining\"\nwould not know which paths they handled already.\n\nAfter all, the user may have resolved the conflicts in his editor\nbut hasn't recorded the resolution to the index yet when he runs\nmergetool, and the tool should handle such a path exactly like how\nit currently handles the paths resolved by rerere in the working\ntree.  But the above code will include such paths in the $files list\nand throw them at the mergetool backends when rerere is not in use.\n\nThis part of the code probably should be _inspecting_ the files and\nthe index to find out what still needs to be fed to the mergetools\nitself.  Asking \"rerere remaining\" about things that it may not have\ndone (either the user edited the paths in the editor, or some\nthird-party mechanism resolved the conflicts already) does not make\nmuch sense, methinks.\n"},{"id":"194299","messageId":"CABURp0qr7dZfEJZ7oDfG4ftm+cvQO1A9OG4Cv0wid3Mz8j7-iA@mail.gmail.com","threadId":"30835","inReplyTo":"7v395ic5kq.fsf@alter.siamese.dyndns.org","subject":"Re: MERGE_RR droppings","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-26T19:00:59Z","receivedAt":"2012-06-26T19:00:59Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Tue, Jun 26, 2012 at 2:04 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Phil Hord <phil.hord@gmail.com> writes:\n>\n>> git mergetool decides to use rerere-remaining based on the existence\n>> of the .git/MERGE_RR file:\n>>\n>>     if test -e \"$GIT_DIR/MERGE_RR\"\n>>     then\n>>         files=$(git rerere remaining)\n>>     else\n>>         files=$(git ls-files -u | sed -e 's/^[^ ]*      //' | sort -u)\n>>     fi\n>>\n>> But when I disabled rerere, I still had MERGE_RR files left over in my\n>> .git directory.   This causes git-mergetool to do the wrong thing.\n>>\n>> I do not know if the correct fix for this is to check rerere.enabled instead.\n>\n> I do not think basing the decision to use \"ls-files -u\" output upon\n> the use of \"rerere\" is a good thing for this script to do in the\n> first place.  Doesn't it close the door to future enhancements and\n> third-party mechanisms that do better job than rerere to help the\n> users auto-resolve conflicted merges?  They certainly do not have to\n> use GIT_DIR/MERGE_RR nor GIT_DIR/rr-cache, and \"rerere remaining\"\n> would not know which paths they handled already.\n>\n> After all, the user may have resolved the conflicts in his editor\n> but hasn't recorded the resolution to the index yet when he runs\n> mergetool, and the tool should handle such a path exactly like how\n> it currently handles the paths resolved by rerere in the working\n> tree.  But the above code will include such paths in the $files list\n> and throw them at the mergetool backends when rerere is not in use.\n>\n> This part of the code probably should be _inspecting_ the files and\n> the index to find out what still needs to be fed to the mergetools\n> itself.  Asking \"rerere remaining\" about things that it may not have\n> done (either the user edited the paths in the editor, or some\n> third-party mechanism resolved the conflicts already) does not make\n> much sense, methinks.\n\n\nI'll buy that.  But what should we be inspecting the files for?  What\nindicates the conflicts are resolved if not 'git add/rm'?\n\nMeanwhile, I run into this trouble when I get a conflicted\ngit-stash-pop.  The first thing I do is invoke git-mergetool.  This\nfails with \"No files need merging\" in the case of a GIT_DIR/MERGE_RR\nleave-behind from some previous activity.  This is quite itchy, and so\nI am looking for the correct thing to do.\n\nDoes the MERGE_RR file need to be deleted more often?\nDo we need some extensible way to indicate currently-unresolved files?\nOr something in-between these two?\n\nP\n"},{"id":"194453","messageId":"CAJDDKr5w2Q6aJcF48WbVyS=q54+iq=RAu9njJ18Wv8=OEbSrnQ@mail.gmail.com","threadId":"30835","inReplyTo":"CABURp0qr7dZfEJZ7oDfG4ftm+cvQO1A9OG4Cv0wid3Mz8j7-iA@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2012-07-01T00:19:17Z","receivedAt":"2012-07-01T00:19:17Z","isPatch":false,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On Tue, Jun 26, 2012 at 12:00 PM, Phil Hord <phil.hord@gmail.com> wrote:\n> On Tue, Jun 26, 2012 at 2:04 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Phil Hord <phil.hord@gmail.com> writes:\n>>\n>>> git mergetool decides to use rerere-remaining based on the existence\n>>> of the .git/MERGE_RR file:\n>>>\n>>>     if test -e \"$GIT_DIR/MERGE_RR\"\n>>>     then\n>>>         files=$(git rerere remaining)\n>>>     else\n>>>         files=$(git ls-files -u | sed -e 's/^[^ ]*      //' | sort -u)\n>>>     fi\n>>>\n>>> But when I disabled rerere, I still had MERGE_RR files left over in my\n>>> .git directory.   This causes git-mergetool to do the wrong thing.\n>>>\n>>> I do not know if the correct fix for this is to check rerere.enabled instead.\n>>\n>> I do not think basing the decision to use \"ls-files -u\" output upon\n>> the use of \"rerere\" is a good thing for this script to do in the\n>> first place.  Doesn't it close the door to future enhancements and\n>> third-party mechanisms that do better job than rerere to help the\n>> users auto-resolve conflicted merges?  They certainly do not have to\n>> use GIT_DIR/MERGE_RR nor GIT_DIR/rr-cache, and \"rerere remaining\"\n>> would not know which paths they handled already.\n>>\n>> After all, the user may have resolved the conflicts in his editor\n>> but hasn't recorded the resolution to the index yet when he runs\n>> mergetool, and the tool should handle such a path exactly like how\n>> it currently handles the paths resolved by rerere in the working\n>> tree.  But the above code will include such paths in the $files list\n>> and throw them at the mergetool backends when rerere is not in use.\n>>\n>> This part of the code probably should be _inspecting_ the files and\n>> the index to find out what still needs to be fed to the mergetools\n>> itself.  Asking \"rerere remaining\" about things that it may not have\n>> done (either the user edited the paths in the editor, or some\n>> third-party mechanism resolved the conflicts already) does not make\n>> much sense, methinks.\n>\n>\n> I'll buy that.  But what should we be inspecting the files for?  What\n> indicates the conflicts are resolved if not 'git add/rm'?\n>\n> Meanwhile, I run into this trouble when I get a conflicted\n> git-stash-pop.  The first thing I do is invoke git-mergetool.  This\n> fails with \"No files need merging\" in the case of a GIT_DIR/MERGE_RR\n> leave-behind from some previous activity.  This is quite itchy, and so\n> I am looking for the correct thing to do.\n>\n> [1]Does the MERGE_RR file need to be deleted more often?\n> [2]Do we need some extensible way to indicate currently-unresolved files?\n> Or something in-between these two?\n>\n> P\n\n>From a mergetool perspective, just doing #2 would be nice.\nWe can have a \"default\" unmerged files provider that does the\n`test -s .../MERGE_RR` check since that would probably deal with\nthis ugly edge case.\n\nWe can then teach this default thing to be smarter and skip text files\nwith no merge markers. Junio, is this what you were thinking?\nThis sounds like a nice way to me.\n-- \nDavid\n"},{"id":"194459","messageId":"7vmx3i3agg.fsf@alter.siamese.dyndns.org","threadId":"30835","inReplyTo":"CAJDDKr5w2Q6aJcF48WbVyS=q54+iq=RAu9njJ18Wv8=OEbSrnQ@mail.gmail.com","subject":"Re: MERGE_RR droppings","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-07-02T07:10:07Z","receivedAt":"2012-07-02T07:10:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Aguilar <davvid@gmail.com> writes:\n\n> We can have a \"default\" unmerged files provider that does the\n> `test -s .../MERGE_RR` check since that would probably deal with\n> this ugly edge case.\n>\n> We can then teach this default thing to be smarter and skip text files\n> with no merge markers. Junio, is this what you were thinking?\n> This sounds like a nice way to me.\n\nI am not sure what I were thinking ;-) so let me think aloud.\n\nIn any case, once the user says (either via directly using \"git add\"\nor using the command via the mergetool) the path is resolved,\nmergetool would no longer want to touch it, until the user says\n\"oops, the resolution was a mistake; pleae make it unresolved again\"\nwith something like \"git checkout -m\".  So in this message, I'll\nthink only about the case where the index is still unmerged.\n\nThe working tree files may be in one of these states:\n\n 1. It may still be the same as the conflicted state after the\n    three-way merge proper gave the user, perhaps with conflict\n    markers in the text.\n\n 2. rerere or some other mechanism (this includes manual editing or\n    previous run of \"mergetool\") may have resolved the conflict\n    fully.\n\n 3. Or such a mechanism may have only half-resolved the conflict.\n\nAs far as I can see, the mergetool machinery, once it decides to\nfeed a path to the mergetool backend, ignores what is in the working\ntree file, and uses the stage #2 (i.e. the state before merge\nhappened) as LOCAL (and stage #1 as BASE, stage #3 as REMOTE) to\nredo the entire three-way merge from scratch.\n\nSo \"ask rerere what it hasn't resolved\" would only safely work for\nthe first kind, where the state in the working tree file is known to\nbe expendable.\n\nIf it can somehow determine paths that have been fully resolved, it\ncan (and should) skip redoing the three-way merge.  And that is\nprobably what the \"if test -s MERGE_RR; then rerere remaining; fi\"\nlogic under discussion is about.\n\nBut that will still risk losing any half-resolution done by external\nmeans (the third category), including manual editing.  Is that a\ngood thing?\n\nPerhaps there were two conflicting hunks and one of them the user\nhas resolved manually, and then the other one was a bit more complex\nthan the user wanted to resolve in the editor and that is why the\nuser is now running \"mergetool\" to resolve it in a GUI.  \"rerere\"\nwill say \"I didn't touch that path\", and \"mergetool\" will happily\nignore user's manual resolution of one hunk in the working tree, and\nthe user ends up redoing the whole three-way merge for the path, no?\n\nEven if you switch that logic from \"asking rerere\" to \"look for\nconflict markers\", it wouldn't change the story.  Perhaps \"rerere\nremaining\" was a useless addition, and instead we probably should\nhave a way to ask \"rerere\" if the working tree file is different\nfrom what the mergy operation left before \"rerere\" tried to work on\nit?  If it is unchanged, then we know nobody (either the user, any\nthird-party mechanism, or rerere) touched it and it is safe for a\nmergetool backend to redo the three-way merge from scratch (i.e. we\nknow that is in the first category).\n\nOtherwise, you are risking to stomp on the change that may have been\ndone between the time the mergy operation was done and \"mergetool\"\nwas started.\n"},{"id":"194469","messageId":"CABURp0rY6SMiP8NKO4RMGvkta_nYubwt4bq3DL7-UEJJPK56cA@mail.gmail.com","threadId":"30835","inReplyTo":"7vmx3i3agg.fsf@alter.siamese.dyndns.org","subject":"Re: MERGE_RR droppings","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-07-02T19:36:32Z","receivedAt":"2012-07-02T19:36:32Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Mon, Jul 2, 2012 at 3:10 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> David Aguilar <davvid@gmail.com> writes:\n>\n>> We can have a \"default\" unmerged files provider that does the\n>> `test -s .../MERGE_RR` check since that would probably deal with\n>> this ugly edge case.\n>>\n>> We can then teach this default thing to be smarter and skip text files\n>> with no merge markers. Junio, is this what you were thinking?\n>> This sounds like a nice way to me.\n>\n> I am not sure what I were thinking ;-) so let me think aloud.\n>\n> In any case, once the user says (either via directly using \"git add\"\n> or using the command via the mergetool) the path is resolved,\n> mergetool would no longer want to touch it, until the user says\n> \"oops, the resolution was a mistake; pleae make it unresolved again\"\n> with something like \"git checkout -m\".  So in this message, I'll\n> think only about the case where the index is still unmerged.\n>\n> The working tree files may be in one of these states:\n>\n>  1. It may still be the same as the conflicted state after the\n>     three-way merge proper gave the user, perhaps with conflict\n>     markers in the text.\n>\n>  2. rerere or some other mechanism (this includes manual editing or\n>     previous run of \"mergetool\") may have resolved the conflict\n>     fully.\n>\n>  3. Or such a mechanism may have only half-resolved the conflict.\n>\n> As far as I can see, the mergetool machinery, once it decides to\n> feed a path to the mergetool backend, ignores what is in the working\n> tree file, and uses the stage #2 (i.e. the state before merge\n> happened) as LOCAL (and stage #1 as BASE, stage #3 as REMOTE) to\n> redo the entire three-way merge from scratch.\n>\n> So \"ask rerere what it hasn't resolved\" would only safely work for\n> the first kind, where the state in the working tree file is known to\n> be expendable.\n\nYes, and specifically it would only work with 'rerere' and not the\n\"future enhancements and third-party mechanisms\" you imagined earlier.\n\n> If it can somehow determine paths that have been fully resolved, it\n> can (and should) skip redoing the three-way merge.  And that is\n> probably what the \"if test -s MERGE_RR; then rerere remaining; fi\"\n> logic under discussion is about.\n>\n> But that will still risk losing any half-resolution done by external\n> means (the third category), including manual editing.  Is that a\n> good thing?\n>\n> Perhaps there were two conflicting hunks and one of them the user\n> has resolved manually, and then the other one was a bit more complex\n> than the user wanted to resolve in the editor and that is why the\n> user is now running \"mergetool\" to resolve it in a GUI.  \"rerere\"\n> will say \"I didn't touch that path\", and \"mergetool\" will happily\n> ignore user's manual resolution of one hunk in the working tree, and\n> the user ends up redoing the whole three-way merge for the path, no?\n\nI think this is the case in practice, but the workdir file should\nstill be available to the mergetool if it is smart enough to consider\nit.  It is not quite stomped on, though the machinery does expect the\nmerge-result to wind up in the workdir file.\n\nConsider also that after a \"successful\" mergetool execution, the file\nis automatically marked as resolved by being added to the index.\nTherefore, it is not practical for mergetool to be used first to\npartially merge the file in the hopes of using another tool to\ncomplete the merge in a later step.  This is opposite from the default\nand recommended operation mode of rerere, which does NOT add the\nresulting resolution to the index.  And this results in more \"states\"\nfor a file to be in after a merge.\n\n> Even if you switch that logic from \"asking rerere\" to \"look for\n> conflict markers\", it wouldn't change the story.\n\nNo, this really calls for some meta-information storage about the\nfile's status, such as marking the file as \"fully resolved\" or\n\"partially resolved\" in some sort of checklist, maybe even with line\nnumbers indicating regions in :1:file.txt and :3:file.txt which are\nstill TBD (though this \"resolved regions\" business seems useless to me\nright now). Maybe some merge tool can learn to preserve the\npartially-resolved file as a partial target in some kind of iterative\nprocess.  But to do that, we need to have some way to manage this\nmeta-info.  The index comes to mind as a likely container, but a state\nfile similar to MERGE_RR is easier and safer (unless the index already\nhas some extensibility here).\n\n> Perhaps \"rerere\n> remaining\" was a useless addition, and instead we probably should\n> have a way to ask \"rerere\" if the working tree file is different\n> from what the mergy operation left before \"rerere\" tried to work on\n> it?  If it is unchanged, then we know nobody (either the user, any\n> third-party mechanism, or rerere) touched it and it is safe for a\n> mergetool backend to redo the three-way merge from scratch (i.e. we\n> know that is in the first category).\n\nYes, though technically the user could have previously recorded the\nfile as \"resolved\" with the change markers in place, so an unchanged\nfile might NOT mean that it still needs to be resolved.  This seems\nlike a silly case to consider, but I can see it extending to other\nkinds of diff-markers which do not show up in the file itself, for\nexample, and we would be no further.\n\n> Otherwise, you are risking to stomp on the change that may have been\n> done between the time the mergy operation was done and \"mergetool\"\n> was started.\n\nSo  'mergetool' is not useful to examine the result of a successful\nrerere-merge, for example. because it will certainly ignore the\nalready-merged bits in the workdir.  We also do not want to ask the\nuser to reconsider the rerere resolved files during her mergetool\nsession.\n\nThere certainly are way more corner cases in this niche than I ever expected.\n\nThe normal rerere action is to apply previous resolutions in the\nworkdir but not in the index.  This is so the user can recognize that\nthe change needs closer inspection because she does not trust rerere\nto always merge the project perfectly.  These files still appear in\nls-files --unmerged.  rerere-remaining allows git to recognize those\nfiles. It allows git-mergetool to merge the files rerere did not touch\nand also avoid stomping on the rerere resolutions which are waiting in\nthe workdir for the user's attention.\n\nI personally do not like all these slightly-different cases.  It\ncauses the rebase-mergtool-continue cycle to lose all consistency for\nme.    I am eager to help sort this out into something reasonable. I\nhope we can decide what that should look like.\n\nIn the meantime, I will try to find a way to clean out stray MERGE_RR\nfiles before I stash-pop.\n\nPhil\n"}]}