Skip to content

Commit 2034623

Browse files
Michael J Grubergitster
Michael J Gruber
authored andcommitted
Allow push and fetch urls to be different
This introduces a config setting remote.$remotename.pushurl which is used for pushes only. If absent remote.$remotename.url is used for pushes and fetches as before. This is useful, for example, in order to do passwordless fetches (remote update) over the git transport but pushes over ssh. Signed-off-by: Michael J Gruber <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f4f78e6 commit 2034623

File tree

5 files changed

+37
-4
lines changed

5 files changed

+37
-4
lines changed

Documentation/config.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,9 @@ remote.<name>.url::
13191319
The URL of a remote repository. See linkgit:git-fetch[1] or
13201320
linkgit:git-push[1].
13211321

1322+
remote.<name>.pushurl::
1323+
The push URL of a remote repository. See linkgit:git-push[1].
1324+
13221325
remote.<name>.proxy::
13231326
For remotes that require curl (http, https and ftp), the URL to
13241327
the proxy to use for that remote. Set to the empty string to

Documentation/urls-remotes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ config file would appear like this:
2727
------------
2828
[remote "<name>"]
2929
url = <url>
30+
pushurl = <pushurl>
3031
push = <refspec>
3132
fetch = <refspec>
3233
------------
3334

35+
The `<pushurl>` is used for pushes only. It is optional and defaults
36+
to `<url>`.
3437

3538
Named file in `$GIT_DIR/remotes`
3639
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

builtin-push.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ static int do_push(const char *repo, int flags)
117117
{
118118
int i, errs;
119119
struct remote *remote = remote_get(repo);
120+
const char **url;
121+
int url_nr;
120122

121123
if (!remote) {
122124
if (repo)
@@ -152,9 +154,16 @@ static int do_push(const char *repo, int flags)
152154
setup_default_push_refspecs();
153155
}
154156
errs = 0;
155-
for (i = 0; i < remote->url_nr; i++) {
157+
if (remote->pushurl_nr) {
158+
url = remote->pushurl;
159+
url_nr = remote->pushurl_nr;
160+
} else {
161+
url = remote->url;
162+
url_nr = remote->url_nr;
163+
}
164+
for (i = 0; i < url_nr; i++) {
156165
struct transport *transport =
157-
transport_get(remote, remote->url[i]);
166+
transport_get(remote, url[i]);
158167
int err;
159168
if (receivepack)
160169
transport_set_option(transport,
@@ -163,14 +172,14 @@ static int do_push(const char *repo, int flags)
163172
transport_set_option(transport, TRANS_OPT_THIN, "yes");
164173

165174
if (flags & TRANSPORT_PUSH_VERBOSE)
166-
fprintf(stderr, "Pushing to %s\n", remote->url[i]);
175+
fprintf(stderr, "Pushing to %s\n", url[i]);
167176
err = transport_push(transport, refspec_nr, refspec, flags);
168177
err |= transport_disconnect(transport);
169178

170179
if (!err)
171180
continue;
172181

173-
error("failed to push some refs to '%s'", remote->url[i]);
182+
error("failed to push some refs to '%s'", url[i]);
174183
errs++;
175184
}
176185
return !!errs;

remote.c

+14
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ static void add_url_alias(struct remote *remote, const char *url)
106106
add_url(remote, alias_url(url));
107107
}
108108

109+
static void add_pushurl(struct remote *remote, const char *pushurl)
110+
{
111+
ALLOC_GROW(remote->pushurl, remote->pushurl_nr + 1, remote->pushurl_alloc);
112+
remote->pushurl[remote->pushurl_nr++] = pushurl;
113+
}
114+
109115
static struct remote *make_remote(const char *name, int len)
110116
{
111117
struct remote *ret;
@@ -379,6 +385,11 @@ static int handle_config(const char *key, const char *value, void *cb)
379385
if (git_config_string(&v, key, value))
380386
return -1;
381387
add_url(remote, v);
388+
} else if (!strcmp(subkey, ".pushurl")) {
389+
const char *v;
390+
if (git_config_string(&v, key, value))
391+
return -1;
392+
add_pushurl(remote, v);
382393
} else if (!strcmp(subkey, ".push")) {
383394
const char *v;
384395
if (git_config_string(&v, key, value))
@@ -424,6 +435,9 @@ static void alias_all_urls(void)
424435
for (j = 0; j < remotes[i]->url_nr; j++) {
425436
remotes[i]->url[j] = alias_url(remotes[i]->url[j]);
426437
}
438+
for (j = 0; j < remotes[i]->pushurl_nr; j++) {
439+
remotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j]);
440+
}
427441
}
428442
}
429443

remote.h

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ struct remote {
1515
int url_nr;
1616
int url_alloc;
1717

18+
const char **pushurl;
19+
int pushurl_nr;
20+
int pushurl_alloc;
21+
1822
const char **push_refspec;
1923
struct refspec *push;
2024
int push_refspec_nr;

0 commit comments

Comments
 (0)