Browse Source

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
maint
Junio C Hamano 16 years ago
parent
commit
deded16d15
  1. 3
      Documentation/config.txt
  2. 4
      Documentation/technical/api-remote.txt
  3. 3
      Documentation/urls-remotes.txt
  4. 17
      builtin-push.c
  5. 51
      builtin-remote.c
  6. 14
      remote.c
  7. 4
      remote.h
  8. 10
      t/t5505-remote.sh
  9. 13
      t/t5516-fetch-push.sh

3
Documentation/config.txt

@ -1319,6 +1319,9 @@ remote.<name>.url::
The URL of a remote repository. See linkgit:git-fetch[1] or The URL of a remote repository. See linkgit:git-fetch[1] or
linkgit:git-push[1]. linkgit:git-push[1].


remote.<name>.pushurl::
The push URL of a remote repository. See linkgit:git-push[1].

remote.<name>.proxy:: remote.<name>.proxy::
For remotes that require curl (http, https and ftp), the URL to For remotes that require curl (http, https and ftp), the URL to
the proxy to use for that remote. Set to the empty string to the proxy to use for that remote. Set to the empty string to

4
Documentation/technical/api-remote.txt

@ -18,6 +18,10 @@ struct remote


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


`pushurl`::

An array of all of the pushurl_nr push URLs configured for the remote

`push`:: `push`::


An array of refspecs configured for pushing, with An array of refspecs configured for pushing, with

3
Documentation/urls-remotes.txt

@ -27,10 +27,13 @@ config file would appear like this:
------------ ------------
[remote "<name>"] [remote "<name>"]
url = <url> url = <url>
pushurl = <pushurl>
push = <refspec> push = <refspec>
fetch = <refspec> fetch = <refspec>
------------ ------------


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


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

17
builtin-push.c

@ -117,6 +117,8 @@ static int do_push(const char *repo, int flags)
{ {
int i, errs; int i, errs;
struct remote *remote = remote_get(repo); struct remote *remote = remote_get(repo);
const char **url;
int url_nr;


if (!remote) { if (!remote) {
if (repo) if (repo)
@ -152,9 +154,16 @@ static int do_push(const char *repo, int flags)
setup_default_push_refspecs(); setup_default_push_refspecs();
} }
errs = 0; errs = 0;
for (i = 0; i < remote->url_nr; i++) { 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++) {
struct transport *transport = struct transport *transport =
transport_get(remote, remote->url[i]); transport_get(remote, url[i]);
int err; int err;
if (receivepack) if (receivepack)
transport_set_option(transport, transport_set_option(transport,
@ -163,14 +172,14 @@ static int do_push(const char *repo, int flags)
transport_set_option(transport, TRANS_OPT_THIN, "yes"); transport_set_option(transport, TRANS_OPT_THIN, "yes");


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


if (!err) if (!err)
continue; continue;


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

51
builtin-remote.c

@ -999,15 +999,25 @@ static int show(int argc, const char **argv)
info.list = &info_list; info.list = &info_list;
for (; argc; argc--, argv++) { for (; argc; argc--, argv++) {
int i; int i;
const char **url;
int url_nr;


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


printf("* remote %s\n", *argv); printf("* remote %s\n", *argv);
if (states.remote->url_nr) { printf(" Fetch URL: %s\n", states.remote->url_nr > 0 ?
for (i=0; i < states.remote->url_nr; i++) states.remote->url[0] : "(no URL)");
printf(" URL: %s\n", states.remote->url[i]); if (states.remote->pushurl_nr) {
} else url = states.remote->pushurl;
printf(" URL: %s\n", "(no URL)"); url_nr = states.remote->pushurl_nr;
} else {
url = states.remote->url;
url_nr = states.remote->url_nr;
}
for (i=0; i < url_nr; i++)
printf(" Push URL: %s\n", url[i]);
if (!i)
printf(" Push URL: %s\n", "(no URL)");
if (no_query) if (no_query)
printf(" HEAD branch: (not queried)\n"); printf(" HEAD branch: (not queried)\n");
else if (!states.heads.nr) else if (!states.heads.nr)
@ -1266,14 +1276,31 @@ static int update(int argc, const char **argv)
static int get_one_entry(struct remote *remote, void *priv) static int get_one_entry(struct remote *remote, void *priv)
{ {
struct string_list *list = priv; struct string_list *list = priv;
const char **url;
int i, url_nr;
void **utilp;


if (remote->url_nr > 0) { if (remote->url_nr > 0) {
int i; utilp = &(string_list_append(remote->name, list)->util);

*utilp = xmalloc(strlen(remote->url[0])+strlen(" (fetch)")+1);
for (i = 0; i < remote->url_nr; i++) strcpy((char *) *utilp, remote->url[0]);
string_list_append(remote->name, list)->util = (void *)remote->url[i]; strcat((char *) *utilp, " (fetch)");
} else } else
string_list_append(remote->name, list)->util = NULL; string_list_append(remote->name, list)->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++)
{
utilp = &(string_list_append(remote->name, list)->util);
*utilp = xmalloc(strlen(url[i])+strlen(" (push)")+1);
strcpy((char *) *utilp, url[i]);
strcat((char *) *utilp, " (push)");
}


return 0; return 0;
} }
@ -1281,7 +1308,10 @@ static int get_one_entry(struct remote *remote, void *priv)
static int show_all(void) static int show_all(void)
{ {
struct string_list list = { NULL, 0, 0 }; struct string_list list = { NULL, 0, 0 };
int result = for_each_remote(get_one_entry, &list); int result;

list.strdup_strings = 1;
result = for_each_remote(get_one_entry, &list);


if (!result) { if (!result) {
int i; int i;
@ -1299,6 +1329,7 @@ static int show_all(void)
} }
} }
} }
string_list_clear(&list, 1);
return result; return result;
} }



14
remote.c

@ -106,6 +106,12 @@ static void add_url_alias(struct remote *remote, const char *url)
add_url(remote, alias_url(url)); add_url(remote, alias_url(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;
}

static struct remote *make_remote(const char *name, int len) static struct remote *make_remote(const char *name, int len)
{ {
struct remote *ret; struct remote *ret;
@ -379,6 +385,11 @@ static int handle_config(const char *key, const char *value, void *cb)
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
add_url(remote, v); add_url(remote, v);
} else if (!strcmp(subkey, ".pushurl")) {
const char *v;
if (git_config_string(&v, key, value))
return -1;
add_pushurl(remote, v);
} else if (!strcmp(subkey, ".push")) { } else if (!strcmp(subkey, ".push")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
@ -424,6 +435,9 @@ static void alias_all_urls(void)
for (j = 0; j < remotes[i]->url_nr; j++) { for (j = 0; j < remotes[i]->url_nr; j++) {
remotes[i]->url[j] = alias_url(remotes[i]->url[j]); remotes[i]->url[j] = alias_url(remotes[i]->url[j]);
} }
for (j = 0; j < remotes[i]->pushurl_nr; j++) {
remotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j]);
}
} }
} }



4
remote.h

@ -15,6 +15,10 @@ struct remote {
int url_nr; int url_nr;
int url_alloc; int url_alloc;


const char **pushurl;
int pushurl_nr;
int pushurl_alloc;

const char **push_refspec; const char **push_refspec;
struct refspec *push; struct refspec *push;
int push_refspec_nr; int push_refspec_nr;

10
t/t5505-remote.sh

@ -135,7 +135,8 @@ EOF


cat > test/expect << EOF cat > test/expect << EOF
* remote origin * remote origin
URL: $(pwd)/one Fetch URL: $(pwd)/one
Push URL: $(pwd)/one
HEAD branch: master HEAD branch: master
Remote branches: Remote branches:
master new (next fetch will store in remotes/origin) master new (next fetch will store in remotes/origin)
@ -151,7 +152,8 @@ cat > test/expect << EOF
master pushes to master (local out of date) master pushes to master (local out of date)
master pushes to upstream (create) master pushes to upstream (create)
* remote two * remote two
URL: ../two Fetch URL: ../two
Push URL: ../three
HEAD branch (remote HEAD is ambiguous, may be one of the following): HEAD branch (remote HEAD is ambiguous, may be one of the following):
another another
master master
@ -173,6 +175,7 @@ test_expect_success 'show' '
git branch --track rebase origin/master && git branch --track rebase origin/master &&
git branch -d -r origin/master && git branch -d -r origin/master &&
git config --add remote.two.url ../two && git config --add remote.two.url ../two &&
git config --add remote.two.pushurl ../three &&
git config branch.rebase.rebase true && git config branch.rebase.rebase true &&
git config branch.octopus.merge "topic-a topic-b topic-c" && git config branch.octopus.merge "topic-a topic-b topic-c" &&
(cd ../one && (cd ../one &&
@ -191,7 +194,8 @@ test_expect_success 'show' '


cat > test/expect << EOF cat > test/expect << EOF
* remote origin * remote origin
URL: $(pwd)/one Fetch URL: $(pwd)/one
Push URL: $(pwd)/one
HEAD branch: (not queried) HEAD branch: (not queried)
Remote branches: (status not queried) Remote branches: (status not queried)
master master

13
t/t5516-fetch-push.sh

@ -419,6 +419,19 @@ test_expect_success 'push with config remote.*.push = HEAD' '
git config --remove-section remote.there git config --remove-section remote.there
git config --remove-section branch.master git config --remove-section branch.master


test_expect_success 'push with config remote.*.pushurl' '

mk_test heads/master &&
git checkout master &&
git config remote.there.url test2repo &&
git config remote.there.pushurl testrepo &&
git push there &&
check_push_result $the_commit heads/master
'

# clean up the cruft left with the previous one
git config --remove-section remote.there

test_expect_success 'push with dry-run' ' test_expect_success 'push with dry-run' '


mk_test heads/master && mk_test heads/master &&

Loading…
Cancel
Save