Skip to content

Commit deded16

Browse files
committedJun 21, 2009
Merge branch 'mg/pushurl'
* mg/pushurl: avoid NULL dereference on failed malloc builtin-remote: Make "remote -v" display push urls builtin-remote: Show push urls as well technical/api-remote: Describe new struct remote member pushurl t5516: Check pushurl config setting Allow push and fetch urls to be different
2 parents 974e6e4 + ce61595 commit deded16

9 files changed

+102
-17
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/technical/api-remote.txt

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ struct remote
1818

1919
An array of all of the url_nr URLs configured for the remote
2020

21+
`pushurl`::
22+
23+
An array of all of the pushurl_nr push URLs configured for the remote
24+
2125
`push`::
2226

2327
An array of refspecs configured for pushing, with

‎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;

‎builtin-remote.c

+41-10
Original file line numberDiff line numberDiff line change
@@ -999,15 +999,25 @@ static int show(int argc, const char **argv)
999999
info.list = &info_list;
10001000
for (; argc; argc--, argv++) {
10011001
int i;
1002+
const char **url;
1003+
int url_nr;
10021004

10031005
get_remote_ref_states(*argv, &states, query_flag);
10041006

10051007
printf("* remote %s\n", *argv);
1006-
if (states.remote->url_nr) {
1007-
for (i=0; i < states.remote->url_nr; i++)
1008-
printf(" URL: %s\n", states.remote->url[i]);
1009-
} else
1010-
printf(" URL: %s\n", "(no URL)");
1008+
printf(" Fetch URL: %s\n", states.remote->url_nr > 0 ?
1009+
states.remote->url[0] : "(no URL)");
1010+
if (states.remote->pushurl_nr) {
1011+
url = states.remote->pushurl;
1012+
url_nr = states.remote->pushurl_nr;
1013+
} else {
1014+
url = states.remote->url;
1015+
url_nr = states.remote->url_nr;
1016+
}
1017+
for (i=0; i < url_nr; i++)
1018+
printf(" Push URL: %s\n", url[i]);
1019+
if (!i)
1020+
printf(" Push URL: %s\n", "(no URL)");
10111021
if (no_query)
10121022
printf(" HEAD branch: (not queried)\n");
10131023
else if (!states.heads.nr)
@@ -1266,22 +1276,42 @@ static int update(int argc, const char **argv)
12661276
static int get_one_entry(struct remote *remote, void *priv)
12671277
{
12681278
struct string_list *list = priv;
1279+
const char **url;
1280+
int i, url_nr;
1281+
void **utilp;
12691282

12701283
if (remote->url_nr > 0) {
1271-
int i;
1272-
1273-
for (i = 0; i < remote->url_nr; i++)
1274-
string_list_append(remote->name, list)->util = (void *)remote->url[i];
1284+
utilp = &(string_list_append(remote->name, list)->util);
1285+
*utilp = xmalloc(strlen(remote->url[0])+strlen(" (fetch)")+1);
1286+
strcpy((char *) *utilp, remote->url[0]);
1287+
strcat((char *) *utilp, " (fetch)");
12751288
} else
12761289
string_list_append(remote->name, list)->util = NULL;
1290+
if (remote->pushurl_nr) {
1291+
url = remote->pushurl;
1292+
url_nr = remote->pushurl_nr;
1293+
} else {
1294+
url = remote->url;
1295+
url_nr = remote->url_nr;
1296+
}
1297+
for (i = 0; i < url_nr; i++)
1298+
{
1299+
utilp = &(string_list_append(remote->name, list)->util);
1300+
*utilp = xmalloc(strlen(url[i])+strlen(" (push)")+1);
1301+
strcpy((char *) *utilp, url[i]);
1302+
strcat((char *) *utilp, " (push)");
1303+
}
12771304

12781305
return 0;
12791306
}
12801307

12811308
static int show_all(void)
12821309
{
12831310
struct string_list list = { NULL, 0, 0 };
1284-
int result = for_each_remote(get_one_entry, &list);
1311+
int result;
1312+
1313+
list.strdup_strings = 1;
1314+
result = for_each_remote(get_one_entry, &list);
12851315

12861316
if (!result) {
12871317
int i;
@@ -1299,6 +1329,7 @@ static int show_all(void)
12991329
}
13001330
}
13011331
}
1332+
string_list_clear(&list, 1);
13021333
return result;
13031334
}
13041335

‎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;

‎t/t5505-remote.sh

+7-3
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ EOF
135135

136136
cat > test/expect << EOF
137137
* remote origin
138-
URL: $(pwd)/one
138+
Fetch URL: $(pwd)/one
139+
Push URL: $(pwd)/one
139140
HEAD branch: master
140141
Remote branches:
141142
master new (next fetch will store in remotes/origin)
@@ -151,7 +152,8 @@ cat > test/expect << EOF
151152
master pushes to master (local out of date)
152153
master pushes to upstream (create)
153154
* remote two
154-
URL: ../two
155+
Fetch URL: ../two
156+
Push URL: ../three
155157
HEAD branch (remote HEAD is ambiguous, may be one of the following):
156158
another
157159
master
@@ -173,6 +175,7 @@ test_expect_success 'show' '
173175
git branch --track rebase origin/master &&
174176
git branch -d -r origin/master &&
175177
git config --add remote.two.url ../two &&
178+
git config --add remote.two.pushurl ../three &&
176179
git config branch.rebase.rebase true &&
177180
git config branch.octopus.merge "topic-a topic-b topic-c" &&
178181
(cd ../one &&
@@ -191,7 +194,8 @@ test_expect_success 'show' '
191194

192195
cat > test/expect << EOF
193196
* remote origin
194-
URL: $(pwd)/one
197+
Fetch URL: $(pwd)/one
198+
Push URL: $(pwd)/one
195199
HEAD branch: (not queried)
196200
Remote branches: (status not queried)
197201
master

‎t/t5516-fetch-push.sh

+13
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,19 @@ test_expect_success 'push with config remote.*.push = HEAD' '
419419
git config --remove-section remote.there
420420
git config --remove-section branch.master
421421

422+
test_expect_success 'push with config remote.*.pushurl' '
423+
424+
mk_test heads/master &&
425+
git checkout master &&
426+
git config remote.there.url test2repo &&
427+
git config remote.there.pushurl testrepo &&
428+
git push there &&
429+
check_push_result $the_commit heads/master
430+
'
431+
432+
# clean up the cruft left with the previous one
433+
git config --remove-section remote.there
434+
422435
test_expect_success 'push with dry-run' '
423436
424437
mk_test heads/master &&

0 commit comments

Comments
 (0)