The choice of `url.<replacement>.insteadOf <original>` as a way to replace URLs is not only a bit confusing, as it has already been discussed[1], but also presents some problems and makes it impossible to achieve certain configurations. [1] https://public-inbox.org/git/20181122173109.GI28192@xxxxxxxxxxxxxxxxxxxxx/ SCENARIO 1: I want to replace all references to the (now defunct) 'http://example.org/' to the new server, 'http://example.com/'. OK, that is easy (even if a bit counter-intuitive). Just do: git config url.'http://example.com/'.insteadOf 'http://example.org/' SCENARIO 2: I want to replace BOTH 'http://example.org/' and 'http://example.net/' with 'http://example.com/'. Well, now I have a problem. If I do: git config url.'http://example.com/'.insteadOf 'http://example.org/' git config url.'http://example.com/'.insteadOf 'http://example.net/' the second entry will replace the first, since I'm just using the config entry `url.http://example.com/.insteadOf` twice. So, it appears that this simply cannot be done in Git! (Maybe if I daisy-chain them? like .org -> .net and then .net -> .com) SCENARIO 3: I had set 'http://example.org/' to redirect to 'http://example.com/', but that was a mistake, or there has been a migration, and it should be 'http://example.edu/'. The "natural reaction" here is to rewrite the command with the right replacement value, but if I write: git config url.'http://example.com/'.insteadOf 'http://example.org/' git config url.'http://example.edu/'.insteadOf 'http://example.org/' the second command doesn't replace the first, but instead is added alongside. I'll need to manually unset the first: git config --unset url.'http://example.com/'.insteadOf SCENARIO 4: For some reason (e.g. because I messed up in scenario 3), there are two insteadOf entries in the git config with the same value. This results in an ambiguous case, and Git does nothing to prevent it! The documentation says that the longest insteadOf value wins, but both have the same length since both are the same URL. ---- SOLUTION: None of this would happen if, instead of a `url.<replacement>.insteadOf <original>` approach, Git followed the opposite approach, `url.<original>.replaceWith <replacement>` (or `rewriteTo`, as it is suggested in [1]). So this approach is not only more intuitive and looks more resilient, it IS more resilient. Let's have a look at the previous scenarios again: SCENARIO 1: About as easy as before, except that it follows a more readable "from ... to ..." scheme: git config url.'http://example.org/'.replaceWith 'http://example.com/' (which I suspect will also give Git less trouble to find in the config, or at least it feels like it would). SCENARIO 2: Easy peasy. Two different sources with the same target = two different keys with the same value: git config url.'http://example.org/'.replaceWith 'http://example.com/' git config url.'http://example.net/'.replaceWith 'http://example.com/' And we no longer have the problem that we cannot replace two different URLs with the same replacement. SCENARIO 3: Rewriting the rule will simply overwrite the old value: git config url.'http://example.org/'.replaceWith 'http://example.com/' git config url.'http://example.org/'.replaceWith 'http://example.edu/' SCENARIO 4: Scenario 4 simply cannot happen with this approach under normal circumstances because there can't be two entries with the same key but different values, unless the user edited the config file manually. (But there CAN be two entries with different keys and the same value, which is what caused scenario 4 before.) So, it might be a good idea to implement and recommend the `replaceWith` (or `rewriteTo`) syntax, and deprecate the `insteadOf` syntax (although it'll probably be necessary to keep it around for backwards compatibility).