# branch.<name>.pushremote not working with push.default simple or upstream

9 messages from 2013-06-07 to 2013-06-07. Participants: Leandro Lucarella, Ramkumar Ramachandra, Junio C Hamano.
Thread: https://gitlist.dev/t/34049

## Leandro Lucarella, 2013-06-07 12:41

Subject: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <20130607124146.GF28668@sociomantic.com>
URL: https://gitlist.dev/e/20130607124146.GF28668%40sociomantic.com

```
Hi, I tried to use the new Git feature to push by default to a different
remote you normally pull but I had some problems. I asked in the #git
IRC channel and been told it looks like a bug and to report it here.

I have 2 remotes, origin and upstream. origin is my private fork (and I
can push to it) while upstream is read-only for me. I have only one
branch, 'master' (present in all the remotes), originally tracking
origin/master.

I changed branch.master.remote to upstream and set
branch.master.pushremote to origin, but when I do I git push I get an
error:

$ git push --dry-run --verbose
fatal: You are pushing to remote 'origin', which is not the upstream of
your current branch 'master', without telling me what to push
to update which remote branch.

I'm using push.default 'simple' to stay forward compatible with Git 2.0.
In the IRC channel they suggested to try with other push.default
settings and I did. 'matching' and 'current' works, but 'simple' and
'upstream' fail with the error message above.

Thank you.

-- 
Leandro Lucarella
Senior R&D Developer
sociomantic labs GmbH <http://www.sociomantic.com>

```

## Ramkumar Ramachandra, 2013-06-07 14:11

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <CALkWK0miONv_O67SHcfJoXq1x7xPvKu6uefg+TiPGbF-1WJ-bg@mail.gmail.com>
URL: https://gitlist.dev/e/CALkWK0miONv_O67SHcfJoXq1x7xPvKu6uefg%2BTiPGbF-1WJ-bg%40mail.gmail.com
In-Reply-To: <20130607124146.GF28668@sociomantic.com>

```
[+CC: jc, jk]

Leandro Lucarella wrote:
> I changed branch.master.remote to upstream and set
> branch.master.pushremote to origin, but when I do I git push I get an
> error:
>
> $ git push --dry-run --verbose
> fatal: You are pushing to remote 'origin', which is not the upstream of
> your current branch 'master', without telling me what to push
> to update which remote branch.

Yes, this is a defect: both remote.pushdefault and
branch.<name>.pushremote suffer from it.

Let me explain what's happening.  The error is triggered off in
setup_push_upstream() in builtin/push.c (which both simple and
upstream use).  It's exactly the same error that will be reported if
you do the following without a branch.master.pushremote or
remote.pushdefault configured:

  $ git push origin --dry-run --verbose
  fatal: You are pushing to remote 'origin', which is not the upstream of
  your current branch 'master', without telling me what to push
  to update which remote branch.

You should therefore be able to infer that remote.pushdefault/
branch.<name>.pushremote is simply saving you from remembering/ typing
out that "origin" on the command-line.  The error precisely describes
the problem.  To understand what this "upstream" the error is talking
about, see:

   $ git rev-parse --symbolic-full-name @{u}
   refs/remotes/upstream/master

So, if you are pushing to upstream, the push knows what to do: push to
the refspec <branch>:<branch>@{u} (see builtin/push.c:148).  If you're
pushing to origin, it has no idea _what_ to push, and hence errors
out.  By design, upstream/ simple assume that you push to the same
place that you pull from: the description clearly says that it is
intended to make the push and pull symmetric.

Finally, the reason remote.pushdefault/ branch.<name>.pushremote works
in the other modes is simple: in matching and current, the push
refspec is not dependent on the current branch's upstream.  In
matching, the refspec it is the constant ":", and in current, it is
the constant "HEAD" (will subtly change with rr/push-head).

I think the correct fix is to change the semantics of upstream/simple
to dictate a refspec independent of remote.  So, if:

1. branch.master.merge is configured to refs/heads/rr/master
2. branch.master.remote is configured to origin
3. remote.pushdefault is configured to ram
4. push.default is configured to upstream

Then, the a push should push the refspec master:rr/master to the
remote ram.  Let's see what the others have to say before proceeding.

Thank you for reporting this problem.  It is indeed very serious,
especially since simple is going to be default in Git 2.0.

```

## Junio C Hamano, 2013-06-07 15:47

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <7v8v2lvs5s.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v8v2lvs5s.fsf%40alter.siamese.dyndns.org
In-Reply-To: <CALkWK0miONv_O67SHcfJoXq1x7xPvKu6uefg+TiPGbF-1WJ-bg@mail.gmail.com>

```
Ramkumar Ramachandra <artagnon@gmail.com> writes:

> [+CC: jc, jk]
>
> Leandro Lucarella wrote:
>> I changed branch.master.remote to upstream and set
>> branch.master.pushremote to origin, but when I do I git push I get an
>> error:
>>
>> $ git push --dry-run --verbose
>> fatal: You are pushing to remote 'origin', which is not the upstream of
>> your current branch 'master', without telling me what to push
>> to update which remote branch.
>
> Yes, this is a defect: both remote.pushdefault and
> branch.<name>.pushremote suffer from it.

The upstream and simple modes have been defined to push to
"upstream" repository in central-shared-repository workflow.

At this point in Leandro's example, I think the configuration is:

	[branch "master"]
		remote = upstream
                merge = refs/heads/master
                pushremote = origin

and master@{u} == upstream's master, not origin's.

This shows the "triangular" support in 1.8.3 is only half-finished;
the other half was discussed a few weeks ago ($gmane/224604), but I
do not recall what the current status of the topic is.  I personally
think 'single' the root level of the thread hints is an overkill
mechanism, so here is a suggestion to show one possible way forward.

Until the branch.$name.push mechanism is introduced to specify which
destination branch is updated by the push, and/or branch.$name.push
is not specified after such a mechanism is introduced, I think the
natural extension of the current end-user configuration would be to
redefine "upstream" mode to push to update the branch with the same
name (in the above example, 'master' of 'origin' is updated), when
the "repository that is pushed to, which is different from the
repository that is fetched from" is specified via remote.pushdefault
or branch.$name.pushremote mechanisms.

This incidentally covers "simple" mode, because "pushing to update
the branch with the same name" is the only behaviour accepted by the
mode anyway.

When branch.$name.push mechanism is introduced and the user uses it,
then "upstream", "simple", or any other setting for that matter
would be ignored.  With

	[branch "master"]
		remote = upstream
                merge = refs/heads/master
                pushremote = origin
		push = refs/heads/master

it is clear that "git push" while on 'master' should push to origin
to update its master branch.

```

## Leandro Lucarella, 2013-06-07 16:14

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <20130607161402.GH28668@sociomantic.com>
URL: https://gitlist.dev/e/20130607161402.GH28668%40sociomantic.com
In-Reply-To: <7v8v2lvs5s.fsf@alter.siamese.dyndns.org>

```
On Fri, Jun 07, 2013 at 08:47:59AM -0700, Junio C Hamano wrote:
> When branch.$name.push mechanism is introduced and the user uses it,
> then "upstream", "simple", or any other setting for that matter
> would be ignored.  With
> 
> 	[branch "master"]
> 		remote = upstream
>                 merge = refs/heads/master
>                 pushremote = origin
> 		push = refs/heads/master
> 
> it is clear that "git push" while on 'master' should push to origin
> to update its master branch.

Thanks for the detailed explanations, I think this would cover my use
case. Just for clarification, here are some more details on this use
case, which I think is becoming very popular among github users.
We have a "blessed" repository (upstream in my case) and only a few
people is able to push to it (let's call them maintainers). Every
developer, including the ones with push access, have to go through peer
reviewing and are not allowed to push their own commits to upstream. For
peer reviewing, each have it's own public fork, that other people can
review and merge/push if is good.

In this scheme, you always pull from the blessed repository and only
push to your personal fork, with the exceptions of the maintainers that
need to push from time to time other people pull requests.

My ideal would be to be able to just do 'git pull' to get the new stuff
and 'git push' to push to my fork. Since pushing to the blessed
repository is more "critical", is perfect that I need to explicitly push
to it with 'git push upstream master'.

Thank you.

-- 
Leandro Lucarella
Senior R&D Developer
sociomantic labs GmbH <http://www.sociomantic.com>

```

## Ramkumar Ramachandra, 2013-06-07 16:51

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <CALkWK0m0QDGVUmHkmzC7G6it9fJafQCh8+423-NOyMwq9yts1Q@mail.gmail.com>
URL: https://gitlist.dev/e/CALkWK0m0QDGVUmHkmzC7G6it9fJafQCh8%2B423-NOyMwq9yts1Q%40mail.gmail.com
In-Reply-To: <7v8v2lvs5s.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano wrote:
> This shows the "triangular" support in 1.8.3 is only half-finished;
> the other half was discussed a few weeks ago ($gmane/224604)

I intentionally omitted that detail, because it is not directly
related to this bug.  We have to fix the existing simple and upstream,
whether or not we introduce branch.<name>.push.  I've personally
stopped working on branch.<name>.push, and am focusing on getting @{p}
first (you've already seen a dirty wip).  The transport code
underlying the push is dirty enough, and I'd first like to understand
it before bolting on more features.

> I think the
> natural extension of the current end-user configuration would be to
> redefine "upstream" mode to push to update the branch with the same
> name

Right, so does this work?

diff --git a/builtin/push.c b/builtin/push.c
index 2d84d10..b253a64 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -137,11 +137,6 @@ static void setup_push_upstream(struct remote
 	if (branch->merge_nr != 1)
 		die(_("The current branch %s has multiple upstream branches, "
 		    "refusing to push."), branch->name);
-	if (strcmp(branch->remote_name, remote->name))
-		die(_("You are pushing to remote '%s', which is not the upstream of\n"
-		      "your current branch '%s', without telling me what to push\n"
-		      "to update which remote branch."),
-		    remote->name, branch->name);
 	if (simple && strcmp(branch->refname, branch->merge[0]->src))
 		die_push_simple(branch, remote);

```

## Ramkumar Ramachandra, 2013-06-07 16:57

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <CALkWK0=v2vF7oGG3yUAXfaGdodCrkbvmQA+z9hMcoeMUFGFgsg@mail.gmail.com>
URL: https://gitlist.dev/e/CALkWK0%3Dv2vF7oGG3yUAXfaGdodCrkbvmQA%2Bz9hMcoeMUFGFgsg%40mail.gmail.com
In-Reply-To: <20130607161402.GH28668@sociomantic.com>

```
Leandro Lucarella wrote:
> Thanks for the detailed explanations, I think this would cover my use
> case. Just for clarification, here are some more details on this use
> case, which I think is becoming very popular among github users.
> We have a "blessed" repository (upstream in my case) and only a few
> people is able to push to it (let's call them maintainers). Every
> developer, including the ones with push access, have to go through peer
> reviewing and are not allowed to push their own commits to upstream. For
> peer reviewing, each have it's own public fork, that other people can
> review and merge/push if is good.

Yes, and I wrote it precisely to address this itch.  git/git is
origin, and artagnon/git is ram.  I just set remote.pushdefault to ram
and continue working as usual.

I apologize for not having thought hard enough about other
push.default modes: I personally use current, and like it very much.
As an added bonus, even new branches created with git checkout -b
hot-branch will get push to go to the right place; no need to set
upstream before pushing.

```

## Leandro Lucarella, 2013-06-07 17:07

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <20130607170752.GI28668@sociomantic.com>
URL: https://gitlist.dev/e/20130607170752.GI28668%40sociomantic.com
In-Reply-To: <CALkWK0=v2vF7oGG3yUAXfaGdodCrkbvmQA+z9hMcoeMUFGFgsg@mail.gmail.com>

```
On Fri, Jun 07, 2013 at 10:27:58PM +0530, Ramkumar Ramachandra wrote:
> Leandro Lucarella wrote:
> > Thanks for the detailed explanations, I think this would cover my use
> > case. Just for clarification, here are some more details on this use
> > case, which I think is becoming very popular among github users.
> > We have a "blessed" repository (upstream in my case) and only a few
> > people is able to push to it (let's call them maintainers). Every
> > developer, including the ones with push access, have to go through peer
> > reviewing and are not allowed to push their own commits to upstream. For
> > peer reviewing, each have it's own public fork, that other people can
> > review and merge/push if is good.
> 
> Yes, and I wrote it precisely to address this itch.  git/git is
> origin, and artagnon/git is ram.  I just set remote.pushdefault to ram
> and continue working as usual.
> 
> I apologize for not having thought hard enough about other
> push.default modes: I personally use current, and like it very much.
> As an added bonus, even new branches created with git checkout -b
> hot-branch will get push to go to the right place; no need to set
> upstream before pushing.

I might try to just switch to current, I feel more comfortable with
simple because I feel is safer to explicitly set the upstream branch,
but is true that most of the time is not necessary.

-- 
Leandro Lucarella
Senior R&D Developer
sociomantic labs GmbH <http://www.sociomantic.com>

```

## Ramkumar Ramachandra, 2013-06-07 17:33

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <CALkWK0=FnZUBXMJjSKgrbunDn3TtME-1tw++B5FimJx5=K_1qQ@mail.gmail.com>
URL: https://gitlist.dev/e/CALkWK0%3DFnZUBXMJjSKgrbunDn3TtME-1tw%2B%2BB5FimJx5%3DK_1qQ%40mail.gmail.com
In-Reply-To: <20130607170752.GI28668@sociomantic.com>

```
Leandro Lucarella wrote:
> I might try to just switch to current, I feel more comfortable with
> simple because I feel is safer to explicitly set the upstream branch,
> but is true that most of the time is not necessary.

Be more experimental!  Use the lesser-known features, and tell us
about breakages: that's how you can help git improve :)

```

## Junio C Hamano, 2013-06-07 18:34

Subject: Re: branch.<name>.pushremote not working with push.default simple or upstream
Message-ID: <7vhah9u5w3.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vhah9u5w3.fsf%40alter.siamese.dyndns.org
In-Reply-To: <CALkWK0m0QDGVUmHkmzC7G6it9fJafQCh8+423-NOyMwq9yts1Q@mail.gmail.com>

```
Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Junio C Hamano wrote:
>> This shows the "triangular" support in 1.8.3 is only half-finished;
>> the other half was discussed a few weeks ago ($gmane/224604)
>
> I intentionally omitted that detail, because it is not directly
> related to this bug.  We have to fix the existing simple and upstream,
> whether or not we introduce branch.<name>.push.  I've personally
> stopped working on branch.<name>.push, and am focusing on getting @{p}
> first (you've already seen a dirty wip).  The transport code
> underlying the push is dirty enough, and I'd first like to understand
> it before bolting on more features.
>
>> I think the
>> natural extension of the current end-user configuration would be to
>> redefine "upstream" mode to push to update the branch with the same
>> name
>
> Right, so does this work?

It might be a beginning of a change in the right direction (I didn't
check the codeflow), but given that the test that comes after the
one you removed is looking at branch->merge[0] and deciding what to
do, and branch.$name.merge should *never* affect anything when
remote.pushdefault or branch.$name.pushremote is in use while
deciding what is pushed out or if the push is allowed, I do not
think the removal of these five lines alone can possibly "work".

> diff --git a/builtin/push.c b/builtin/push.c
> index 2d84d10..b253a64 100644
> --- a/builtin/push.c
> +++ b/builtin/push.c
> @@ -137,11 +137,6 @@ static void setup_push_upstream(struct remote
>  	if (branch->merge_nr != 1)
>  		die(_("The current branch %s has multiple upstream branches, "
>  		    "refusing to push."), branch->name);
> -	if (strcmp(branch->remote_name, remote->name))
> -		die(_("You are pushing to remote '%s', which is not the upstream of\n"
> -		      "your current branch '%s', without telling me what to push\n"
> -		      "to update which remote branch."),
> -		    remote->name, branch->name);
>  	if (simple && strcmp(branch->refname, branch->merge[0]->src))
>  		die_push_simple(branch, remote);

```
