remote: allow resetting url list

Because remote.*.url is treated as a multi-valued key, there is no way to override previous config. So for example if you have remote.origin.url set to some wrong value, doing: git -c remote.origin.url=right fetch would not work. It would append "right" to the list, which means we'd still fetch from "wrong" (since subsequent values are used only as push urls). Let's provide a mechanism to reset the list, like we do for other multi-valued keys (e.g., credential.helper, http.extraheaders, and merge.suppressDest all use this "empty string means reset" pattern). Reported-by: Mathew George <mathewegeorge@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jun 14, 2024 at 06:31 UTC 9badf97c42474df3f0474a851bdc2e62e59da403
3 files changed +48 -3
Documentation/config/remote.txt
+4 -1
@@ -8,13 +8,16 @@ remote.<name>.url::
8 linkgit:git-push[1]. A configured remote can have multiple URLs;
9 in this case the first is used for fetching, and all are used
10 for pushing (assuming no `remote.<name>.pushurl` is defined).
11 + Setting this key to the empty string clears the list of urls,
12 + allowing you to override earlier config.
13
14 remote.<name>.pushurl::
15 The push URL of a remote repository. See linkgit:git-push[1].
16 If a `pushurl` option is present in a configured remote, it
17 is used for pushing instead of `remote.<name>.url`. A configured
18 remote can have multiple push URLs; in this case a push goes to
17 - all of them.
19 + all of them. Setting this key to the empty string clears the
20 + list of urls, allowing you to override earlier config.
21
22 remote.<name>.proxy::
23 For remotes that require curl (http, https and ftp), the URL to
remote.c
+8 -2
@@ -63,12 +63,18 @@ static char *alias_url(const char *url, struct rewrites *r)
63
64 static void add_url(struct remote *remote, const char *url)
65 {
66 - strvec_push(&remote->url, url);
66 + if (*url)
67 + strvec_push(&remote->url, url);
68 + else
69 + strvec_clear(&remote->url);
70 }
71
72 static void add_pushurl(struct remote *remote, const char *pushurl)
73 {
71 - strvec_push(&remote->pushurl, pushurl);
74 + if (*pushurl)
75 + strvec_push(&remote->pushurl, pushurl);
76 + else
77 + strvec_clear(&remote->pushurl);
78 }
79
80 static void add_pushurl_alias(struct remote_state *remote_state,
t/t5505-remote.sh
+36
@@ -1492,4 +1492,40 @@ test_expect_success 'refs/remotes/* <src> refspec and unqualified <dst> DWIM and
1492 )
1493 '
1494
1495 +test_expect_success 'empty config clears remote.*.url list' '
1496 + test_when_finished "git config --remove-section remote.multi" &&
1497 + git config --add remote.multi.url wrong-one &&
1498 + git config --add remote.multi.url wrong-two &&
1499 + git -c remote.multi.url= \
1500 + -c remote.multi.url=right-one \
1501 + -c remote.multi.url=right-two \
1502 + remote show -n multi >actual.raw &&
1503 + grep URL actual.raw >actual &&
1504 + cat >expect <<-\EOF &&
1505 + Fetch URL: right-one
1506 + Push URL: right-one
1507 + Push URL: right-two
1508 + EOF
1509 + test_cmp expect actual
1510 +'
1511 +
1512 +test_expect_success 'empty config clears remote.*.pushurl list' '
1513 + test_when_finished "git config --remove-section remote.multi" &&
1514 + git config --add remote.multi.url right &&
1515 + git config --add remote.multi.url will-be-ignored &&
1516 + git config --add remote.multi.pushurl wrong-push-one &&
1517 + git config --add remote.multi.pushurl wrong-push-two &&
1518 + git -c remote.multi.pushurl= \
1519 + -c remote.multi.pushurl=right-push-one \
1520 + -c remote.multi.pushurl=right-push-two \
1521 + remote show -n multi >actual.raw &&
1522 + grep URL actual.raw >actual &&
1523 + cat >expect <<-\EOF &&
1524 + Fetch URL: right
1525 + Push URL: right-push-one
1526 + Push URL: right-push-two
1527 + EOF
1528 + test_cmp expect actual
1529 +'
1530 +
1531 test_done