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

8 messages from 2009-06-04 to 2009-06-07. Participants: Nikos Chantziaras, Junio C Hamano, Mike Gaffney, Michael J Gruber, Tay Ray Chuan, Linus Torvalds.
Thread: https://gitlist.dev/t/19667

## Nikos Chantziaras, 2009-06-04 23:16

Subject: Using different protocols for "pull" and "push".
Message-ID: <h09kk8$rb4$1@ger.gmane.org>
URL: https://gitlist.dev/e/h09kk8%24rb4%241%40ger.gmane.org

```
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, 2009-06-05 00:52

Subject: Re: Using different protocols for "pull" and "push".
Message-ID: <7v1vpztsci.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v1vpztsci.fsf%40alter.siamese.dyndns.org
In-Reply-To: <h09kk8$rb4$1@ger.gmane.org>

```
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.

```

## Mike Gaffney, 2009-06-05 15:03

Subject: Re: Using different protocols for "pull" and "push".
Message-ID: <4A2933B4.1060209@gmail.com>
URL: https://gitlist.dev/e/4A2933B4.1060209%40gmail.com
In-Reply-To: <h09kk8$rb4$1@ger.gmane.org>

```
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:
> 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

```

## Michael J Gruber, 2009-06-06 14:43

Subject: [WIP/RFC] Allow push and fetch urls to be different
Message-ID: <1244299395-6605-1-git-send-email-git@drmicha.warpmail.net>
URL: https://gitlist.dev/e/1244299395-6605-1-git-send-email-git%40drmicha.warpmail.net
In-Reply-To: <7v1vpztsci.fsf@alter.siamese.dyndns.org>

```
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, 2009-06-06 14:50

Subject: Re: [WIP/RFC] Allow push and fetch urls to be different
Message-ID: <be6fef0d0906060750u2da77229p59f21b59d0aef4d2@mail.gmail.com>
URL: https://gitlist.dev/e/be6fef0d0906060750u2da77229p59f21b59d0aef4d2%40mail.gmail.com
In-Reply-To: <1244299395-6605-1-git-send-email-git@drmicha.warpmail.net>

```
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, 2009-06-06 17:57

Subject: Re: [WIP/RFC] Allow push and fetch urls to be different
Message-ID: <alpine.LFD.2.01.0906061057160.6847@localhost.localdomain>
URL: https://gitlist.dev/e/alpine.LFD.2.01.0906061057160.6847%40localhost.localdomain
In-Reply-To: <1244299395-6605-1-git-send-email-git@drmicha.warpmail.net>

```


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, 2009-06-07 04:19

Subject: Re: [WIP/RFC] Allow push and fetch urls to be different
Message-ID: <7vtz2sbrqh.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vtz2sbrqh.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1244299395-6605-1-git-send-email-git@drmicha.warpmail.net>

```
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?

```

## Michael J Gruber, 2009-06-07 09:00

Subject: Re: [WIP/RFC] Allow push and fetch urls to be different
Message-ID: <4A2B819F.8010907@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4A2B819F.8010907%40drmicha.warpmail.net
In-Reply-To: <7vtz2sbrqh.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano venit, vidit, dixit 07.06.2009 06:19:
> 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

```
