{"thread":{"id":"59768","subject":"[not even design notes yet] teaching rerere to remember removal?","startedAt":"2023-05-18T22:18:08Z","lastAt":"2023-05-19T07:52:22Z","messageCount":2,"participants":["Junio C Hamano","Oswald Buddenhagen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"477569","messageId":"xmqq353ts2qt.fsf@gitster.g","threadId":"59768","inReplyTo":null,"subject":"[not even design notes yet] teaching rerere to remember removal?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-05-18T22:18:02Z","receivedAt":"2023-05-18T22:18:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This is more like just an early scratches on paper that might some\nday turn into a design.\n\nA side branch can remove path P, while the mainline, since the side\nbranch forked from it, can modify P.  When such a side branch is\nmerged to the mainilne, we would see a 'one side modified, the other\nside removed' merge conflict.  The change made on the mainline may\nbe of small significance (e.g. code restructuring), while the\nremoval done on the side branch may be of bigger significance\n(e.g. the command implemented by the file P is no longer necessary).\n\nFor safety, the rerere mechanism does not unconditionally remember\nsuch a removal and replay.  When you resolve such a conflict in\nfavor of removal of P after looking at it, the decision to remove it\nmay be reasonable, but if you let the mainline further tweak P\nwithout knowing other party working on the side branch is planning\nto remove it, at some point you may want to reconsider the decision\nto discard the changes made to P on the mainline.  The discarded\nchanges may not be important enough to make you want to resurrect\nthe change and side-port to another path, but at least you would\nwant to have a chance to double check and decide that the new\nwork the mainline did to P is still discardable.\n\nSo I am wondering what should be used as the record of \"if the other\nbranch made this change, we have seen this conflict already, and we\nknow it is safe to resolve it to remove the path\".  As such a\nconflict will leave either stages 1 & 2 (we modified, while they\nremoved), or 1 & 3 (we removed, while they kept working on it), e.g.\n\n    $ git ls-files -u\n    100644 d1d63feaa9e299ace44d228176cd2b4335193569 1\tt/helper/test-fast-rebase.c\n    100644 cac20a72b3fcb52c5ccb66cbbb1679ecb8f39f97 2\tt/helper/test-fast-rebase.c\n\none idea is to take a textual diff of these two stages:\n\n    $ git diff :{1,2}:t/helper/test-fast-rebase.c\n    diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c\n    index d1d63feaa9..cac20a72b3 100644\n    --- a/t/helper/test-fast-rebase.c\n    +++ b/t/helper/test-fast-rebase.c\n    @@ -12,15 +12,16 @@\n\n     #define USE_THE_INDEX_VARIABLE\n     #include \"test-tool.h\"\n    -#include \"cache.h\"\n     #include \"cache-tree.h\"\n     #include \"commit.h\"\n     #include \"environment.h\"\n     #include \"gettext.h\"\n    +#include \"hash.h\"\n     #include \"hex.h\"\n     #include \"lockfile.h\"\n     #include \"merge-ort.h\"\n     #include \"object-name.h\"\n    +#include \"read-cache-ll.h\"\n     #include \"refs.h\"\n     #include \"revision.h\"\n     #include \"sequencer.h\"\n\nand record that when we that one side made this change to a path\nwhile the other side removed the path, we know it is safe to resolve\nsuch a conflict to remove the path.\n\nThe \"rerere conflict ID\" (the directory name under .git/rerere/ that\neach rerere database entry uses) is most likely the SHA-1 hash of the\nabove patch text, with pathname and line numbers redacted.\n\n"},{"id":"477592","messageId":"ZGcqgR5RimHJiwFv@ugly","threadId":"59768","inReplyTo":"xmqq353ts2qt.fsf@gitster.g","subject":"Re: [not even design notes yet] teaching rerere to remember removal?","fromName":"Oswald Buddenhagen","fromEmail":"oswald.buddenhagen@gmx.de","sentAt":"2023-05-19T07:51:29Z","receivedAt":"2023-05-19T07:52:22Z","isPatch":false,"sender":{"key":"oswald.buddenhagen@gmx.de","avatar":"https://avatars.githubusercontent.com/u/812380?v=4"},"body":"On Thu, May 18, 2023 at 03:18:02PM -0700, Junio C Hamano wrote:\n>So I am wondering what should be used as the record of \"if the other\n>branch made this change, we have seen this conflict already, and we\n>know it is safe to resolve it to remove the path\".\n>\ni suppose i may be missing the obvious, but why not just treat the \nremoval as a full diff (like a traditional patch would do) and remember \nthe resolution accordingly like any other conflict?\n\nthe key to making this useful is presenting followup conflicts in a \nsensible way that highlights where they actually are, but that would be \nuseful regardless - i often run into this while rebasing, where finding \nthat one line that i added to a bigger section that was (re-)moved \nrequires so much attention that i instead look at the original patch \nrather than the conflict to see what it was. (note that i'm using diff3 \nmarkers.)\n\nregards,\nossi\n"}]}