git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Cannot override `remote.origin.url` with `-c` option

From
Jeff King <peff@peff.net>
Date
Jun 11, 2024, 07:51 UTC
Message-ID
<20240611075137.GF3248245@coredump.intra.peff.net>
In-Reply-To
<83D801A8-3878-43C1-B7A7-78B3B7315FD8@gmail.com>
On Sun, Jun 09, 2024 at 12:21:47PM +0530, Mathew George wrote:
Show 10 quoted lines
> > What did you expect to happen? (Expected behavior)
> 
> The '-c' option should allow me to override the remote URL,
> which, as a result of running `git remote add`, is configured as
> follows in test/.git/config:
> 
> ```
> [remote "origin"]
> 	url = wrong-url
> ```
I don't think "-c" is the culprit here, but rather that remote.*.url is
a multi-valued config option. Rather than having a single value with
"last one wins" semantics, multiple instances of the config variable
form a list. So you'd see the same thing with:
  
  [remote "origin"]
  url = wrong-url
  url = right-url
in the config file.
Of course that leaves two questions:
  1. What are multiple URLs actually good for? I have no idea. I
     couldn't find any useful documentation in the manpages for
     git-config, git-remote, or git-fetch. It looks like any URLs after
     the first are used as push-only URLs:
       $ git remote show -n origin
       * remote origin
       Fetch URL: wrong-url
       Push  URL: wrong-url
       Push  URL: right-url
       [...]
     There's also a "pushurl" config option, which _replaces_ the
     original URL for pushing, rather than including it.
     As far as I can tell there's no way to actually have multiple fetch
     URLs (and the corner cases would be weird anyway). I suspect we'd
     come up with different semantics if we were designing it these
     days, but it has been this way since at least 2007. So any changes
     would probably need a deprecation period.
  2. Is there a way to override the list?
     Sadly, no. For some config keys, we allow a value-less boolean
     entry to reset the list. But since the config code doesn't know
     about the semantics of each key, this has to be implemented
     individually for each key, and nobody has bothered to do so for
     remote.*.url.
     The value-less key is something like:
       [remote "origin"]
       url = wrong-url
       # this one resets the list to empty!
       url
       # and this one adds a new value
       url = right-url
     Or in "-c" terms, it would be:
       git -c remote.origin.url -c remote.origin.url=right-url ...
     The syntax is ugly, but it is backwards compatible (that value-less
     entry is currently an error). So we could do that now (I'll show a
     messy patch below).

Of course none of that helps your immediate case. I did think of one workaround, though, which is to use the "insteadOf" config to rewrite the URL. So:

  git -c url.right-url.insteadOf=wrong-url ...

will rewrite all instances of "wrong-url" to use "right-url" instead (in origin and elsewhere).

-Peff
---
diff --git a/remote.c b/remote.c
index dcb5492c85..69b0f28637 100644
--- a/remote.c
+++ b/remote.c
@@ -63,6 +63,10 @@ static const char *alias_url(const char *url, struct rewrites *r)
 
 static void add_url(struct remote *remote, const char *url)
 {
+	if (!url) {
+		remote->url_nr = 0;
+		return;
+	}
 	ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
 	remote->url[remote->url_nr++] = url;
 }
@@ -430,10 +434,7 @@ static int handle_config(const char *key, const char *value,
 	else if (!strcmp(subkey, "prunetags"))
 		remote->prune_tags = git_config_bool(key, value);
 	else if (!strcmp(subkey, "url")) {
-		char *v;
-		if (git_config_string(&v, key, value))
-			return -1;
-		add_url(remote, v);
+		add_url(remote, xstrdup_or_null(value));
 	} else if (!strcmp(subkey, "pushurl")) {
 		char *v;
 		if (git_config_string(&v, key, value))
Previous: Mathew GeorgeNext: Junio C Hamano
Message 2 of 29 in “Cannot override `remote.origin.url` with `-c` option”
  1. Mathew GeorgeJun 9, 2024
  2. Jeff KingJun 11, 2024
  3. Junio C HamanoJun 11, 2024
  4. Jeff KingJun 13, 2024
  5. 0/11 allow overriding remote.*.urlJeff King, Jun 14, 2024
  6. 01/11 archive: fix check for missing urlJeff King, Jun 14, 2024
  7. 02/11 remote: refactor alias_url() memory ownershipJeff King, Jun 14, 2024
  8. Junio C HamanoJun 14, 2024
  9. 03/11 remote: transfer ownership of memory in add_url(), etcJeff King, Jun 14, 2024
  10. Junio C HamanoJun 14, 2024
  11. Jeff KingJun 16, 2024
  12. Junio C HamanoJun 17, 2024
  13. Elijah NewrenJun 25, 2024
  14. 04/11 remote: use strvecs to store remote url/pushurlJeff King, Jun 14, 2024
  15. Elijah NewrenJun 25, 2024
  16. 05/11 remote: simplify url/pushurl selectionJeff King, Jun 14, 2024
  17. Elijah NewrenJun 25, 2024
  18. 06/11 config: document remote.*.url/pushurl interactionJeff King, Jun 14, 2024
  19. Elijah NewrenJun 25, 2024
  20. 07/11 remote: allow resetting url listJeff King, Jun 14, 2024
  21. Elijah NewrenJun 25, 2024
  22. 08/11 t5801: make remote-testgit GIT_DIR setup more robustJeff King, Jun 14, 2024
  23. Elijah NewrenJun 25, 2024
  24. 09/11 t5801: test remote.*.vcs configJeff King, Jun 14, 2024
  25. 10/11 remote: always require at least one url in a remoteJeff King, Jun 14, 2024
  26. 11/11 remote: drop checks for zero-url caseJeff King, Jun 14, 2024
  27. Elijah NewrenJun 25, 2024
  28. Elijah NewrenJun 25, 2024
  29. Jeff KingJun 26, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.