{"thread":{"id":"58361","subject":"Potential problems with url.<base>.insteadOf","startedAt":"2022-08-25T23:47:23Z","lastAt":"2022-08-26T16:16:44Z","messageCount":5,"participants":["Javier Mora","Andreas Schwab","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"461972","messageId":"CAH1-q0iPsnkypiF=2LRgXwNqE_+R0gj706FCKgqGEUum+OAhQg@mail.gmail.com","threadId":"58361","inReplyTo":null,"subject":"Potential problems with url.<base>.insteadOf","fromName":"Javier Mora","fromEmail":"cousteaulecommandant@gmail.com","sentAt":"2022-08-25T23:47:08Z","receivedAt":"2022-08-25T23:47:23Z","isPatch":false,"sender":{"key":"cousteaulecommandant@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6584870?v=4"},"body":"The choice of `url.<replacement>.insteadOf <original>` as a way to\nreplace URLs is not only a bit confusing, as it has already been\ndiscussed[1], but also presents some problems and makes it impossible\nto achieve certain configurations.\n[1] https://public-inbox.org/git/20181122173109.GI28192@sigill.intra.peff.net/\n\nSCENARIO 1:\nI want to replace all references to the (now defunct)\n'http://example.org/' to the new server, 'http://example.com/'.\n\nOK, that is easy (even if a bit counter-intuitive).  Just do:\ngit config url.'http://example.com/'.insteadOf 'http://example.org/'\n\nSCENARIO 2:\nI want to replace BOTH 'http://example.org/' and 'http://example.net/'\nwith 'http://example.com/'.\n\nWell, now I have a problem.  If I do:\n\ngit config url.'http://example.com/'.insteadOf 'http://example.org/'\ngit config url.'http://example.com/'.insteadOf 'http://example.net/'\n\nthe second entry will replace the first, since I'm just using the\nconfig entry `url.http://example.com/.insteadOf` twice.\nSo, it appears that this simply cannot be done in Git!\n(Maybe if I daisy-chain them?  like .org -> .net and then .net -> .com)\n\nSCENARIO 3:\nI had set 'http://example.org/' to redirect to 'http://example.com/',\nbut that was a mistake, or there has been a migration, and it should\nbe 'http://example.edu/'.\n\nThe \"natural reaction\" here is to rewrite the command with the right\nreplacement value, but if I write:\n\ngit config url.'http://example.com/'.insteadOf 'http://example.org/'\ngit config url.'http://example.edu/'.insteadOf 'http://example.org/'\n\nthe second command doesn't replace the first, but instead is added alongside.\nI'll need to manually unset the first:\n\ngit config --unset url.'http://example.com/'.insteadOf\n\nSCENARIO 4:\nFor some reason (e.g. because I messed up in scenario 3), there are\ntwo insteadOf entries in the git config with the same value.\nThis results in an ambiguous case, and Git does nothing to prevent it!\nThe documentation says that the longest insteadOf value wins, but both\nhave the same length since both are the same URL.\n\n----\n\nSOLUTION:\nNone of this would happen if, instead of a\n`url.<replacement>.insteadOf <original>` approach, Git followed the\nopposite approach, `url.<original>.replaceWith <replacement>` (or\n`rewriteTo`, as it is suggested in [1]).\nSo this approach is not only more intuitive and looks more resilient,\nit IS more resilient.\n\nLet's have a look at the previous scenarios again:\n\nSCENARIO 1:\nAbout as easy as before, except that it follows a more readable \"from\n... to ...\" scheme:\n\ngit config url.'http://example.org/'.replaceWith 'http://example.com/'\n\n(which I suspect will also give Git less trouble to find in the\nconfig, or at least it feels like it would).\n\nSCENARIO 2:\nEasy peasy.  Two different sources with the same target = two\ndifferent keys with the same value:\n\ngit config url.'http://example.org/'.replaceWith 'http://example.com/'\ngit config url.'http://example.net/'.replaceWith 'http://example.com/'\n\nAnd we no longer have the problem that we cannot replace two different\nURLs with the same replacement.\n\nSCENARIO 3:\nRewriting the rule will simply overwrite the old value:\n\ngit config url.'http://example.org/'.replaceWith 'http://example.com/'\ngit config url.'http://example.org/'.replaceWith 'http://example.edu/'\n\nSCENARIO 4:\nScenario 4 simply cannot happen with this approach under normal\ncircumstances because there can't be two entries with the same key but\ndifferent values, unless the user edited the config file manually.\n(But there CAN be two entries with different keys and the same value,\nwhich is what caused scenario 4 before.)\n\nSo, it might be a good idea to implement and recommend the\n`replaceWith` (or `rewriteTo`) syntax, and deprecate the `insteadOf`\nsyntax (although it'll probably be necessary to keep it around for\nbackwards compatibility).\n"},{"id":"461980","messageId":"87a67rjxb6.fsf@linux-m68k.org","threadId":"58361","inReplyTo":"CAH1-q0iPsnkypiF=2LRgXwNqE_+R0gj706FCKgqGEUum+OAhQg@mail.gmail.com","subject":"Re: Potential problems with url.<base>.insteadOf","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2022-08-26T07:09:17Z","receivedAt":"2022-08-26T07:18:13Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"On Aug 26 2022, Javier Mora wrote:\n\n> Well, now I have a problem.  If I do:\n>\n> git config url.'http://example.com/'.insteadOf 'http://example.org/'\n> git config url.'http://example.com/'.insteadOf 'http://example.net/'\n\ngit config --add url.'http://example.com/'.insteadOf 'http://example.net/'\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1\n\"And now for something completely different.\"\n"},{"id":"461986","messageId":"CAH1-q0j8a4q47UOBvUp0W0JgF+W7J+EQLLRhv9hx-dxdhqSYqA@mail.gmail.com","threadId":"58361","inReplyTo":"87a67rjxb6.fsf@linux-m68k.org","subject":"Re: Potential problems with url.<base>.insteadOf","fromName":"Javier Mora","fromEmail":"cousteaulecommandant@gmail.com","sentAt":"2022-08-26T09:34:09Z","receivedAt":"2022-08-26T09:34:25Z","isPatch":false,"sender":{"key":"cousteaulecommandant@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6584870?v=4"},"body":"El vie, 26 ago 2022 a las 9:09, Andreas Schwab\n(<schwab@linux-m68k.org>) escribió:\n>\n> On Aug 26 2022, Javier Mora wrote:\n>\n> > Well, now I have a problem.  If I do:\n> >\n> > git config url.'http://example.com/'.insteadOf 'http://example.org/'\n> > git config url.'http://example.com/'.insteadOf 'http://example.net/'\n>\n> git config --add url.'http://example.com/'.insteadOf 'http://example.net/'\n\nWell, that was embarrassing...\nMy bad; I didn't know about the `--add` option (nor that gitconfig\nsupported multi-value options, for that matter, but that's on me for\nnot reading the whole manpage).\nMaybe the manpage section on `insteadOf` should mention that it's a\nmulti-value option, but I see that this is not a bug as I thought it\nwas.  (If anything, a not-very-intuitive feature, but that's a\ndifferent matter.)\n\nOne minor issue I still see is the fact that adding the same insteadOf\nkey-value pair multiple times will result in the same line being added\nmultiple times unless you explicitly delete it first; there doesn't\nseem to be an easy way to \"add key-value pair if it doesn't exist\nyet\".  (The closest seems to be `--replace-all`, but that complicates\nthings a bit.)\n"},{"id":"461999","messageId":"xmqq7d2v0yqg.fsf@gitster.g","threadId":"58361","inReplyTo":"CAH1-q0iPsnkypiF=2LRgXwNqE_+R0gj706FCKgqGEUum+OAhQg@mail.gmail.com","subject":"Re: Potential problems with url.<base>.insteadOf","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-08-26T16:13:27Z","receivedAt":"2022-08-26T16:13:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Javier Mora <cousteaulecommandant@gmail.com> writes:\n\n> The choice of `url.<replacement>.insteadOf <original>` as a way to\n> replace URLs is not only a bit confusing, as it has already been\n> discussed[1], but also presents some problems and makes it impossible\n> to achieve certain configurations.\n> [1] https://public-inbox.org/git/20181122173109.GI28192@sigill.intra.peff.net/\n>\n> SCENARIO 1:\n> I want to replace all references to the (now defunct)\n> 'http://example.org/' to the new server, 'http://example.com/'.\n>\n> OK, that is easy (even if a bit counter-intuitive).  Just do:\n> git config url.'http://example.com/'.insteadOf 'http://example.org/'\n>\n> SCENARIO 2:\n> I want to replace BOTH 'http://example.org/' and 'http://example.net/'\n> with 'http://example.com/'.\n\nSo, you want to end up with\n\n    [url \"http://example.com/\"]\n\tinsteadOf = http://example.org\n\tinsteadOf = http://example.net\n\nbut you cannot get there with only \"git config VARIABLE VALUE\",\nbecause that syntax is used to clear the existing values for\nVARIRABLE before setting it to VALUE.\n\nHave you tried\n\n    $ git config url.http://example.com/.insteadof http://example.org\n\nthat clears existing values for url.http://example.com/.insteadof\nand sets it to \"http://example.org\", then immediately follow it with\n\n    $ git config --add url.http://example.com/.insteadof http://example.net\n\nthat keeps existing values for url.http://example.com/.insteadof\nand adds another value to the same variable?\n\n\n"},{"id":"462000","messageId":"xmqq35dj0yl3.fsf@gitster.g","threadId":"58361","inReplyTo":"CAH1-q0iPsnkypiF=2LRgXwNqE_+R0gj706FCKgqGEUum+OAhQg@mail.gmail.com","subject":"Re: Potential problems with url.<base>.insteadOf","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-08-26T16:16:40Z","receivedAt":"2022-08-26T16:16:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Javier Mora <cousteaulecommandant@gmail.com> writes:\n\n> This results in an ambiguous case, and Git does nothing to prevent it!\n> The documentation says that the longest insteadOf value wins, but both\n> have the same length since both are the same URL.\n\nThe longest has this case in mind:\n\n    [url \"A\"] insteadof = https://example.com/\n    [url \"B\"] insteadof = https://example.com/special/\n\nSo \"A\" is used as a replacement for the whole site, except for the\nspecial hierarchy that is rewritten to \"B\".\n\nGetting rid of what you no longer need with \"config --unset\" is the\nright thing to do, and you did fine in the previous example.\n"}]}