diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.txt index 0678b4bcfe..8efc53e836 100644 --- a/Documentation/config/remote.txt +++ b/Documentation/config/remote.txt @@ -5,10 +5,19 @@ remote.pushDefault:: remote..url:: The URL of a remote repository. See linkgit:git-fetch[1] or - linkgit:git-push[1]. + linkgit:git-push[1]. A configured remote can have multiple URLs; + in this case the first is used for fetching, and all are used + for pushing (assuming no `remote..pushurl` is defined). + Setting this key to the empty string clears the list of urls, + allowing you to override earlier config. remote..pushurl:: The push URL of a remote repository. See linkgit:git-push[1]. + If a `pushurl` option is present in a configured remote, it + is used for pushing instead of `remote..url`. A configured + remote can have multiple push URLs; in this case a push goes to + all of them. Setting this key to the empty string clears the + list of urls, allowing you to override earlier config. remote..proxy:: For remotes that require curl (http, https and ftp), the URL to diff --git a/builtin/archive.c b/builtin/archive.c index 15ee1ec7bb..7234607aaa 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -31,9 +31,7 @@ static int run_remote_archiver(int argc, const char **argv, struct packet_reader reader; _remote = remote_get(remote); - if (!_remote->url[0]) - die(_("git archive: Remote with no URL")); - transport = transport_get(_remote, _remote->url[0]); + transport = transport_get(_remote, _remote->url.v[0]); transport_connect(transport, "git-upload-archive", exec, fd); /* diff --git a/builtin/clone.c b/builtin/clone.c index b28f88eb43..80ef2bfca8 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1294,7 +1294,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, branch_top.buf); - path = get_repo_path(remote->url[0], &is_bundle); + path = get_repo_path(remote->url.v[0], &is_bundle); is_local = option_local != 0 && path && !is_bundle; if (is_local) { if (option_depth) @@ -1316,7 +1316,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (option_local > 0 && !is_local) warning(_("--local is ignored")); - transport = transport_get(remote, path ? path : remote->url[0]); + transport = transport_get(remote, path ? path : remote->url.v[0]); transport_set_verbosity(transport, option_verbosity, option_progress); transport->family = family; transport->cloning = 1; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 69841ed49f..debf2d4f88 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -112,11 +112,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) die("bad repository '%s'", dest); die("No remote configured to list refs from."); } - if (!remote->url_nr) - die("remote %s has no configured URL", dest); if (get_url) { - printf("%s\n", *remote->url); + printf("%s\n", remote->url.v[0]); return 0; } @@ -133,7 +131,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) } if (!dest && !quiet) - fprintf(stderr, "From %s\n", *remote->url); + fprintf(stderr, "From %s\n", remote->url.v[0]); for ( ; ref; ref = ref->next) { struct ref_array_item *item; if (!check_ref_type(ref, flags)) diff --git a/builtin/push.c b/builtin/push.c index 2fbb31c3ad..8260c6e46a 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -141,16 +141,6 @@ static void set_refspecs(const char **refs, int nr, const char *repo) free_refs(local_refs); } -static int push_url_of_remote(struct remote *remote, const char ***url_p) -{ - if (remote->pushurl_nr) { - *url_p = remote->pushurl; - return remote->pushurl_nr; - } - *url_p = remote->url; - return remote->url_nr; -} - static NORETURN void die_push_simple(struct branch *branch, struct remote *remote) { @@ -434,8 +424,7 @@ static int do_push(int flags, struct remote *remote) { int i, errs; - const char **url; - int url_nr; + struct strvec *url; struct refspec *push_refspec = &rs; if (push_options->nr) @@ -448,19 +437,10 @@ static int do_push(int flags, setup_default_push_refspecs(&flags, remote); } errs = 0; - url_nr = push_url_of_remote(remote, &url); - if (url_nr) { - for (i = 0; i < url_nr; i++) { - struct transport *transport = - transport_get(remote, url[i]); - if (flags & TRANSPORT_PUSH_OPTIONS) - transport->push_options = push_options; - if (push_with_options(transport, push_refspec, flags)) - errs++; - } - } else { + url = push_url_of_remote(remote); + for (i = 0; i < url->nr; i++) { struct transport *transport = - transport_get(remote, NULL); + transport_get(remote, url->v[i]); if (flags & TRANSPORT_PUSH_OPTIONS) transport->push_options = push_options; if (push_with_options(transport, push_refspec, flags)) diff --git a/builtin/remote.c b/builtin/remote.c index 8230f33798..08292498bd 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -619,8 +619,8 @@ static int migrate_file(struct remote *remote) int i; strbuf_addf(&buf, "remote.%s.url", remote->name); - for (i = 0; i < remote->url_nr; i++) - git_config_set_multivar(buf.buf, remote->url[i], "^$", 0); + for (i = 0; i < remote->url.nr; i++) + git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.push", remote->name); for (i = 0; i < remote->push.raw_nr; i++) @@ -1002,8 +1002,7 @@ static int get_remote_ref_states(const char *name, struct transport *transport; const struct ref *remote_refs; - transport = transport_get(states->remote, states->remote->url_nr > 0 ? - states->remote->url[0] : NULL); + transport = transport_get(states->remote, states->remote->url.v[0]); remote_refs = transport_get_remote_refs(transport, NULL); states->queried = 1; @@ -1213,15 +1212,15 @@ static int get_one_entry(struct remote *remote, void *priv) { struct string_list *list = priv; struct strbuf remote_info_buf = STRBUF_INIT; - const char **url; - int i, url_nr; + struct strvec *url; + int i; - if (remote->url_nr > 0) { + if (remote->url.nr > 0) { struct strbuf promisor_config = STRBUF_INIT; const char *partial_clone_filter = NULL; strbuf_addf(&promisor_config, "remote.%s.partialclonefilter", remote->name); - strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url[0]); + strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url.v[0]); if (!git_config_get_string_tmp(promisor_config.buf, &partial_clone_filter)) strbuf_addf(&remote_info_buf, " [%s]", partial_clone_filter); @@ -1230,16 +1229,10 @@ static int get_one_entry(struct remote *remote, void *priv) strbuf_detach(&remote_info_buf, NULL); } else string_list_append(list, remote->name)->util = NULL; - if (remote->pushurl_nr) { - url = remote->pushurl; - url_nr = remote->pushurl_nr; - } else { - url = remote->url; - url_nr = remote->url_nr; - } - for (i = 0; i < url_nr; i++) + url = push_url_of_remote(remote); + for (i = 0; i < url->nr; i++) { - strbuf_addf(&remote_info_buf, "%s (push)", url[i]); + strbuf_addf(&remote_info_buf, "%s (push)", url->v[i]); string_list_append(list, remote->name)->util = strbuf_detach(&remote_info_buf, NULL); } @@ -1295,28 +1288,20 @@ static int show(int argc, const char **argv, const char *prefix) for (; argc; argc--, argv++) { int i; - const char **url; - int url_nr; + struct strvec *url; get_remote_ref_states(*argv, &info.states, query_flag); printf_ln(_("* remote %s"), *argv); - printf_ln(_(" Fetch URL: %s"), info.states.remote->url_nr > 0 ? - info.states.remote->url[0] : _("(no URL)")); - if (info.states.remote->pushurl_nr) { - url = info.states.remote->pushurl; - url_nr = info.states.remote->pushurl_nr; - } else { - url = info.states.remote->url; - url_nr = info.states.remote->url_nr; - } - for (i = 0; i < url_nr; i++) + printf_ln(_(" Fetch URL: %s"), info.states.remote->url.v[0]); + url = push_url_of_remote(info.states.remote); + for (i = 0; i < url->nr; i++) /* * TRANSLATORS: the colon ':' should align * with the one in " Fetch URL: %s" * translation. */ - printf_ln(_(" Push URL: %s"), url[i]); + printf_ln(_(" Push URL: %s"), url->v[i]); if (!i) printf_ln(_(" Push URL: %s"), _("(no URL)")); if (no_query) @@ -1453,10 +1438,7 @@ static int prune_remote(const char *remote, int dry_run) } printf_ln(_("Pruning %s"), remote); - printf_ln(_("URL: %s"), - states.remote->url_nr - ? states.remote->url[0] - : _("(no URL)")); + printf_ln(_("URL: %s"), states.remote->url.v[0]); for_each_string_list_item(item, &states.stale) string_list_append(&refs_to_prune, item->util); @@ -1622,8 +1604,7 @@ static int get_url(int argc, const char **argv, const char *prefix) int i, push_mode = 0, all_mode = 0; const char *remotename = NULL; struct remote *remote; - const char **url; - int url_nr; + struct strvec *url; struct option options[] = { OPT_BOOL('\0', "push", &push_mode, N_("query push URLs rather than fetch URLs")), @@ -1645,27 +1626,13 @@ static int get_url(int argc, const char **argv, const char *prefix) exit(2); } - url_nr = 0; - if (push_mode) { - url = remote->pushurl; - url_nr = remote->pushurl_nr; - } - /* else fetch mode */ - - /* Use the fetch URL when no push URLs were found or requested. */ - if (!url_nr) { - url = remote->url; - url_nr = remote->url_nr; - } - - if (!url_nr) - die(_("no URLs configured for remote '%s'"), remotename); + url = push_mode ? push_url_of_remote(remote) : &remote->url; if (all_mode) { - for (i = 0; i < url_nr; i++) - printf_ln("%s", url[i]); + for (i = 0; i < url->nr; i++) + printf_ln("%s", url->v[i]); } else { - printf_ln("%s", *url); + printf_ln("%s", url->v[0]); } return 0; @@ -1680,8 +1647,7 @@ static int set_url(int argc, const char **argv, const char *prefix) const char *oldurl = NULL; struct remote *remote; regex_t old_regex; - const char **urlset; - int urlset_nr; + struct strvec *urlset; struct strbuf name_buf = STRBUF_INIT; struct option options[] = { OPT_BOOL('\0', "push", &push_mode, @@ -1718,12 +1684,10 @@ static int set_url(int argc, const char **argv, const char *prefix) if (push_mode) { strbuf_addf(&name_buf, "remote.%s.pushurl", remotename); - urlset = remote->pushurl; - urlset_nr = remote->pushurl_nr; + urlset = &remote->pushurl; } else { strbuf_addf(&name_buf, "remote.%s.url", remotename); - urlset = remote->url; - urlset_nr = remote->url_nr; + urlset = &remote->url; } /* Special cases that add new entry. */ @@ -1740,8 +1704,8 @@ static int set_url(int argc, const char **argv, const char *prefix) if (regcomp(&old_regex, oldurl, REG_EXTENDED)) die(_("Invalid old URL pattern: %s"), oldurl); - for (i = 0; i < urlset_nr; i++) - if (!regexec(&old_regex, urlset[i], 0, NULL, 0)) + for (i = 0; i < urlset->nr; i++) + if (!regexec(&old_regex, urlset->v[i], 0, NULL, 0)) matches++; else negative_matches++; diff --git a/remote-curl.c b/remote-curl.c index f8c6bd0826..4adcf25ed6 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -1576,7 +1576,7 @@ int cmd_main(int argc, const char **argv) if (argc > 2) { end_url_with_slash(&url, argv[2]); } else { - end_url_with_slash(&url, remote->url[0]); + end_url_with_slash(&url, remote->url.v[0]); } http_init(remote, url.buf, 0); diff --git a/remote.c b/remote.c index 5fab7f0970..f43cf5e7a4 100644 --- a/remote.c +++ b/remote.c @@ -34,10 +34,10 @@ struct counted_string { static int valid_remote(const struct remote *remote) { - return (!!remote->url) || (!!remote->foreign_vcs); + return !!remote->url.nr; } -static const char *alias_url(const char *url, struct rewrites *r) +static char *alias_url(const char *url, struct rewrites *r) { int i, j; struct counted_string *longest; @@ -58,36 +58,43 @@ static const char *alias_url(const char *url, struct rewrites *r) } } if (!longest) - return url; + return NULL; return xstrfmt("%s%s", r->rewrite[longest_i]->base, url + longest->len); } static void add_url(struct remote *remote, const char *url) { - ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc); - remote->url[remote->url_nr++] = url; + if (*url) + strvec_push(&remote->url, url); + else + strvec_clear(&remote->url); } static void add_pushurl(struct remote *remote, const char *pushurl) { - ALLOC_GROW(remote->pushurl, remote->pushurl_nr + 1, remote->pushurl_alloc); - remote->pushurl[remote->pushurl_nr++] = pushurl; + if (*pushurl) + strvec_push(&remote->pushurl, pushurl); + else + strvec_clear(&remote->pushurl); } static void add_pushurl_alias(struct remote_state *remote_state, struct remote *remote, const char *url) { - const char *pushurl = alias_url(url, &remote_state->rewrites_push); - if (pushurl != url) - add_pushurl(remote, pushurl); + char *alias = alias_url(url, &remote_state->rewrites_push); + if (alias) + add_pushurl(remote, alias); + free(alias); } static void add_url_alias(struct remote_state *remote_state, struct remote *remote, const char *url) { - add_url(remote, alias_url(url, &remote_state->rewrites)); + char *alias = alias_url(url, &remote_state->rewrites); + add_url(remote, alias ? alias : url); add_pushurl_alias(remote_state, remote, url); + free(alias); } struct remotes_hash_key { @@ -149,18 +156,12 @@ static struct remote *make_remote(struct remote_state *remote_state, static void remote_clear(struct remote *remote) { - int i; - free((char *)remote->name); free((char *)remote->foreign_vcs); - for (i = 0; i < remote->url_nr; i++) - free((char *)remote->url[i]); - FREE_AND_NULL(remote->url); + strvec_clear(&remote->url); + strvec_clear(&remote->pushurl); - for (i = 0; i < remote->pushurl_nr; i++) - free((char *)remote->pushurl[i]); - FREE_AND_NULL(remote->pushurl); free((char *)remote->receivepack); free((char *)remote->uploadpack); FREE_AND_NULL(remote->http_proxy); @@ -294,7 +295,7 @@ static void read_remotes_file(struct remote_state *remote_state, if (skip_prefix(buf.buf, "URL:", &v)) add_url_alias(remote_state, remote, - xstrdup(skip_spaces(v))); + skip_spaces(v)); else if (skip_prefix(buf.buf, "Push:", &v)) refspec_append(&remote->push, skip_spaces(v)); else if (skip_prefix(buf.buf, "Pull:", &v)) @@ -337,7 +338,7 @@ static void read_branches_file(struct remote_state *remote_state, else frag = to_free = repo_default_branch_name(the_repository, 0); - add_url_alias(remote_state, remote, strbuf_detach(&buf, NULL)); + add_url_alias(remote_state, remote, buf.buf); refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s", frag, remote->name); @@ -348,6 +349,7 @@ static void read_branches_file(struct remote_state *remote_state, refspec_appendf(&remote->push, "HEAD:refs/heads/%s", frag); remote->fetch_tags = 1; /* always auto-follow */ + strbuf_release(&buf); free(to_free); } @@ -432,15 +434,13 @@ 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); + if (!value) + return config_error_nonbool(key); + add_url(remote, value); } else if (!strcmp(subkey, "pushurl")) { - char *v; - if (git_config_string(&v, key, value)) - return -1; - add_pushurl(remote, v); + if (!value) + return config_error_nonbool(key); + add_pushurl(remote, value); } else if (!strcmp(subkey, "push")) { char *v; if (git_config_string(&v, key, value)) @@ -493,20 +493,25 @@ static void alias_all_urls(struct remote_state *remote_state) int add_pushurl_aliases; if (!remote_state->remotes[i]) continue; - for (j = 0; j < remote_state->remotes[i]->pushurl_nr; j++) { - remote_state->remotes[i]->pushurl[j] = - alias_url(remote_state->remotes[i]->pushurl[j], - &remote_state->rewrites); + for (j = 0; j < remote_state->remotes[i]->pushurl.nr; j++) { + char *alias = alias_url(remote_state->remotes[i]->pushurl.v[j], + &remote_state->rewrites); + if (alias) + strvec_replace(&remote_state->remotes[i]->pushurl, + j, alias); } - add_pushurl_aliases = remote_state->remotes[i]->pushurl_nr == 0; - for (j = 0; j < remote_state->remotes[i]->url_nr; j++) { + add_pushurl_aliases = remote_state->remotes[i]->pushurl.nr == 0; + for (j = 0; j < remote_state->remotes[i]->url.nr; j++) { + char *alias; if (add_pushurl_aliases) add_pushurl_alias( remote_state, remote_state->remotes[i], - remote_state->remotes[i]->url[j]); - remote_state->remotes[i]->url[j] = - alias_url(remote_state->remotes[i]->url[j], + remote_state->remotes[i]->url.v[j]); + alias = alias_url(remote_state->remotes[i]->url.v[j], &remote_state->rewrites); + if (alias) + strvec_replace(&remote_state->remotes[i]->url, + j, alias); } } } @@ -646,10 +651,10 @@ static void validate_remote_url(struct remote *remote) else die(_("unrecognized value transfer.credentialsInUrl: '%s'"), value); - for (i = 0; i < remote->url_nr; i++) { + for (i = 0; i < remote->url.nr; i++) { struct url_info url_info = { 0 }; - if (!url_normalize(remote->url[i], &url_info) || + if (!url_normalize(remote->url.v[i], &url_info) || !url_info.passwd_off) goto loop_cleanup; @@ -823,13 +828,18 @@ struct ref *ref_remove_duplicates(struct ref *ref_map) int remote_has_url(struct remote *remote, const char *url) { int i; - for (i = 0; i < remote->url_nr; i++) { - if (!strcmp(remote->url[i], url)) + for (i = 0; i < remote->url.nr; i++) { + if (!strcmp(remote->url.v[i], url)) return 1; } return 0; } +struct strvec *push_url_of_remote(struct remote *remote) +{ + return remote->pushurl.nr ? &remote->pushurl : &remote->url; +} + static int match_name_with_pattern(const char *key, const char *name, const char *value, char **result) { diff --git a/remote.h b/remote.h index ca1458dec2..b901b56746 100644 --- a/remote.h +++ b/remote.h @@ -4,6 +4,7 @@ #include "hash.h" #include "hashmap.h" #include "refspec.h" +#include "strvec.h" struct option; struct transport_ls_refs_options; @@ -68,16 +69,9 @@ struct remote { char *foreign_vcs; /* An array of all of the url_nr URLs configured for the remote */ - const char **url; - - int url_nr; - int url_alloc; - + struct strvec url; /* An array of all of the pushurl_nr push URLs configured for the remote */ - const char **pushurl; - - int pushurl_nr; - int pushurl_alloc; + struct strvec pushurl; struct refspec push; @@ -129,6 +123,7 @@ typedef int each_remote_fn(struct remote *remote, void *priv); int for_each_remote(each_remote_fn fn, void *priv); int remote_has_url(struct remote *remote, const char *url); +struct strvec *push_url_of_remote(struct remote *remote); struct ref_push_report { const char *ref_name; diff --git a/t/helper/test-bundle-uri.c b/t/helper/test-bundle-uri.c index 09dc78733c..0c5fa723d8 100644 --- a/t/helper/test-bundle-uri.c +++ b/t/helper/test-bundle-uri.c @@ -88,8 +88,6 @@ static int cmd_ls_remote(int argc, const char **argv) die(_("bad repository '%s'"), dest); die(_("no remote configured to get bundle URIs from")); } - if (!remote->url_nr) - die(_("remote '%s' has no configured URL"), dest); transport = transport_get(remote, NULL); if (transport_get_remote_bundle_uri(transport) < 0) { diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 7789ff12c4..08424e878e 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -1492,4 +1492,40 @@ test_expect_success 'refs/remotes/* refspec and unqualified DWIM and ) ' +test_expect_success 'empty config clears remote.*.url list' ' + test_when_finished "git config --remove-section remote.multi" && + git config --add remote.multi.url wrong-one && + git config --add remote.multi.url wrong-two && + git -c remote.multi.url= \ + -c remote.multi.url=right-one \ + -c remote.multi.url=right-two \ + remote show -n multi >actual.raw && + grep URL actual.raw >actual && + cat >expect <<-\EOF && + Fetch URL: right-one + Push URL: right-one + Push URL: right-two + EOF + test_cmp expect actual +' + +test_expect_success 'empty config clears remote.*.pushurl list' ' + test_when_finished "git config --remove-section remote.multi" && + git config --add remote.multi.url right && + git config --add remote.multi.url will-be-ignored && + git config --add remote.multi.pushurl wrong-push-one && + git config --add remote.multi.pushurl wrong-push-two && + git -c remote.multi.pushurl= \ + -c remote.multi.pushurl=right-push-one \ + -c remote.multi.pushurl=right-push-two \ + remote show -n multi >actual.raw && + grep URL actual.raw >actual && + cat >expect <<-\EOF && + Fetch URL: right + Push URL: right-push-one + Push URL: right-push-two + EOF + test_cmp expect actual +' + test_done diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 4e0a77f985..20f43f7b7d 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -38,6 +38,29 @@ test_expect_success 'cloning from local repo' ' test_cmp server/file local/file ' +test_expect_success 'clone with remote.*.vcs config' ' + GIT_TRACE=$PWD/vcs-clone.trace \ + git clone --no-local -c remote.origin.vcs=testgit "$PWD/server" vcs-clone && + test_grep remote-testgit vcs-clone.trace +' + +test_expect_success 'fetch with configured remote.*.vcs' ' + git init vcs-fetch && + git -C vcs-fetch config remote.origin.vcs testgit && + git -C vcs-fetch config remote.origin.url "$PWD/server" && + GIT_TRACE=$PWD/vcs-fetch.trace \ + git -C vcs-fetch fetch origin && + test_grep remote-testgit vcs-fetch.trace +' + +test_expect_success 'vcs remote with no url' ' + NOURL_UPSTREAM=$PWD/server && + export NOURL_UPSTREAM && + git init vcs-nourl && + git -C vcs-nourl config remote.origin.vcs nourl && + git -C vcs-nourl fetch origin +' + test_expect_success 'create new commit on remote' ' (cd server && echo content >>file && diff --git a/t/t5801/git-remote-nourl b/t/t5801/git-remote-nourl new file mode 100755 index 0000000000..09be6013c5 --- /dev/null +++ b/t/t5801/git-remote-nourl @@ -0,0 +1,3 @@ +#!/bin/sh + +exec git-remote-testgit "$1" "$NOURL_UPSTREAM" diff --git a/t/t5801/git-remote-testgit b/t/t5801/git-remote-testgit index c5b10f5775..f8b476499f 100755 --- a/t/t5801/git-remote-testgit +++ b/t/t5801/git-remote-testgit @@ -26,7 +26,8 @@ then t_refspec="" fi -GIT_DIR="$url/.git" +unset $(git rev-parse --local-env-vars) +GIT_DIR=$(git -C "$url" rev-parse --absolute-git-dir) export GIT_DIR force= diff --git a/transport.c b/transport.c index b9c8827ed9..139721a990 100644 --- a/transport.c +++ b/transport.c @@ -1114,6 +1114,7 @@ static struct transport_vtable builtin_smart_vtable = { struct transport *transport_get(struct remote *remote, const char *url) { const char *helper; + const char *p; struct transport *ret = xcalloc(1, sizeof(*ret)); ret->progress = isatty(2); @@ -1129,19 +1130,15 @@ struct transport *transport_get(struct remote *remote, const char *url) ret->remote = remote; helper = remote->foreign_vcs; - if (!url && remote->url) - url = remote->url[0]; + if (!url) + url = remote->url.v[0]; ret->url = url; - /* maybe it is a foreign URL? */ - if (url) { - const char *p = url; - - while (is_urlschemechar(p == url, *p)) - p++; - if (starts_with(p, "::")) - helper = xstrndup(url, p - url); - } + p = url; + while (is_urlschemechar(p == url, *p)) + p++; + if (starts_with(p, "::")) + helper = xstrndup(url, p - url); if (helper) { transport_helper_init(ret, helper);