{"thread":{"id":"60749","subject":"Custom merge drivers: accessing the pathnames and revisions of the files being merged","startedAt":"2024-01-16T08:49:16Z","lastAt":"2024-01-16T22:00:00Z","messageCount":3,"participants":["Antonin Delpeuch","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"486823","messageId":"8bb5e41e-4db9-4527-8492-3aca6a0f40bf@delpeuch.eu","threadId":"60749","inReplyTo":null,"subject":"Custom merge drivers: accessing the pathnames and revisions of the files being merged","fromName":"Antonin Delpeuch","fromEmail":"antonin@delpeuch.eu","sentAt":"2024-01-16T08:44:02Z","receivedAt":"2024-01-16T08:49:16Z","isPatch":false,"sender":{"key":"antonin@delpeuch.eu","avatar":"https://avatars.githubusercontent.com/u/309908?v=4"},"body":"Hello,\n\nCustom merge drivers [1] provide a convenient way to extend Git's merge \nalgorithms. But as far as I can tell, there is no way to access the \npathnames and revisions of the files to merge. Those would be very \nuseful to generate informative conflict markers, like the built-in merge \nstrategies do.\n\nFor instance, when merging with the ort strategy and diff3 conflict \nstyle, I get markers such as:\n\n<<<<<<< HEAD:main/my_file.txt\n…\n||||||| 194c4190b:main/my_file.txt\n…\n=======\n…\n >>>>>>> origin/branch:main/my_renamed_file.txt\n\nThose strings at the end of conflict markers, with the revision and the \npathname, are very useful to understand which parts are coming from where.\n\nWhen implementing a custom merge driver, I don't see how to access this \ninformation to include it in the conflict markers. Custom merge drivers \nare typically invoked on temporary files generated by Git with \nuninformative paths, such as \".merge_file_NgiKjJ\".\n\nTherefore, my merge driver is only able to generate conflicts which look \nlike this:\n\n<<<<<<< .merge_file_NgiKjJ\n…\n||||||| .merge_file_D1XtCW\n…\n=======\n…\n >>>>>>> .merge_file_WbmrBA\n\nOf course, in a given rebase/merge session, the order in which the \nconflicting parts will be presented will remain consistent, so I will \ngenerally be able to remember which revision each part corresponds to,\nbut it's still a mental load I would ideally try to avoid. Also, if the \nrename detection heuristics have false positives, then I can get merge \nconflicts which come from unrelated files: in that case it is very \nuseful to see the pathnames, to understand this situation better.\n\nSo, I wonder: would people be open to exposing additional parameters to \nmerge drivers? For instance we could add parameters \"%X\", \"%Y\" \"%Z\" to \nexpose those \"revision:pathname\" strings for each part. (I think colons \ncannot be part of revision names, so this can be parsed unambiguously by \nthe custom merge driver to recover the revision and pathname \nindependently, if needed.)\n\nI would be happy to submit a patch for this if you think this makes \nsense. If it is already possible to access this information in another \nway, I would like to work on documenting that.\n\nBest wishes,\nAntonin\n\n[1]: https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver\n"},{"id":"486853","messageId":"xmqqedeh1816.fsf@gitster.g","threadId":"60749","inReplyTo":"8bb5e41e-4db9-4527-8492-3aca6a0f40bf@delpeuch.eu","subject":"Re: Custom merge drivers: accessing the pathnames and revisions of the files being merged","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-01-16T17:51:17Z","receivedAt":"2024-01-16T17:51:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Antonin Delpeuch <antonin@delpeuch.eu> writes:\n\n> So, I wonder: would people be open to exposing additional parameters\n> to merge drivers? For instance we could add parameters \"%X\", \"%Y\" \"%Z\"\n> to expose those \"revision:pathname\" strings for each part. (I think\n> colons cannot be part of revision names, so this can be parsed\n> unambiguously by the custom merge driver to recover the revision and\n> pathname independently, if needed.)\n\nThe last time this changed was in ef45bb1f (ll-merge: pass the\noriginal path to external drivers, 2015-06-04).  \n\nI may not necessarily endorse the choice of XYZ [*], but I do not\nfundamentally oppose to such a new feature existing.  The mechanism\nto define a custom merge driver is designed to be future-proof in\nthat only the parameters it uses is given as the value of\nmerge.*.driver variable, so it is not a problem that existing merge\ndrivers will not know what to do with \"pathname in the common\nancestor\", \"pathname on our side\", and \"pathname on their side\".\n\n\n[Footnote]\n\n * Whatever letters we choose, they must have mnemonic value that\n   signals two of them are the both sides of the merge that are\n   equal participants, and the other one is the old-file, their\n   common ancestor that plays quite a different from these two in\n   the merge.  I cannot tell which one of the XYZ would be the more\n   special than other two, which is the primary reason why I do not\n   know if XYZ is a good idea.\n\n\n"},{"id":"486871","messageId":"4e6dddd1-2149-403b-82ed-b822c4b0c31e@delpeuch.eu","threadId":"60749","inReplyTo":"xmqqedeh1816.fsf@gitster.g","subject":"Re: Custom merge drivers: accessing the pathnames and revisions of the files being merged","fromName":"Antonin Delpeuch","fromEmail":"antonin@delpeuch.eu","sentAt":"2024-01-16T21:59:53Z","receivedAt":"2024-01-16T22:00:00Z","isPatch":false,"sender":{"key":"antonin@delpeuch.eu","avatar":"https://avatars.githubusercontent.com/u/309908?v=4"},"body":"Thanks a lot for your insights! Yes I also very much appreciate that the \nextension point is built in such a way that introducing new parameters \nis non-breaking.\n\nOn 16/01/2024 18:51, Junio C Hamano wrote:\n>   * Whatever letters we choose, they must have mnemonic value that\n>     signals two of them are the both sides of the merge that are\n>     equal participants, and the other one is the old-file, their\n>     common ancestor that plays quite a different from these two in\n>     the merge.  I cannot tell which one of the XYZ would be the more\n>     special than other two, which is the primary reason why I do not\n>     know if XYZ is a good idea.\n\nThat makes perfect sense. How about:\n\n- %S for the \"source\" pathname (corresponding to the %O file)\n\n- %X for the first side of the merge (corresponding to the %A file)\n\n- %Y for the second side of the merge (corresponding to the %B file)\n\nAnyway, I'll try to work on a patch: it should be easy to adapt the \nletters to any other choice.\n\nBest,\n\nAntonin\n\n"}]}