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
This commit is contained in:
commit
deded16d15
@ -1319,6 +1319,9 @@ remote.<name>.url::
|
||||
The URL of a remote repository. See linkgit:git-fetch[1] or
|
||||
linkgit:git-push[1].
|
||||
|
||||
remote.<name>.pushurl::
|
||||
The push URL of a remote repository. See linkgit:git-push[1].
|
||||
|
||||
remote.<name>.proxy::
|
||||
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
|
||||
|
@ -18,6 +18,10 @@ struct 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`::
|
||||
|
||||
An array of refspecs configured for pushing, with
|
||||
|
@ -27,10 +27,13 @@ config file would appear like this:
|
||||
------------
|
||||
[remote "<name>"]
|
||||
url = <url>
|
||||
pushurl = <pushurl>
|
||||
push = <refspec>
|
||||
fetch = <refspec>
|
||||
------------
|
||||
|
||||
The `<pushurl>` is used for pushes only. It is optional and defaults
|
||||
to `<url>`.
|
||||
|
||||
Named file in `$GIT_DIR/remotes`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -117,6 +117,8 @@ static int do_push(const char *repo, int flags)
|
||||
{
|
||||
int i, errs;
|
||||
struct remote *remote = remote_get(repo);
|
||||
const char **url;
|
||||
int url_nr;
|
||||
|
||||
if (!remote) {
|
||||
if (repo)
|
||||
@ -152,9 +154,16 @@ static int do_push(const char *repo, int flags)
|
||||
setup_default_push_refspecs();
|
||||
}
|
||||
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 =
|
||||
transport_get(remote, remote->url[i]);
|
||||
transport_get(remote, url[i]);
|
||||
int err;
|
||||
if (receivepack)
|
||||
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");
|
||||
|
||||
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_disconnect(transport);
|
||||
|
||||
if (!err)
|
||||
continue;
|
||||
|
||||
error("failed to push some refs to '%s'", remote->url[i]);
|
||||
error("failed to push some refs to '%s'", url[i]);
|
||||
errs++;
|
||||
}
|
||||
return !!errs;
|
||||
|
@ -999,15 +999,25 @@ static int show(int argc, const char **argv)
|
||||
info.list = &info_list;
|
||||
for (; argc; argc--, argv++) {
|
||||
int i;
|
||||
const char **url;
|
||||
int url_nr;
|
||||
|
||||
get_remote_ref_states(*argv, &states, query_flag);
|
||||
|
||||
printf("* remote %s\n", *argv);
|
||||
if (states.remote->url_nr) {
|
||||
for (i=0; i < states.remote->url_nr; i++)
|
||||
printf(" URL: %s\n", states.remote->url[i]);
|
||||
} else
|
||||
printf(" URL: %s\n", "(no URL)");
|
||||
printf(" Fetch URL: %s\n", states.remote->url_nr > 0 ?
|
||||
states.remote->url[0] : "(no URL)");
|
||||
if (states.remote->pushurl_nr) {
|
||||
url = states.remote->pushurl;
|
||||
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)
|
||||
printf(" HEAD branch: (not queried)\n");
|
||||
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)
|
||||
{
|
||||
struct string_list *list = priv;
|
||||
const char **url;
|
||||
int i, url_nr;
|
||||
void **utilp;
|
||||
|
||||
if (remote->url_nr > 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < remote->url_nr; i++)
|
||||
string_list_append(remote->name, list)->util = (void *)remote->url[i];
|
||||
utilp = &(string_list_append(remote->name, list)->util);
|
||||
*utilp = xmalloc(strlen(remote->url[0])+strlen(" (fetch)")+1);
|
||||
strcpy((char *) *utilp, remote->url[0]);
|
||||
strcat((char *) *utilp, " (fetch)");
|
||||
} else
|
||||
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;
|
||||
}
|
||||
@ -1281,7 +1308,10 @@ static int get_one_entry(struct remote *remote, void *priv)
|
||||
static int show_all(void)
|
||||
{
|
||||
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) {
|
||||
int i;
|
||||
@ -1299,6 +1329,7 @@ static int show_all(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
string_list_clear(&list, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
14
remote.c
14
remote.c
@ -106,6 +106,12 @@ static void add_url_alias(struct remote *remote, const char *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)
|
||||
{
|
||||
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))
|
||||
return -1;
|
||||
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")) {
|
||||
const char *v;
|
||||
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++) {
|
||||
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
4
remote.h
@ -15,6 +15,10 @@ struct remote {
|
||||
int url_nr;
|
||||
int url_alloc;
|
||||
|
||||
const char **pushurl;
|
||||
int pushurl_nr;
|
||||
int pushurl_alloc;
|
||||
|
||||
const char **push_refspec;
|
||||
struct refspec *push;
|
||||
int push_refspec_nr;
|
||||
|
@ -135,7 +135,8 @@ EOF
|
||||
|
||||
cat > test/expect << EOF
|
||||
* remote origin
|
||||
URL: $(pwd)/one
|
||||
Fetch URL: $(pwd)/one
|
||||
Push URL: $(pwd)/one
|
||||
HEAD branch: master
|
||||
Remote branches:
|
||||
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 upstream (create)
|
||||
* remote two
|
||||
URL: ../two
|
||||
Fetch URL: ../two
|
||||
Push URL: ../three
|
||||
HEAD branch (remote HEAD is ambiguous, may be one of the following):
|
||||
another
|
||||
master
|
||||
@ -173,6 +175,7 @@ test_expect_success 'show' '
|
||||
git branch --track rebase origin/master &&
|
||||
git branch -d -r origin/master &&
|
||||
git config --add remote.two.url ../two &&
|
||||
git config --add remote.two.pushurl ../three &&
|
||||
git config branch.rebase.rebase true &&
|
||||
git config branch.octopus.merge "topic-a topic-b topic-c" &&
|
||||
(cd ../one &&
|
||||
@ -191,7 +194,8 @@ test_expect_success 'show' '
|
||||
|
||||
cat > test/expect << EOF
|
||||
* remote origin
|
||||
URL: $(pwd)/one
|
||||
Fetch URL: $(pwd)/one
|
||||
Push URL: $(pwd)/one
|
||||
HEAD branch: (not queried)
|
||||
Remote branches: (status not queried)
|
||||
master
|
||||
|
@ -419,6 +419,19 @@ test_expect_success 'push with config remote.*.push = HEAD' '
|
||||
git config --remove-section remote.there
|
||||
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' '
|
||||
|
||||
mk_test heads/master &&
|
||||
|
Loading…
Reference in New Issue
Block a user