{"thread":{"id":"39826","subject":"git rerere is confused with identical conflicts in multiple files","startedAt":"2015-07-10T08:04:17Z","lastAt":"2015-07-10T15:21:52Z","messageCount":3,"participants":["Markos Chandras","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"265974","messageId":"559F7C81.50805@imgtec.com","threadId":"39826","inReplyTo":null,"subject":"git rerere is confused with identical conflicts in multiple files","fromName":"Markos Chandras","fromEmail":"markos.chandras@imgtec.com","sentAt":"2015-07-10T08:04:17Z","receivedAt":"2015-07-10T08:04:17Z","isPatch":false,"sender":{"key":"markos.chandras@imgtec.com","avatar":null},"body":"Hi,\n\n(Please keep me on CC as I am not subscribed to the list)\n\nI am having a weird problem when merging a branch which causes some\nconflicts\n\nThis is the initial status for the rerere cache\n\n$ tree .git/rr-cache\n.git/rr-cache [error opening dir]\n\n0 directories, 0 files\n\n\nI then go ahead and merge the said branch and I end up with the\nfollowing conflicts\n\nAuto-merging arch/mips/mm/sc-mips.c\nAuto-merging arch/mips/mm/c-r4k.c\nCONFLICT (content): Merge conflict in arch/mips/mm/c-r4k.c\nAuto-merging arch/mips/kernel/traps.c\nCONFLICT (content): Merge conflict in arch/mips/kernel/traps.c\nAuto-merging arch/mips/kernel/spram.c\nCONFLICT (content): Merge conflict in arch/mips/kernel/spram.c\nAuto-merging arch/mips/kernel/idle.c\nCONFLICT (content): Merge conflict in arch/mips/kernel/idle.c\nAuto-merging arch/mips/kernel/cpu-probe.c\nAuto-merging arch/mips/include/asm/mipsregs.h\nAuto-merging arch/mips/include/asm/cpu.h\nCONFLICT (content): Merge conflict in arch/mips/include/asm/cpu.h\nAuto-merging arch/mips/include/asm/cpu-type.h\nCONFLICT (content): Merge conflict in arch/mips/include/asm/cpu-type.h\nRecorded preimage for 'arch/mips/include/asm/cpu-type.h'\nRecorded preimage for 'arch/mips/include/asm/cpu.h'\nAutomatic merge failed; fix conflicts and then commit the result.\n\nAs you see, git only records two preimage files instead of 6.\n\nthe rr-cache is like this now\n\n$ tree .git/rr-cache\n.git/rr-cache\n├── 5563edc0fb427275a0ca5677c93c40def8b53258\n│   └── preimage\n└── f175ff6228f624296b661664bce4ab4e84d712cc\n    └── preimage\n\n2 directories, 2 files\n\nand .git/MERGE_RR\n\n$ cat .git/MERGE_RR\n5563edc0fb427275a0ca5677c93c40def8b53258\narch/mips/include/asm/cpu-type.hf175ff6228f624296b661664bce4ab4e84d712cc\n\narch/mips/include/asm/cpu.h5563edc0fb427275a0ca5677c93c40def8b53258\n   arch/mips/kernel/idle.c5563edc0fb427275a0ca5677c93c40def8b53258\narch/mips/kernel/spram.c5563edc0fb427275a0ca5677c93c40def8b53258\narch/mips/kernel/traps.c5563edc0fb427275a0ca5677c93c40def8b53258\narch/mips/mm/c-r4k.c\n\nso as you see, multiple files share the same hash. That's probably\nbecause the \"conflicting context ( the part between >>> <<<<)\" in every\nfile but cpu.h is identical and git seems to calculate the hash purely\non the conflicting context. That makes git rerere thinks that it only\nhas to resolve 2 conflicts instead of 6.\n\nDoes anyone have an idea how to resolve that? If my assumption is\ncorrect (I only looked at the git code briefly) I believe it would make\nsense to throw the filepath into the sha1 calculation as well in order\nto ensure it will not conflict with similar changes across different files.\n\n-- \nmarkos\n"},{"id":"265985","messageId":"xmqqvbdsksmv.fsf@gitster.dls.corp.google.com","threadId":"39826","inReplyTo":"559F7C81.50805@imgtec.com","subject":"Re: git rerere is confused with identical conflicts in multiple files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-07-10T14:13:28Z","receivedAt":"2015-07-10T14:13:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markos Chandras <Markos.Chandras@imgtec.com> writes:\n\n> $ cat .git/MERGE_RR\n> 5563edc0fb427275a0ca5677c93c40def8b53258\n> arch/mips/include/asm/cpu-type.hf175ff6228f624296b661664bce4ab4e84d712cc\n>\n> arch/mips/include/asm/cpu.h5563edc0fb427275a0ca5677c93c40def8b53258\n>    arch/mips/kernel/idle.c5563edc0fb427275a0ca5677c93c40def8b53258\n> arch/mips/kernel/spram.c5563edc0fb427275a0ca5677c93c40def8b53258\n> arch/mips/kernel/traps.c5563edc0fb427275a0ca5677c93c40def8b53258\n> arch/mips/mm/c-r4k.c\n>\n> so as you see, multiple files share the same hash. That's probably\n> because the \"conflicting context ( the part between >>> <<<<)\" in every\n> file but cpu.h is identical and git seems to calculate the hash purely\n> on the conflicting context. That makes git rerere thinks that it only\n> has to resolve 2 conflicts instead of 6.\n\nYes, that is by design, and should not change.  The thing is, you do\nwant to share the same resolution across files, regardless of the\npath, when the recorded resolution replays cleanly [*1*].\n\n> Does anyone have an idea how to resolve that? If my assumption is\n> correct (I only looked at the git code briefly) I believe it would make\n> sense to throw the filepath into the sha1 calculation as well in order\n> to ensure it will not conflict with similar changes across different files.\n\nInteresting coincidence, but I have been looking at this for the\npast few weeks myself but when you are doing the maintainer of a\nreasonably active project, time for your own development is hard\nto come by X-<.\n\nMy current plan is to allow hashing exactly the same way, but\nrecording different preimage/postimage pairs as necessary.\n\nRight now we do something like this:\n\n    - See conflict; compute conflict ID.\n    - Does rr-cache/$ID/ exist?\n      - If not, record rr-cache/$ID/preimage\n    - Add $ID to MERGE_RR.\n\nAnd then for each $ID (and path) in MERGE_RR:\n\n    - Does rr-cache/$ID/postimage exist?\n      - If so, attempt three-way merge using preimage, postimage and\n        thisimage.\n        - Did three-way merge replay cleanly?  If so, be happy.\n        - Did three-way merge conflict?  If so, punt.\n    - Does path still have conflicts?\n      - If not, record rr-cache/$ID/postimage.\n\nThe thing to fix is \"did it conflict, if so punt\" step.  Within the\nsame conflict ID, we would introduce the concept of \"variant\", and\nallow you to keep rr_cache/$ID/{preimage,postimage}.$variant.  The\nfirst part of the per MERGE_RR entry process would instead go like\nso:\n\n    - Does rr-cache/$ID/ has one or more postimages?\n      - If so, for each variant, attempt three-way merge using\n        preimage, postimage and thisimage.\n      - Did one of the three-way merges replay cleanly?\n        - If so, be happy.\n        - If not, assign an unused variant to this path and change\n          its MERGE_RR entry from $ID to $ID.$variant\n\n    - Does path still have conflicts?\n      - If not, record rr-cache/$ID/postimage for \"variant\".\n\nThe current \"preimage\", \"postimage\" will be kept as the first\nvariant in rr-cache/$ID/ directory.  The second variant will likely\nbe named (I don't have a code yet but have been slowly laying out\nthe fundation to allow us to do this) \"preimage.0\" and \"postimage.0\",\nand the third one will have \".1\" suffix.\n\nThis approach has the added benefit that existing rr-cache entries\nwill stay valid (in addition to being able to replay the same\nresolution even after you renamed the path that conflict, unlike the\ncase when you hashed the pathname together to break the conflict ID\ncomputtion).\n\nA WIP has been published on jc/rerere topic in my repository for the\npast few weeks, but I haven't reached the interesting \"multi variant\"\npart yet, as I said.\n\n\n[Footnote]\n\n*1* My experience urges me to add \"And most of the time, the same\nresolution does apply cleanly even to multiple paths conflicted in\nthe same merge\" to that sentence.\n"},{"id":"265987","messageId":"559FE310.5060204@imgtec.com","threadId":"39826","inReplyTo":"xmqqvbdsksmv.fsf@gitster.dls.corp.google.com","subject":"Re: git rerere is confused with identical conflicts in multiple files","fromName":"Markos Chandras","fromEmail":"markos.chandras@imgtec.com","sentAt":"2015-07-10T15:21:52Z","receivedAt":"2015-07-10T15:21:52Z","isPatch":false,"sender":{"key":"markos.chandras@imgtec.com","avatar":null},"body":"Hi,\n\nOn 07/10/2015 03:13 PM, Junio C Hamano wrote:\n> Markos Chandras <Markos.Chandras@imgtec.com> writes:\n> \n>> $ cat .git/MERGE_RR\n>> 5563edc0fb427275a0ca5677c93c40def8b53258\n>> arch/mips/include/asm/cpu-type.hf175ff6228f624296b661664bce4ab4e84d712cc\n>>\n>> arch/mips/include/asm/cpu.h5563edc0fb427275a0ca5677c93c40def8b53258\n>>    arch/mips/kernel/idle.c5563edc0fb427275a0ca5677c93c40def8b53258\n>> arch/mips/kernel/spram.c5563edc0fb427275a0ca5677c93c40def8b53258\n>> arch/mips/kernel/traps.c5563edc0fb427275a0ca5677c93c40def8b53258\n>> arch/mips/mm/c-r4k.c\n>>\n>> so as you see, multiple files share the same hash. That's probably\n>> because the \"conflicting context ( the part between >>> <<<<)\" in every\n>> file but cpu.h is identical and git seems to calculate the hash purely\n>> on the conflicting context. That makes git rerere thinks that it only\n>> has to resolve 2 conflicts instead of 6.\n> \n> Yes, that is by design, and should not change.  The thing is, you do\n> want to share the same resolution across files, regardless of the\n> path, when the recorded resolution replays cleanly [*1*].\n\nI see.\n\n> [...]\n> \n> The thing to fix is \"did it conflict, if so punt\" step.  Within the\n> same conflict ID, we would introduce the concept of \"variant\", and\n> allow you to keep rr_cache/$ID/{preimage,postimage}.$variant.  The\n> first part of the per MERGE_RR entry process would instead go like\n> so:\n> \n>     - Does rr-cache/$ID/ has one or more postimages?\n>       - If so, for each variant, attempt three-way merge using\n>         preimage, postimage and thisimage.\n>       - Did one of the three-way merges replay cleanly?\n>         - If so, be happy.\n>         - If not, assign an unused variant to this path and change\n>           its MERGE_RR entry from $ID to $ID.$variant\n> \n>     - Does path still have conflicts?\n>       - If not, record rr-cache/$ID/postimage for \"variant\".\n> \n> The current \"preimage\", \"postimage\" will be kept as the first\n> variant in rr-cache/$ID/ directory.  The second variant will likely\n> be named (I don't have a code yet but have been slowly laying out\n> the fundation to allow us to do this) \"preimage.0\" and \"postimage.0\",\n> and the third one will have \".1\" suffix.\n> \n> This approach has the added benefit that existing rr-cache entries\n> will stay valid (in addition to being able to replay the same\n> resolution even after you renamed the path that conflict, unlike the\n> case when you hashed the pathname together to break the conflict ID\n> computtion).\n\nI understand. Thanks for the explanation.\n\n> \n> A WIP has been published on jc/rerere topic in my repository for the\n> past few weeks, but I haven't reached the interesting \"multi variant\"\n> part yet, as I said.\n\nI am happy to test it when you have something more complete. If you can\nreply to this e-mail when the 'variant' patch finds its way into the\nmaster branch that would be great as well\n\n-- \nmarkos\n"}]}