threads / discuss / 19667

Using different protocols for "pull" and "push".

Subject: Using different protocols for "pull" and "push".

## tl;dr

8 messages between Jun 4, 2009 and Jun 7, 2009.

replies: 7people: 6as markdown or json

Nikos Chantziaras· Jun 4, 2009, 23:16 UTC · lore
Hi.

I wonder if it's possible to setup Git (probably in .git/config) to use SSH only for "git push" and use the git protocol for "git pull". My current configuration is:

[remote "origin"]
         url = ssh://user@project.someserver.net/gitroot/project
         fetch = +refs/heads/*:refs/remotes/origin/*

Issuing a "git pull" command results in pulling using SSH (along with asking for a password). Is there a way to alter the configuration so that a "pull" will use git:// instead of ssh:// ?

Junio C Hamano· Jun 5, 2009, 00:52 UTC · re: Nikos Chantziaras · lore

Re: Using different protocols for "pull" and "push".

Nikos Chantziaras <realnc@arcor.de> writes:
> I wonder if it's possible to setup Git (probably in .git/config) to
> use SSH only for "git push" and use the git protocol for "git pull".

The configuration format does not allow it, unfortunately. We should be able to introduce remote.$name.pushurl that is used only for push if present (and fall back to remote.$name.url if there isn't) reasonably easily, though.

Michael J Gruber· Jun 6, 2009, 14:43 UTC · re: Junio C Hamano · lore

[WIP/RFC] 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 to do passwordless fetches (remote update) over git: but pushes over ssh.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
This is a working prototype, but I'd like to rfc about the approach before
coding further. Do I need to do anything in http-push.c? I don't think so.
Things that would go in a full series:
* documentation (man pages, maybe manual)
* tests
* teach builtin-remote about pushurl
 builtin-push.c |   17 +++++++++++++----
 remote.c       |   14 ++++++++++++++
 remote.h       |    4 ++++
 3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/builtin-push.c b/builtin-push.c
index c869974..7be1239 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -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;
diff --git a/remote.c b/remote.c
index 08a5964..9a0397e 100644
--- a/remote.c
+++ b/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]);
+		}
 	}
 }
 
diff --git a/remote.h b/remote.h
index 257a555..5db8420 100644
--- a/remote.h
+++ b/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;
-- 
1.6.3.2.277.gd10543
Tay Ray Chuan· Jun 6, 2009, 14:50 UTC · re: Michael J Gruber · lore

Re: [WIP/RFC] Allow push and fetch urls to be different

Hi,

On Sat, Jun 6, 2009 at 10:43 PM, Michael J Gruber<git@drmicha.warpmail.net> wrote:

> This is a working prototype, but I'd like to rfc about the approach before
> coding further. Do I need to do anything in http-push.c? I don't think so.

As long as you're "controlling" the url before it gets used (like you're doing now in builtin-push.c), you don't have to bother about http-push.c.

-- 
Cheers,
Ray Chuan
Linus Torvalds· Jun 6, 2009, 17:57 UTC · re: Michael J Gruber · lore

Re: [WIP/RFC] Allow push and fetch urls to be different

On Sat, 6 Jun 2009, Michael J Gruber wrote:
>
> 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.
Ack, looks sane to me. 
			Linus
Junio C Hamano· Jun 7, 2009, 04:19 UTC · re: Michael J Gruber · lore

Re: [WIP/RFC] Allow push and fetch urls to be different

Michael J Gruber <git@drmicha.warpmail.net> writes:
Show 10 quoted lines
> 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 to do passwordless fetches
> (remote update) over git: but pushes over ssh.
>
> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
> ---
> This is a working prototype, but I'd like to rfc about the approach before
> coding further.

As I am guilty for suggesting this, obviously I do not have a problem with what the patch wants to achieve.

And the change looks simple, straightforward and correct.
> Things that would go in a full series:
> * documentation (man pages, maybe manual)
> * tests
Surely.
> * teach builtin-remote about pushurl

Hmm,... my impression was that "git remote" does not have much support for the push side. What kind of things are you going to teach?

Michael J Gruber· Jun 7, 2009, 09:00 UTC · re: Junio C Hamano · lore

Re: [WIP/RFC] Allow push and fetch urls to be different

Junio C Hamano venit, vidit, dixit 07.06.2009 06:19:
Show 28 quoted lines
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> 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 to do passwordless fetches
>> (remote update) over git: but pushes over ssh.
>>
>> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
>> ---
>> This is a working prototype, but I'd like to rfc about the approach before
>> coding further.
> 
> As I am guilty for suggesting this, obviously I do not have a problem with
> what the patch wants to achieve.
> 
> And the change looks simple, straightforward and correct.
> 
>> Things that would go in a full series:
>> * documentation (man pages, maybe manual)
>> * tests
> 
> Surely.
> 
>> * teach builtin-remote about pushurl
> 
> Hmm,...  my impression was that "git remote" does not have much support
> for the push side.  What kind of things are you going to teach?

First I was thinking about rm and mv, but that's being taken care of automatically by removing/renaming a config section. This leaves "remote show $remote" which should list the pushurls along with the urls. "remote -v" should probably list urls but not pushurls. I don't plan on adding pushurl support to "remote add", I think using git config is OK for this setting.

Michael
Mike Gaffney· Jun 5, 2009, 15:03 UTC · re: Nikos Chantziaras · lore

Re: Using different protocols for "pull" and "push".

I typically set up a "push" remote when I need to do things like this. I've got a few projects where I get confused of which one is origin so I protect myself from pushing accidentally (I have to think for a second when pushing).

-Mike
Nikos Chantziaras wrote:
Show 18 quoted lines
> Hi.
>
> I wonder if it's possible to setup Git (probably in .git/config) to 
> use SSH only for "git push" and use the git protocol for "git pull".  
> My current configuration is:
>
> [remote "origin"]
>         url = ssh://user@project.someserver.net/gitroot/project
>         fetch = +refs/heads/*:refs/remotes/origin/*
>
> Issuing a "git pull" command results in pulling using SSH (along with 
> asking for a password).  Is there a way to alter the configuration so 
> that a "pull" will use git:// instead of ssh:// ?
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

← back to recent threads