{"thread":{"id":"20864","subject":"[PATCHv2 0/2] Add url.<base>.pushInsteadOf: URL rewriting for push only","startedAt":"2009-09-07T08:55:40Z","lastAt":"2009-09-08T16:34:50Z","messageCount":7,"participants":["Josh Triplett","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"122605","messageId":"cover.1252313313.git.josh@joshtriplett.org","threadId":"20864","inReplyTo":null,"subject":"[PATCHv2 0/2] Add url.<base>.pushInsteadOf: URL rewriting for push only","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2009-09-07T08:55:40Z","receivedAt":"2009-09-07T08:55:40Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"Many sites host repositories via both git:// for fetch-only anonymous\naccess and ssh:// for push-capable access.  The \"insteadOf\" mechanism\nmakes it straightforward to substitute the push-capable URLs for the\npull-only URLs, which proves convenient when the site hosts many\nrepositories using the same URL scheme.  However, if you use such a\nsubstitution and you cannot use the ssh:// URLs (either because you\ndon't have SSH access or you don't have permission to a particular\nrepository), you cannot clone or fetch either, even though you could do\nso via the git:// URLs.  A situation like this arises when sharing git\nconfiguration files between systems, of which only a few have SSH access\nto repositories.\n\n\"pushurl\" provides a way to specify URLs used only for push, but this\nrequires configuring a pushurl for each such repository.  As in the\nrationale for insteadOf, it makes sense to configure this for all\nrepositories hosted on a given system at once.\n\nThis patch series adds a new \"pushInsteadOf\" option to go with\n\"insteadOf\".  pushInsteadOf allows systematically rewriting fetch-only\nURLs to push-capable URLs when used with push.  For instance:\n\n[url \"ssh://example.org/\"]\n    pushInsteadOf = \"git://example.org/\"\n\nThis will allow clones of \"git://example.org/path/to/repo\" to\nsubsequently push to \"ssh://example.org/path/to/repo\", without manually\nconfiguring pushurl for that remote.\n\nIncludes documentation for the new option, bash completion updates, and\ntest cases (both that pushInsteadOf applies to push and that it does\n*not* apply to fetch).\n\n\nChanges in v2:\n - Don't add implicit pushurls from pushInsteadOf to remotes with explicit\n   pushurls (suggested by Junio).\n - Fix pushInsteadOf rewrites to occur before insteadOf rewrites, to avoid\n   basing the pushInsteadOf rewrites on the rewritten URLs.\n\n\nJosh Triplett (2):\n  Wrap rewrite globals in a struct in preparation for adding another set\n  Add url.<base>.pushInsteadOf: URL rewriting for push only\n\n Documentation/config.txt               |   13 +++++\n Documentation/urls.txt                 |   18 +++++++\n contrib/completion/git-completion.bash |    2 +-\n remote.c                               |   83 ++++++++++++++++++++------------\n t/t5516-fetch-push.sh                  |   31 ++++++++++++\n 5 files changed, 115 insertions(+), 32 deletions(-)\n"},{"id":"122606","messageId":"bdf2f41d610eb68d335bfd02c9bf4638a02a225a.1252313313.git.josh@joshtriplett.org","threadId":"20864","inReplyTo":"cover.1252313313.git.josh@joshtriplett.org","subject":"[PATCHv2 1/2] Wrap rewrite globals in a struct in preparation for adding another set","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2009-09-07T08:56:00Z","receivedAt":"2009-09-07T08:56:00Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"remote.c has a global set of URL rewrites, accessed by alias_url and\nmake_rewrite.  Wrap them in a new \"struct rewrites\", passed to alias_url\nand make_rewrite.  This allows adding other sets of rewrites.\n\nSigned-off-by: Josh Triplett <josh@joshtriplett.org>\n---\n remote.c |   53 ++++++++++++++++++++++++++++-------------------------\n 1 files changed, 28 insertions(+), 25 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 4b5b905..ff8e71f 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -28,6 +28,11 @@ struct rewrite {\n \tint instead_of_nr;\n \tint instead_of_alloc;\n };\n+struct rewrites {\n+\tstruct rewrite **rewrite;\n+\tint rewrite_alloc;\n+\tint rewrite_nr;\n+};\n \n static struct remote **remotes;\n static int remotes_alloc;\n@@ -41,14 +46,12 @@ static struct branch *current_branch;\n static const char *default_remote_name;\n static int explicit_default_remote_name;\n \n-static struct rewrite **rewrite;\n-static int rewrite_alloc;\n-static int rewrite_nr;\n+static struct rewrites rewrites;\n \n #define BUF_SIZE (2048)\n static char buffer[BUF_SIZE];\n \n-static const char *alias_url(const char *url)\n+static const char *alias_url(const char *url, struct rewrites *r)\n {\n \tint i, j;\n \tchar *ret;\n@@ -57,14 +60,14 @@ static const char *alias_url(const char *url)\n \n \tlongest = NULL;\n \tlongest_i = -1;\n-\tfor (i = 0; i < rewrite_nr; i++) {\n-\t\tif (!rewrite[i])\n+\tfor (i = 0; i < r->rewrite_nr; i++) {\n+\t\tif (!r->rewrite[i])\n \t\t\tcontinue;\n-\t\tfor (j = 0; j < rewrite[i]->instead_of_nr; j++) {\n-\t\t\tif (!prefixcmp(url, rewrite[i]->instead_of[j].s) &&\n+\t\tfor (j = 0; j < r->rewrite[i]->instead_of_nr; j++) {\n+\t\t\tif (!prefixcmp(url, r->rewrite[i]->instead_of[j].s) &&\n \t\t\t    (!longest ||\n-\t\t\t     longest->len < rewrite[i]->instead_of[j].len)) {\n-\t\t\t\tlongest = &(rewrite[i]->instead_of[j]);\n+\t\t\t     longest->len < r->rewrite[i]->instead_of[j].len)) {\n+\t\t\t\tlongest = &(r->rewrite[i]->instead_of[j]);\n \t\t\t\tlongest_i = i;\n \t\t\t}\n \t\t}\n@@ -72,10 +75,10 @@ static const char *alias_url(const char *url)\n \tif (!longest)\n \t\treturn url;\n \n-\tret = xmalloc(rewrite[longest_i]->baselen +\n+\tret = xmalloc(r->rewrite[longest_i]->baselen +\n \t\t     (strlen(url) - longest->len) + 1);\n-\tstrcpy(ret, rewrite[longest_i]->base);\n-\tstrcpy(ret + rewrite[longest_i]->baselen, url + longest->len);\n+\tstrcpy(ret, r->rewrite[longest_i]->base);\n+\tstrcpy(ret + r->rewrite[longest_i]->baselen, url + longest->len);\n \treturn ret;\n }\n \n@@ -103,7 +106,7 @@ static void add_url(struct remote *remote, const char *url)\n \n static void add_url_alias(struct remote *remote, const char *url)\n {\n-\tadd_url(remote, alias_url(url));\n+\tadd_url(remote, alias_url(url, &rewrites));\n }\n \n static void add_pushurl(struct remote *remote, const char *pushurl)\n@@ -169,22 +172,22 @@ static struct branch *make_branch(const char *name, int len)\n \treturn ret;\n }\n \n-static struct rewrite *make_rewrite(const char *base, int len)\n+static struct rewrite *make_rewrite(struct rewrites *r, const char *base, int len)\n {\n \tstruct rewrite *ret;\n \tint i;\n \n-\tfor (i = 0; i < rewrite_nr; i++) {\n+\tfor (i = 0; i < r->rewrite_nr; i++) {\n \t\tif (len\n-\t\t    ? (len == rewrite[i]->baselen &&\n-\t\t       !strncmp(base, rewrite[i]->base, len))\n-\t\t    : !strcmp(base, rewrite[i]->base))\n-\t\t\treturn rewrite[i];\n+\t\t    ? (len == r->rewrite[i]->baselen &&\n+\t\t       !strncmp(base, r->rewrite[i]->base, len))\n+\t\t    : !strcmp(base, r->rewrite[i]->base))\n+\t\t\treturn r->rewrite[i];\n \t}\n \n-\tALLOC_GROW(rewrite, rewrite_nr + 1, rewrite_alloc);\n+\tALLOC_GROW(r->rewrite, r->rewrite_nr + 1, r->rewrite_alloc);\n \tret = xcalloc(1, sizeof(struct rewrite));\n-\trewrite[rewrite_nr++] = ret;\n+\tr->rewrite[r->rewrite_nr++] = ret;\n \tif (len) {\n \t\tret->base = xstrndup(base, len);\n \t\tret->baselen = len;\n@@ -355,7 +358,7 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\tsubkey = strrchr(name, '.');\n \t\tif (!subkey)\n \t\t\treturn 0;\n-\t\trewrite = make_rewrite(name, subkey - name);\n+\t\trewrite = make_rewrite(&rewrites, name, subkey - name);\n \t\tif (!strcmp(subkey, \".insteadof\")) {\n \t\t\tif (!value)\n \t\t\t\treturn config_error_nonbool(key);\n@@ -433,10 +436,10 @@ static void alias_all_urls(void)\n \t\tif (!remotes[i])\n \t\t\tcontinue;\n \t\tfor (j = 0; j < remotes[i]->url_nr; j++) {\n-\t\t\tremotes[i]->url[j] = alias_url(remotes[i]->url[j]);\n+\t\t\tremotes[i]->url[j] = alias_url(remotes[i]->url[j], &rewrites);\n \t\t}\n \t\tfor (j = 0; j < remotes[i]->pushurl_nr; j++) {\n-\t\t\tremotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j]);\n+\t\t\tremotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j], &rewrites);\n \t\t}\n \t}\n }\n-- \n1.6.3.3\n"},{"id":"122607","messageId":"5e58748923d9b4a182499a6ba8fa4636bce4810e.1252313313.git.josh@joshtriplett.org","threadId":"20864","inReplyTo":"cover.1252313313.git.josh@joshtriplett.org","subject":"[PATCHv2 2/2] Add url.<base>.pushInsteadOf: URL rewriting for push only","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2009-09-07T08:56:33Z","receivedAt":"2009-09-07T08:56:33Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"This configuration option allows systematically rewriting fetch-only\nURLs to push-capable URLs when used with push.  For instance:\n\n[url \"ssh://example.org/\"]\n    pushInsteadOf = \"git://example.org/\"\n\nThis will allow clones of \"git://example.org/path/to/repo\" to\nsubsequently push to \"ssh://example.org/path/to/repo\", without manually\nconfiguring pushurl for that remote.\n\nIncludes documentation for the new option, bash completion updates, and\ntest cases (both that pushInsteadOf applies to push and that it does\n*not* apply to fetch).\n\nSigned-off-by: Josh Triplett <josh@joshtriplett.org>\n---\n Documentation/config.txt               |   13 +++++++++++\n Documentation/urls.txt                 |   18 ++++++++++++++++\n contrib/completion/git-completion.bash |    2 +-\n remote.c                               |   36 ++++++++++++++++++++++++--------\n t/t5516-fetch-push.sh                  |   31 +++++++++++++++++++++++++++\n 5 files changed, 90 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 5256c7f..38c7086 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1500,6 +1500,19 @@ url.<base>.insteadOf::\n \tnever-before-seen repository on the site.  When more than one\n \tinsteadOf strings match a given URL, the longest match is used.\n \n+url.<base>.pushInsteadOf::\n+\tAny URL that starts with this value will not be pushed to;\n+\tinstead, it will be rewritten to start with <base>, and the\n+\tresulting URL will be pushed to. In cases where some site serves\n+\ta large number of repositories, and serves them with multiple\n+\taccess methods, some of which do not allow push, this feature\n+\tallows people to specify a pull-only URL and have git\n+\tautomatically use an appropriate URL to push, even for a\n+\tnever-before-seen repository on the site.  When more than one\n+\tpushInsteadOf strings match a given URL, the longest match is\n+\tused.  If a remote has an explicit pushurl, git will ignore this\n+\tsetting for that remote.\n+\n user.email::\n \tYour email address to be recorded in any newly created commits.\n \tCan be overridden by the 'GIT_AUTHOR_EMAIL', 'GIT_COMMITTER_EMAIL', and\ndiff --git a/Documentation/urls.txt b/Documentation/urls.txt\nindex 5355ebc..d813ceb 100644\n--- a/Documentation/urls.txt\n+++ b/Documentation/urls.txt\n@@ -67,3 +67,21 @@ For example, with this:\n a URL like \"work:repo.git\" or like \"host.xz:/path/to/repo.git\" will be\n rewritten in any context that takes a URL to be \"git://git.host.xz/repo.git\".\n \n+If you want to rewrite URLs for push only, you can create a\n+configuration section of the form:\n+\n+------------\n+\t[url \"<actual url base>\"]\n+\t\tpushInsteadOf = <other url base>\n+------------\n+\n+For example, with this:\n+\n+------------\n+\t[url \"ssh://example.org/\"]\n+\t\tpushInsteadOf = git://example.org/\n+------------\n+\n+a URL like \"git://example.org/path/to/repo.git\" will be rewritten to\n+\"ssh://example.org/path/to/repo.git\" for pushes, but pulls will still\n+use the original URL.\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex bf688e1..9859204 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1532,7 +1532,7 @@ _git_config ()\n \turl.*.*)\n \t\tlocal pfx=\"${cur%.*}.\"\n \t\tcur=\"${cur##*.}\"\n-\t\t__gitcomp \"insteadof\" \"$pfx\" \"$cur\"\n+\t\t__gitcomp \"insteadOf pushInsteadOf\" \"$pfx\" \"$cur\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/remote.c b/remote.c\nindex ff8e71f..73d33f2 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -47,6 +47,7 @@ static const char *default_remote_name;\n static int explicit_default_remote_name;\n \n static struct rewrites rewrites;\n+static struct rewrites rewrites_push;\n \n #define BUF_SIZE (2048)\n static char buffer[BUF_SIZE];\n@@ -104,17 +105,25 @@ static void add_url(struct remote *remote, const char *url)\n \tremote->url[remote->url_nr++] = url;\n }\n \n-static void add_url_alias(struct remote *remote, const char *url)\n-{\n-\tadd_url(remote, alias_url(url, &rewrites));\n-}\n-\n static void add_pushurl(struct remote *remote, const char *pushurl)\n {\n \tALLOC_GROW(remote->pushurl, remote->pushurl_nr + 1, remote->pushurl_alloc);\n \tremote->pushurl[remote->pushurl_nr++] = pushurl;\n }\n \n+static void add_pushurl_alias(struct remote *remote, const char *url)\n+{\n+\tconst char *pushurl = alias_url(url, &rewrites_push);\n+\tif (pushurl != url)\n+\t\tadd_pushurl(remote, pushurl);\n+}\n+\n+static void add_url_alias(struct remote *remote, const char *url)\n+{\n+\tadd_url(remote, alias_url(url, &rewrites));\n+\tadd_pushurl_alias(remote, url);\n+}\n+\n static struct remote *make_remote(const char *name, int len)\n {\n \tstruct remote *ret;\n@@ -358,8 +367,13 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\tsubkey = strrchr(name, '.');\n \t\tif (!subkey)\n \t\t\treturn 0;\n-\t\trewrite = make_rewrite(&rewrites, name, subkey - name);\n \t\tif (!strcmp(subkey, \".insteadof\")) {\n+\t\t\trewrite = make_rewrite(&rewrites, name, subkey - name);\n+\t\t\tif (!value)\n+\t\t\t\treturn config_error_nonbool(key);\n+\t\t\tadd_instead_of(rewrite, xstrdup(value));\n+\t\t} else if (!strcmp(subkey, \".pushinsteadof\")) {\n+\t\t\trewrite = make_rewrite(&rewrites_push, name, subkey - name);\n \t\t\tif (!value)\n \t\t\t\treturn config_error_nonbool(key);\n \t\t\tadd_instead_of(rewrite, xstrdup(value));\n@@ -433,14 +447,18 @@ static void alias_all_urls(void)\n {\n \tint i, j;\n \tfor (i = 0; i < remotes_nr; i++) {\n+\t\tint add_pushurl_aliases;\n \t\tif (!remotes[i])\n \t\t\tcontinue;\n-\t\tfor (j = 0; j < remotes[i]->url_nr; j++) {\n-\t\t\tremotes[i]->url[j] = alias_url(remotes[i]->url[j], &rewrites);\n-\t\t}\n \t\tfor (j = 0; j < remotes[i]->pushurl_nr; j++) {\n \t\t\tremotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j], &rewrites);\n \t\t}\n+\t\tadd_pushurl_aliases = remotes[i]->pushurl_nr == 0;\n+\t\tfor (j = 0; j < remotes[i]->url_nr; j++) {\n+\t\t\tif (add_pushurl_aliases)\n+\t\t\t\tadd_pushurl_alias(remotes[i], remotes[i]->url[j]);\n+\t\t\tremotes[i]->url[j] = alias_url(remotes[i]->url[j], &rewrites);\n+\t\t}\n \t}\n }\n \ndiff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh\nindex 2d2633f..8f455c7 100755\n--- a/t/t5516-fetch-push.sh\n+++ b/t/t5516-fetch-push.sh\n@@ -122,6 +122,23 @@ test_expect_success 'fetch with insteadOf' '\n \t)\n '\n \n+test_expect_success 'fetch with pushInsteadOf (should not rewrite)' '\n+\tmk_empty &&\n+\t(\n+\t\tTRASH=$(pwd)/ &&\n+\t\tcd testrepo &&\n+\t\tgit config \"url.trash/.pushInsteadOf\" \"$TRASH\" &&\n+\t\tgit config remote.up.url \"$TRASH.\" &&\n+\t\tgit config remote.up.fetch \"refs/heads/*:refs/remotes/origin/*\" &&\n+\t\tgit fetch up &&\n+\n+\t\tr=$(git show-ref -s --verify refs/remotes/origin/master) &&\n+\t\ttest \"z$r\" = \"z$the_commit\" &&\n+\n+\t\ttest 1 = $(git for-each-ref refs/remotes/origin | wc -l)\n+\t)\n+'\n+\n test_expect_success 'push without wildcard' '\n \tmk_empty &&\n \n@@ -162,6 +179,20 @@ test_expect_success 'push with insteadOf' '\n \t)\n '\n \n+test_expect_success 'push with pushInsteadOf' '\n+\tmk_empty &&\n+\tTRASH=\"$(pwd)/\" &&\n+\tgit config \"url.$TRASH.pushInsteadOf\" trash/ &&\n+\tgit push trash/testrepo refs/heads/master:refs/remotes/origin/master &&\n+\t(\n+\t\tcd testrepo &&\n+\t\tr=$(git show-ref -s --verify refs/remotes/origin/master) &&\n+\t\ttest \"z$r\" = \"z$the_commit\" &&\n+\n+\t\ttest 1 = $(git for-each-ref refs/remotes/origin | wc -l)\n+\t)\n+'\n+\n test_expect_success 'push with matching heads' '\n \n \tmk_test heads/master &&\n-- \n1.6.3.3\n"},{"id":"122674","messageId":"7vws49gbql.fsf@alter.siamese.dyndns.org","threadId":"20864","inReplyTo":"5e58748923d9b4a182499a6ba8fa4636bce4810e.1252313313.git.josh@joshtriplett.org","subject":"Re: [PATCHv2 2/2] Add url.<base>.pushInsteadOf: URL rewriting for push only","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-09-08T07:02:42Z","receivedAt":"2009-09-08T07:02:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josh Triplett <josh@joshtriplett.org> writes:\n\n> This configuration option allows systematically rewriting fetch-only\n> URLs to push-capable URLs when used with push.  For instance:\n>\n> [url \"ssh://example.org/\"]\n>     pushInsteadOf = \"git://example.org/\"\n>\n> This will allow clones of \"git://example.org/path/to/repo\" to\n> subsequently push to \"ssh://example.org/path/to/repo\", without manually\n> configuring pushurl for that remote.\n>\n> Includes documentation for the new option, bash completion updates, and\n> test cases (both that pushInsteadOf applies to push and that it does\n> *not* apply to fetch).\n\nThanks.\n\nI will queue these patches, but I presume you would also want to add a\ntest that pushInsteadOf is ignored for remotes with an explicit pushURL?\n"},{"id":"122677","messageId":"20090908071513.GA3236@feather","threadId":"20864","inReplyTo":"7vws49gbql.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 2/2] Add url.<base>.pushInsteadOf: URL rewriting for push only","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2009-09-08T07:15:14Z","receivedAt":"2009-09-08T07:15:14Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"On Tue, Sep 08, 2009 at 12:02:42AM -0700, Junio C Hamano wrote:\n> Josh Triplett <josh@joshtriplett.org> writes:\n> \n> > This configuration option allows systematically rewriting fetch-only\n> > URLs to push-capable URLs when used with push.  For instance:\n> >\n> > [url \"ssh://example.org/\"]\n> >     pushInsteadOf = \"git://example.org/\"\n> >\n> > This will allow clones of \"git://example.org/path/to/repo\" to\n> > subsequently push to \"ssh://example.org/path/to/repo\", without manually\n> > configuring pushurl for that remote.\n> >\n> > Includes documentation for the new option, bash completion updates, and\n> > test cases (both that pushInsteadOf applies to push and that it does\n> > *not* apply to fetch).\n> \n> Thanks.\n> \n> I will queue these patches, but I presume you would also want to add a\n> test that pushInsteadOf is ignored for remotes with an explicit pushURL?\n\nWill do.\n\n- Josh Triplett\n"},{"id":"122680","messageId":"20090908074147.GB3236@feather","threadId":"20864","inReplyTo":"20090908071513.GA3236@feather","subject":"[PATCH] Add test for ignoring pushInsteadOf when remote has explicit pushurl","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2009-09-08T07:41:48Z","receivedAt":"2009-09-08T07:41:48Z","isPatch":true,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"Signed-off-by: Josh Triplett <josh@joshtriplett.org>\n---\n\nOn Tue, Sep 08, 2009 at 12:15:13AM -0700, Josh Triplett wrote:\n> On Tue, Sep 08, 2009 at 12:02:42AM -0700, Junio C Hamano wrote:\n> > Josh Triplett <josh@joshtriplett.org> writes:\n> > \n> > > This configuration option allows systematically rewriting fetch-only\n> > > URLs to push-capable URLs when used with push.  For instance:\n> > >\n> > > [url \"ssh://example.org/\"]\n> > >     pushInsteadOf = \"git://example.org/\"\n> > >\n> > > This will allow clones of \"git://example.org/path/to/repo\" to\n> > > subsequently push to \"ssh://example.org/path/to/repo\", without manually\n> > > configuring pushurl for that remote.\n> > >\n> > > Includes documentation for the new option, bash completion updates, and\n> > > test cases (both that pushInsteadOf applies to push and that it does\n> > > *not* apply to fetch).\n> > \n> > Thanks.\n> > \n> > I will queue these patches, but I presume you would also want to add a\n> > test that pushInsteadOf is ignored for remotes with an explicit pushURL?\n> \n> Will do.\n\nDone.  Please add this to the queue, optionally squashing it into patch\n2/2 if you prefer.\n\n t/t5516-fetch-push.sh |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh\nindex 8f455c7..6889a53 100755\n--- a/t/t5516-fetch-push.sh\n+++ b/t/t5516-fetch-push.sh\n@@ -193,6 +193,22 @@ test_expect_success 'push with pushInsteadOf' '\n \t)\n '\n \n+test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '\n+\tmk_empty &&\n+\tTRASH=\"$(pwd)/\" &&\n+\tgit config \"url.trash2/.pushInsteadOf\" trash/ &&\n+\tgit config remote.r.url trash/wrong &&\n+\tgit config remote.r.pushurl \"$TRASH/testrepo\" &&\n+\tgit push r refs/heads/master:refs/remotes/origin/master &&\n+\t(\n+\t\tcd testrepo &&\n+\t\tr=$(git show-ref -s --verify refs/remotes/origin/master) &&\n+\t\ttest \"z$r\" = \"z$the_commit\" &&\n+\n+\t\ttest 1 = $(git for-each-ref refs/remotes/origin | wc -l)\n+\t)\n+'\n+\n test_expect_success 'push with matching heads' '\n \n \tmk_test heads/master &&\n-- \n1.6.3.3\n"},{"id":"122712","messageId":"7vtyzd8ket.fsf@alter.siamese.dyndns.org","threadId":"20864","inReplyTo":"20090908074147.GB3236@feather","subject":"Re: [PATCH] Add test for ignoring pushInsteadOf when remote has explicit pushurl","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-09-08T16:34:50Z","receivedAt":"2009-09-08T16:34:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josh Triplett <josh@joshtriplett.org> writes:\n\n> Done.  Please add this to the queue, optionally squashing it into patch\n> 2/2 if you prefer.\n\nThanks.\n"}]}