All of lore.kernel.org
 help / color / mirror / Atom feed
* [ITCH] Specify refspec without remote
@ 2013-03-18 16:58 Ramkumar Ramachandra
  2013-03-18 17:08 ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-03-18 16:58 UTC (permalink / raw)
  To: Git List

Hi,

This has irritated me for a long time.  I often end up doing:

    $ git push master:master +pu:pu

only to get an error, because I have to specify the remote before
specifying the refspec.  I find this ugly because I rarely want to
push to a remote that is different from the one configured, but often
want to specify my own refspec (say which branches to push, force
push).  Ofcourse, the same is the case while fetching.

Is there a reason for the remote not being optional, or are we just
waiting for a patch?  The only problem I can foresee is very minor:
there is a ref with the same name as a remote; in this case, we'd have
to specify both the remote and the ref.

Thanks.

Ram

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-18 16:58 [ITCH] Specify refspec without remote Ramkumar Ramachandra
@ 2013-03-18 17:08 ` Jeff King
  2013-03-19  9:58   ` Ramkumar Ramachandra
                     ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Jeff King @ 2013-03-18 17:08 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Git List

On Mon, Mar 18, 2013 at 10:28:59PM +0530, Ramkumar Ramachandra wrote:

> This has irritated me for a long time.  I often end up doing:
> 
>     $ git push master:master +pu:pu

Me too.

> Is there a reason for the remote not being optional, or are we just
> waiting for a patch?  The only problem I can foresee is very minor:
> there is a ref with the same name as a remote; in this case, we'd have
> to specify both the remote and the ref.

I think the ambiguity is a little more complex than that, because we
cannot enumerate the universe of all remotes. Keep in mind that we can
take either a configured remote or a URL (or ssh host). So what does:

  git push foo:bar

mean? Is it pushing "refs/heads/foo" to "refs/heads/bar" on "origin"? Or
is it using the default refspecs to push to the "bar" repo on the host
"foo" over ssh?

So you would need some heuristics based on whether something was a valid
refspec, or could be a valid remote name or URL.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-18 17:08 ` Jeff King
@ 2013-03-19  9:58   ` Ramkumar Ramachandra
  2013-03-19 10:02     ` Jeff King
  2013-03-19 11:33   ` Duy Nguyen
  2013-04-09 11:44   ` Ramkumar Ramachandra
  2 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-03-19  9:58 UTC (permalink / raw)
  To: Jeff King; +Cc: Git List

Jeff King wrote:
> On Mon, Mar 18, 2013 at 10:28:59PM +0530, Ramkumar Ramachandra wrote:
>> Is there a reason for the remote not being optional, or are we just
>> waiting for a patch?  The only problem I can foresee is very minor:
>> there is a ref with the same name as a remote; in this case, we'd have
>> to specify both the remote and the ref.
>
> I think the ambiguity is a little more complex than that, because we
> cannot enumerate the universe of all remotes. Keep in mind that we can
> take either a configured remote or a URL (or ssh host). So what does:
>
>   git push foo:bar
>
> mean? Is it pushing "refs/heads/foo" to "refs/heads/bar" on "origin"? Or
> is it using the default refspecs to push to the "bar" repo on the host
> "foo" over ssh?

Wait, why does git-push support pushing to a URL directly?  Shouldn't
the user be required to create a new remote out of the URL and push to
that?  What happens to upstream branches if we directly push to a URL?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19  9:58   ` Ramkumar Ramachandra
@ 2013-03-19 10:02     ` Jeff King
  0 siblings, 0 replies; 68+ messages in thread
From: Jeff King @ 2013-03-19 10:02 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Git List

On Tue, Mar 19, 2013 at 03:28:12PM +0530, Ramkumar Ramachandra wrote:

> > I think the ambiguity is a little more complex than that, because we
> > cannot enumerate the universe of all remotes. Keep in mind that we can
> > take either a configured remote or a URL (or ssh host). So what does:
> >
> >   git push foo:bar
> >
> > mean? Is it pushing "refs/heads/foo" to "refs/heads/bar" on "origin"? Or
> > is it using the default refspecs to push to the "bar" repo on the host
> > "foo" over ssh?
> 
> Wait, why does git-push support pushing to a URL directly?  Shouldn't
> the user be required to create a new remote out of the URL and push to
> that?  What happens to upstream branches if we directly push to a URL?

I do not recall the exact history, but I would not be surprised if git
first learned to push to a URL, and later learned about configured
remotes.  I do not use it that often myself these days, but I find it
occasionally useful for one-off pushes (e.g., pushing a normally private
repo to a temporary publishing point to share with somebody else).

In that case, upstream branches are not touched at all (because we do
not have a configured remote whose fetch refspec we can examine).

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-18 17:08 ` Jeff King
  2013-03-19  9:58   ` Ramkumar Ramachandra
@ 2013-03-19 11:33   ` Duy Nguyen
  2013-03-19 11:53     ` Ramkumar Ramachandra
                       ` (2 more replies)
  2013-04-09 11:44   ` Ramkumar Ramachandra
  2 siblings, 3 replies; 68+ messages in thread
From: Duy Nguyen @ 2013-03-19 11:33 UTC (permalink / raw)
  To: Jeff King; +Cc: Ramkumar Ramachandra, Git List

On Tue, Mar 19, 2013 at 12:08 AM, Jeff King <peff@peff.net> wrote:
>> Is there a reason for the remote not being optional, or are we just
>> waiting for a patch?  The only problem I can foresee is very minor:
>> there is a ref with the same name as a remote; in this case, we'd have
>> to specify both the remote and the ref.
>
> I think the ambiguity is a little more complex than that, because we
> cannot enumerate the universe of all remotes. Keep in mind that we can
> take either a configured remote or a URL (or ssh host). So what does:
>
>   git push foo:bar
>
> mean? Is it pushing "refs/heads/foo" to "refs/heads/bar" on "origin"? Or
> is it using the default refspecs to push to the "bar" repo on the host
> "foo" over ssh?
>
> So you would need some heuristics based on whether something was a valid
> refspec, or could be a valid remote name or URL.

Assume that we agree on what remote is implied, we could simplify
parsing by specifying the remote with "." (or something short and
unambiguous). So the above command would become

git push . foo:bar

Not too much to type
-- 
Duy

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 11:33   ` Duy Nguyen
@ 2013-03-19 11:53     ` Ramkumar Ramachandra
  2013-03-19 12:15       ` Duy Nguyen
  2013-03-19 11:58     ` Holger Hellmuth (IKS)
  2013-03-19 15:43     ` Junio C Hamano
  2 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-03-19 11:53 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Jeff King, Git List

Duy Nguyen wrote:
> On Tue, Mar 19, 2013 at 12:08 AM, Jeff King <peff@peff.net> wrote:
>>> Is there a reason for the remote not being optional, or are we just
>>> waiting for a patch?  The only problem I can foresee is very minor:
>>> there is a ref with the same name as a remote; in this case, we'd have
>>> to specify both the remote and the ref.
>>
>> I think the ambiguity is a little more complex than that, because we
>> cannot enumerate the universe of all remotes. Keep in mind that we can
>> take either a configured remote or a URL (or ssh host). So what does:
>>
>>   git push foo:bar
>>
>> mean? Is it pushing "refs/heads/foo" to "refs/heads/bar" on "origin"? Or
>> is it using the default refspecs to push to the "bar" repo on the host
>> "foo" over ssh?
>>
>> So you would need some heuristics based on whether something was a valid
>> refspec, or could be a valid remote name or URL.
>
> Assume that we agree on what remote is implied, we could simplify
> parsing by specifying the remote with "." (or something short and
> unambiguous). So the above command would become
>
> git push . foo:bar

A URL may be a path to a git repository, and '.' is a valid path.
Currently, 'git push .' seems to push to the current repository (what
does that even mean?).  For something truly unambiguous, we'll have to
use a character that's disallowed in URLs and isn't interpreted by the
shell- I can't seem to think of one.  Otherwise, we'll have to
fallback to using heuristics anyway.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 11:33   ` Duy Nguyen
  2013-03-19 11:53     ` Ramkumar Ramachandra
@ 2013-03-19 11:58     ` Holger Hellmuth (IKS)
  2013-03-19 15:43       ` Junio C Hamano
  2013-03-19 15:43     ` Junio C Hamano
  2 siblings, 1 reply; 68+ messages in thread
From: Holger Hellmuth (IKS) @ 2013-03-19 11:58 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Jeff King, Ramkumar Ramachandra, Git List

Am 19.03.2013 12:33, schrieb Duy Nguyen:
> git push . foo:bar

'.' has more like a "here" semantic, '..' might be a more fitting 
mnemonic here.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 11:53     ` Ramkumar Ramachandra
@ 2013-03-19 12:15       ` Duy Nguyen
  2013-03-19 13:03         ` Holger Hellmuth (IKS)
  0 siblings, 1 reply; 68+ messages in thread
From: Duy Nguyen @ 2013-03-19 12:15 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Jeff King, Git List

On Tue, Mar 19, 2013 at 6:53 PM, Ramkumar Ramachandra
<artagnon@gmail.com> wrote:
>> git push . foo:bar
>
> A URL may be a path to a git repository, and '.' is a valid path.
> Currently, 'git push .' seems to push to the current repository (what
> does that even mean?).  For something truly unambiguous, we'll have to
> use a character that's disallowed in URLs and isn't interpreted by the
> shell- I can't seem to think of one.  Otherwise, we'll have to
> fallback to using heuristics anyway.

Yeah that was a stupid suggestion. There's also "-". Right now git
push accepts it as a remote name, but I think in general "-" alone has
always had a special meaning in UNIX world. We could put a new meaning
to it (literal "-" directory can be specified with "./-"). Not totally
sure if "-" is allowed in refspec though.
-- 
Duy

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 12:15       ` Duy Nguyen
@ 2013-03-19 13:03         ` Holger Hellmuth (IKS)
  0 siblings, 0 replies; 68+ messages in thread
From: Holger Hellmuth (IKS) @ 2013-03-19 13:03 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Ramkumar Ramachandra, Jeff King, Git List

Would it make sense to allow abbreviation similar to how git objects can 
be abbreviated? This would mean origin usually could be spelled just o

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 11:33   ` Duy Nguyen
  2013-03-19 11:53     ` Ramkumar Ramachandra
  2013-03-19 11:58     ` Holger Hellmuth (IKS)
@ 2013-03-19 15:43     ` Junio C Hamano
  2 siblings, 0 replies; 68+ messages in thread
From: Junio C Hamano @ 2013-03-19 15:43 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Jeff King, Ramkumar Ramachandra, Git List

Duy Nguyen <pclouds@gmail.com> writes:

> Assume that we agree on what remote is implied, we could simplify
> parsing by specifying the remote with "." (or something short and
> unambiguous). So the above command would become
>
> git push . foo:bar

That is an established idiom, a handy way to update your own bar
branch to commit pointed by foo branch when and only when the update
fast-forwards.

Please don't.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-19 11:58     ` Holger Hellmuth (IKS)
@ 2013-03-19 15:43       ` Junio C Hamano
  0 siblings, 0 replies; 68+ messages in thread
From: Junio C Hamano @ 2013-03-19 15:43 UTC (permalink / raw)
  To: Holger Hellmuth (IKS)
  Cc: Duy Nguyen, Jeff King, Ramkumar Ramachandra, Git List

"Holger Hellmuth (IKS)" <hellmuth@ira.uka.de> writes:

> Am 19.03.2013 12:33, schrieb Duy Nguyen:
>> git push . foo:bar
>
> '.' has more like a "here" semantic, '..' might be a more fitting
> mnemonic here.

Heh, why not say "origin"?  Or rename it to "o" if you like in your
own repository ;-)

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-03-18 17:08 ` Jeff King
  2013-03-19  9:58   ` Ramkumar Ramachandra
  2013-03-19 11:33   ` Duy Nguyen
@ 2013-04-09 11:44   ` Ramkumar Ramachandra
  2013-04-09 17:31     ` Junio C Hamano
  2 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-09 11:44 UTC (permalink / raw)
  To: Jeff King; +Cc: Git List, Duy Nguyễn

Jeff King wrote:
> So you would need some heuristics based on whether something was a valid
> refspec, or could be a valid remote name or URL.

All refspecs conform to a very simple format:

    quux
    +quux
    quux:baz
    +quux:baz

All of them fail at git_connect().  The third and fourth are
equivalent and take a little longer to fail than the first two,
because ssh tries to resolve the hostname "quux" or "+quux".

Okay, so I was hoping that we could first attempt to push as usual,
and fallback to pushing with the refspec set to argv[0] (if argc is
1); this approach is foolproof and doesn't involve any guessing.
Unfortunately, it's going to be very hard, as the callstack to the
final git_connect() failure looks like:

    git_connect()
    connect_setup()
    get_refs_via_connect()
    transport_push()
    push_with_options()
    do_push()

Now, it's nearly impossible to propagate the error back from
git_connect() to do_push() and switch the refspec.  It's not a simple
callstack either: there are callbacks being setup and called.

There's one small consolation in all this: all refspecs are match
match the !is_url() condition in transport.c:939 get_transport(), and
no preceding conditions.  This means that there is one place to check
if it could possibly be a ref, that's not very deep in the callstack,
and return something to the caller appropriately.  Currently,
get_transport() always returns a valid struct transport with no extra
information; maybe we can change this?

Duy's approach of using a special "-" is trivial to implement, but
doesn't make me happy.  There's no reason I can't have 'git push
master +pu foo:bar'.

Thoughts?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 11:44   ` Ramkumar Ramachandra
@ 2013-04-09 17:31     ` Junio C Hamano
  2013-04-09 17:39       ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-09 17:31 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Jeff King, Git List, Duy Nguyễn

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Jeff King wrote:
>> So you would need some heuristics based on whether something was a valid
>> refspec, or could be a valid remote name or URL.
>
> All refspecs conform to a very simple format:
>
>     quux
>     +quux
>     quux:baz
>     +quux:baz
>
> All of them fail at git_connect().  The third and fourth are
> equivalent and take a little longer to fail than the first two,
> because ssh tries to resolve the hostname "quux" or "+quux".

host:foo/bar (take my "host" branch, push it to their "foo/bar"
branch) could be tricky, no?  It could be trying to go over the ssh
to "host" and access repository at $HOME/foo/bar.  The git_connect()
call may even succeed and you cannot use the failure as a hint to
disambiguate.

Also the request may genuinely be to access foo/bar repository at
the host, but the network layer had trouble connecting temporarily
to the host.  After disambiguating incorrectly to push to the
origin, mapping our host branch to their foo/bar branch, that push
might even succeed.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 17:31     ` Junio C Hamano
@ 2013-04-09 17:39       ` Ramkumar Ramachandra
  2013-04-09 17:58         ` Junio C Hamano
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-09 17:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Git List, Duy Nguyễn

Junio C Hamano wrote:
> host:foo/bar (take my "host" branch, push it to their "foo/bar"
> branch) could be tricky, no?  It could be trying to go over the ssh
> to "host" and access repository at $HOME/foo/bar.  The git_connect()
> call may even succeed and you cannot use the failure as a hint to
> disambiguate.
>
> Also the request may genuinely be to access foo/bar repository at
> the host, but the network layer had trouble connecting temporarily
> to the host.  After disambiguating incorrectly to push to the
> origin, mapping our host branch to their foo/bar branch, that push
> might even succeed.

Oh, ouch.  I didn't think of that.  What do you suggest we do?  Go
with Duy's simple '-' solution, or try some heuristics that may lead
to confusing behavior in edge cases?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 17:39       ` Ramkumar Ramachandra
@ 2013-04-09 17:58         ` Junio C Hamano
  2013-04-09 18:03           ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-09 17:58 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Jeff King, Git List, Duy Nguyễn

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Junio C Hamano wrote:
>> host:foo/bar (take my "host" branch, push it to their "foo/bar"
>> branch) could be tricky, no?  It could be trying to go over the ssh
>> to "host" and access repository at $HOME/foo/bar.  The git_connect()
>> call may even succeed and you cannot use the failure as a hint to
>> disambiguate.
>>
>> Also the request may genuinely be to access foo/bar repository at
>> the host, but the network layer had trouble connecting temporarily
>> to the host.  After disambiguating incorrectly to push to the
>> origin, mapping our host branch to their foo/bar branch, that push
>> might even succeed.
>
> Oh, ouch.  I didn't think of that.  What do you suggest we do?  Go
> with Duy's simple '-' solution, or try some heuristics that may lead
> to confusing behavior in edge cases?

What is bad about saying "push origin ...the rest..."?

It is beyond me why people would want to invent unintuitive line
noise like '-' that others need to read the manual from cover to
cover to find and memorize for something small like this.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 17:58         ` Junio C Hamano
@ 2013-04-09 18:03           ` Ramkumar Ramachandra
  2013-04-09 18:08             ` Ramkumar Ramachandra
  2013-04-09 19:29             ` Junio C Hamano
  0 siblings, 2 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-09 18:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Git List, Duy Nguyễn

Junio C Hamano wrote:
> What is bad about saying "push origin ...the rest..."?

I don't know which remote to push to: all I know is that the remote to
push to is configured somewhere in the web of branch.remote,
remote.pushdefault, and branch.<name>.pushremote, and I don't want to
have to figure that out by hand.  Ever since we got triangular
workflows, I've been missing the implicit beauty when I have to
force-push some refs.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 18:03           ` Ramkumar Ramachandra
@ 2013-04-09 18:08             ` Ramkumar Ramachandra
  2013-04-09 19:29             ` Junio C Hamano
  1 sibling, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-09 18:08 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> [...]

Let's not do anything too complex, and just aim for a more pleasant
experience for the simple case of force-pushing some refs without the
:<dst> counterpart.  Then, all we have to do is verify that what is
specified is not a valid remote, and is not a valid local path (to a
git repository, but we don't need to check that), correct?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 18:03           ` Ramkumar Ramachandra
  2013-04-09 18:08             ` Ramkumar Ramachandra
@ 2013-04-09 19:29             ` Junio C Hamano
  2013-04-09 23:13               ` Jonathan Nieder
  1 sibling, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-09 19:29 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Jeff King, Git List, Duy Nguyễn

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Junio C Hamano wrote:
>> What is bad about saying "push origin ...the rest..."?
>
> I don't know which remote to push to: all I know is that the remote to
> push to is configured somewhere in the web of ...

Ahh, and then the recent triangular stuff makes it even worse.

I can see why we might want some token that says "I am pushing where
I would push normally if this were a 'git push' that does not say
'to where' and 'push what'" to help users.

Some background to explain why I was hesitant to the change.

There must be a reason why the user wants to use a custom set of
refspecs, not the configured ones, for this particular push only.
There must be something special for this particular push that makes
it different from the configured 'git push' default.

I was wondering if it is sensible to assume that the user is likely
to still want to push to the same repository where she usually
pushes to, when she has that special reason.  The underlying
assumption for it to be sensible is that 'to where' (destination
repository) is more sticky than 'push what' (the refspecs).

And I think now I agree that indeed is a sensible assumption.  I am
not sure '-' is a good token for that, but I do not offhand think of
a reason why '-' would be a _bad_ token for that, either.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 19:29             ` Junio C Hamano
@ 2013-04-09 23:13               ` Jonathan Nieder
  2013-04-09 23:14                 ` Jonathan Nieder
                                   ` (3 more replies)
  0 siblings, 4 replies; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-09 23:13 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ramkumar Ramachandra, Jeff King, Git List, Duy Nguyễn

Junio C Hamano wrote:

> And I think now I agree that indeed is a sensible assumption.  I am
> not sure '-' is a good token for that, but I do not offhand think of
> a reason why '-' would be a _bad_ token for that, either.

Random idea: today you can do

	git push origin master; # push branch master to remote origin
	git push --multiple origin korg; # push default refspec to 2 remotes

How about:

	git push origin korg -- master; # push master to 2 remotes
	git push -- master next; # push two refs to default remote
	git push origin -- master; # push master to origin, more explicitly
	git push origin korg --; # push default refspec to 2 remotes, again

	git push host:some/path; # ambiguous argument. Please disambiguate.
	git push host:some/path --; # push default refspec over SSH
	git push -- host:some/path; # push specified refspec to default remote

	git push origin; # is a remote name and not a refname. Good.
	git push master; # is a ref name and not a remote name. Good.

What do you think?
Jonathan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 23:13               ` Jonathan Nieder
@ 2013-04-09 23:14                 ` Jonathan Nieder
  2013-04-10  1:19                 ` Junio C Hamano
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-09 23:14 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ramkumar Ramachandra, Jeff King, Git List, Duy Nguyễn

Jonathan Nieder wrote:

>              today you can do
>
> 	git push origin master; # push branch master to remote origin
> 	git push --multiple origin korg; # push default refspec to 2 remotes

Pretend I said "fetch". ;-)

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 23:13               ` Jonathan Nieder
  2013-04-09 23:14                 ` Jonathan Nieder
@ 2013-04-10  1:19                 ` Junio C Hamano
  2013-04-10  4:13                   ` Jeff King
  2013-04-10  3:50                 ` Jeff King
  2013-04-10 13:19                 ` Ramkumar Ramachandra
  3 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10  1:19 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Ramkumar Ramachandra, Jeff King, Git List, Duy Nguyễn

Jonathan Nieder <jrnieder@gmail.com> writes:

> Junio C Hamano wrote:
>
>> And I think now I agree that indeed is a sensible assumption.  I am
>> not sure '-' is a good token for that, but I do not offhand think of
>> a reason why '-' would be a _bad_ token for that, either.
>
> Random idea: today you can do
>
> 	git push origin master; # push branch master to remote origin
> 	git push --multiple origin korg; # push default refspec to 2 remotes
>
> How about:
>
> 	git push origin korg -- master; # push master to 2 remotes

For this to be any useful, origin and korg has to have the same or
at least similar ref structure, such that pushing my 'master' to
their 'master' makes sense for both sites.  I am not sure how common
it would be.  If people commonly do so, the above looks like a
reasonably useful feature.

> 	git push -- master next; # push two refs to default remote

... or default "push remote" if there is one, I presume?

As you are giving what to push, I am assuming that
branch.$name.remote would not come into play in this case.

> 	git push origin -- master; # push master to origin, more explicitly


> 	git push origin korg --; # push default refspec to 2 remotes, again

As you are _not_ saying what to push, I would expect
branch.$name.remote may have to come into the picture, but because
you are saying where to push, that is not the case.  What does
"default refspec" mean in this context?  What "git push origin" (no refspecs)
would push by default will be sent to "origin", and what "git push
korg" (no refspecs) would push by default will be sent to "korg"?

All of the above sounds a bit too complicated to explain to end
users, but I think they are internally consistent.

> 	git push host:some/path; # ambiguous argument. Please disambiguate.
> 	git push host:some/path --; # push default refspec over SSH
> 	git push -- host:some/path; # push specified refspec to default remote

OK.

> 	git push origin; # is a remote name and not a refname. Good.
> 	git push master; # is a ref name and not a remote name. Good.

Hmm, I dunno.

> What do you think?
> Jonathan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 23:13               ` Jonathan Nieder
  2013-04-09 23:14                 ` Jonathan Nieder
  2013-04-10  1:19                 ` Junio C Hamano
@ 2013-04-10  3:50                 ` Jeff King
  2013-04-10 13:22                   ` Ramkumar Ramachandra
  2013-04-10 16:38                   ` Junio C Hamano
  2013-04-10 13:19                 ` Ramkumar Ramachandra
  3 siblings, 2 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10  3:50 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Junio C Hamano, Ramkumar Ramachandra, Git List, Duy Nguyễn

On Tue, Apr 09, 2013 at 04:13:32PM -0700, Jonathan Nieder wrote:

> Random idea: today you can do
> 
> 	git push origin master; # push branch master to remote origin
> 	git push --multiple origin korg; # push default refspec to 2 remotes

Can we do "git push --multiple" today? My git does not seem to know
about that (and I don't remember any patches in the area). Am I missing
something?

> How about:
> 
> 	git push origin korg -- master; # push master to 2 remotes
> 	git push -- master next; # push two refs to default remote
> 	git push origin -- master; # push master to origin, more explicitly
> 	git push origin korg --; # push default refspec to 2 remotes, again

I like that _way_ better than the "-" proposal. Rather than introducing
a magic token for "the default ref", it fixes the actual syntax problem
(that we have two lists of arguments to the command, and we do not know
where one begins and the other ends). And it does it the same way as
other parts of git.

> 	git push host:some/path; # ambiguous argument. Please disambiguate.

This is a regression.  I thought the point of this exercise was to leave
that working. We could just as easily switch to:

  git push --remote=host:some/path

if we are willing to break the existing syntax. Though your proposal
does have the benefit of breaking only one particular syntax which is
(I'm guessing) less frequently used. But we'd still need the usual
deprecation period, I think.

> 	git push host:some/path --; # push default refspec over SSH
> 	git push -- host:some/path; # push specified refspec to default remote

I like this.

> 	git push origin; # is a remote name and not a refname. Good.
> 	git push master; # is a ref name and not a remote name. Good.

And this is sensible, too.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10  1:19                 ` Junio C Hamano
@ 2013-04-10  4:13                   ` Jeff King
  2013-04-10 16:37                     ` Junio C Hamano
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10  4:13 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

On Tue, Apr 09, 2013 at 06:19:01PM -0700, Junio C Hamano wrote:

> > 	git push -- master next; # push two refs to default remote
> 
> ... or default "push remote" if there is one, I presume?
> 
> As you are giving what to push, I am assuming that
> branch.$name.remote would not come into play in this case.

I would have assumed the opposite. We feed "push" two items: where to
push (dst), and what refspecs to push (refs). We may or may not have
each item. Here's what's possible today:

  dst=present, refs=present: (case 1)
    push to $dst, using $refs
  dst=present, refs=missing: (case 2)
    push to $dst, using refspecs from remote.$dst.push or push.default
  dst=missing, refs=missing: (case 3)
    push to remote.pushDefault, branch.*.remote, or "origin"; use
    refspecs from remote.$x.push or push.default, where $x is the remote
    we decide to use.

The missing case 4 is obviously:

  dst=missing, refs=present

And I would expect it to select the remote in the same way as case 3. In
other words, the "where" and the "what" are orthogonal, and the presence
or absence of one does not affect how the other is calculated (with the
exception that _if_ we have a configured remote, whether it was
specified by the user or calculated, we may use its config if no
refspecs are specified).

Do you want to explain your thinking? I'm guessing it has to do with the
fact that choosing branch.*.remote is about trying to push to the
configured upstream (even though we traditionally do _not_ take into
account branch.*.merge when doing so).

> > 	git push origin korg --; # push default refspec to 2 remotes, again
> 
> As you are _not_ saying what to push, I would expect
> branch.$name.remote may have to come into the picture, but because
> you are saying where to push, that is not the case.  What does
> "default refspec" mean in this context?  What "git push origin" (no refspecs)
> would push by default will be sent to "origin", and what "git push
> korg" (no refspecs) would push by default will be sent to "korg"?

Yeah, I would expect that each uses its own default refspec. That is,
the above command is exactly equivalent to:

  git push origin && git push korg

(possibly without the short-circuit behavior of "&&", but definitely
taking both into account in the exit code).

I'd also be fine if we punted on the multiple remotes thing for now. You
can accomplish it easily in the shell, as I showed above (and it is not
any less efficient, since we have to make two network connections
anyway). Jonathan's syntax allows for 0 to N remotes alongside 0 to N
refspecs. The interesting new case (to me, anyway) is the 0 remotes, >0
refspecs case. But we don't have to handle >1 remotes now; once we have
the syntax in place, we can make it work later when we've decided on the
semantics.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-09 23:13               ` Jonathan Nieder
                                   ` (2 preceding siblings ...)
  2013-04-10  3:50                 ` Jeff King
@ 2013-04-10 13:19                 ` Ramkumar Ramachandra
  3 siblings, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 13:19 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, Jeff King, Git List, Duy Nguyễn

Jonathan Nieder wrote:
>         git push origin korg -- master; # push master to 2 remotes
>         git push -- master next; # push two refs to default remote
>         git push origin -- master; # push master to origin, more explicitly
>         git push origin korg --; # push default refspec to 2 remotes, again

I definitely like the idea of using -- to disambiguate, as it is
consistent with existing git commands (that are internally using the
rev-list machinery).  However, I disagree with the idea of being able
to specify multiple remotes: what does 'git push A B -- master +next'
mean?  Do I know that master and next are present in both A and B?  Do
I know for certain that a force-push to next won't wipe any data on
either A or B accidentally?  As the number of remotes and refs
increase, the amount of information that the user must know about each
of the remotes is simply huge.  Therefore, I think it is unnecessarily
confusing and unnecessary.  Moreover, it can easily be achieved in
shell, and there is no advantage to supporting it in push unless we're
doing something like a parallel push.

>        git push host:some/path; # ambiguous argument. Please disambiguate.

Regression.  It should just treat host:some/path as a destination, not a ref.

>        git push origin; # is a remote name and not a refname. Good.
>        git push master; # is a ref name and not a remote name. Good.

This is what I finally want.  With your -- to disambiguate, the logic
for doing this has been simplified greatly.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10  3:50                 ` Jeff King
@ 2013-04-10 13:22                   ` Ramkumar Ramachandra
  2013-04-10 15:56                     ` Jeff King
  2013-04-10 16:38                   ` Junio C Hamano
  1 sibling, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 13:22 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
>   git push --remote=host:some/path
>
> if we are willing to break the existing syntax. Though your proposal
> does have the benefit of breaking only one particular syntax which is
> (I'm guessing) less frequently used. But we'd still need the usual
> deprecation period, I think.

Why?  'git push host:some/path' should treat host:some/path as a
destination and not a refspec.  If the user meant refspec, she should
do 'git push -- host:some/path' instead.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 13:22                   ` Ramkumar Ramachandra
@ 2013-04-10 15:56                     ` Jeff King
  0 siblings, 0 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 15:56 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

On Wed, Apr 10, 2013 at 06:52:51PM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> >   git push --remote=host:some/path
> >
> > if we are willing to break the existing syntax. Though your proposal
> > does have the benefit of breaking only one particular syntax which is
> > (I'm guessing) less frequently used. But we'd still need the usual
> > deprecation period, I think.
> 
> Why?  'git push host:some/path' should treat host:some/path as a
> destination and not a refspec.  If the user meant refspec, she should
> do 'git push -- host:some/path' instead.

You snipped the part of Jonathan's message I quoted; I was responding
specifically to making "git push host:some/path" an error.  I do not
think that is a good idea, and doing so would require a deprecation
period.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10  4:13                   ` Jeff King
@ 2013-04-10 16:37                     ` Junio C Hamano
  2013-04-10 17:27                       ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10 16:37 UTC (permalink / raw)
  To: Jeff King
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

Jeff King <peff@peff.net> writes:

> On Tue, Apr 09, 2013 at 06:19:01PM -0700, Junio C Hamano wrote:
>
>> > 	git push -- master next; # push two refs to default remote
>> 
>> ... or default "push remote" if there is one, I presume?
>> 
>> As you are giving what to push, I am assuming that
>> branch.$name.remote would not come into play in this case.
>
>...
> The missing case 4 is obviously:
>
>   dst=missing, refs=present
> ...
> Do you want to explain your thinking? I'm guessing it has to do with the
> fact that choosing branch.*.remote is about trying to push to the
> configured upstream (even though we traditionally do _not_ take into
> account branch.*.merge when doing so).

With the branch.$name.remote, the user tells us "When I am on this
branch, I want to talk to this remote".  When you did

	git push -- master next ;# case #4

on branch maint, branch.maint.remote should not come into play.

Would we want to push our 'master' to branch.master.remote in a way 

	git checkout master && git push

would do, while at the same time because we were told to do the same
for 'next', we do the same as

	git checkout next && git push

would do?  That would work if you give just branch names, but that
is not a general enough definition to cover your case #4, e.g.

	git push -- v1.2.3 master:refs/remotes/mothership/master

If we define case #4 to push to the remote.pushdefault (falling back
to remote.default), this case would do what can simply be expected;
if the earlier cases also push to that same place, ignoring
branch.$name.remote for master and next, that would be consistent.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10  3:50                 ` Jeff King
  2013-04-10 13:22                   ` Ramkumar Ramachandra
@ 2013-04-10 16:38                   ` Junio C Hamano
  2013-04-10 17:29                     ` Jeff King
  1 sibling, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10 16:38 UTC (permalink / raw)
  To: Jeff King
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

Jeff King <peff@peff.net> writes:

> On Tue, Apr 09, 2013 at 04:13:32PM -0700, Jonathan Nieder wrote:
>
>> Random idea: today you can do
>> 
>> 	git push origin master; # push branch master to remote origin
>> 	git push --multiple origin korg; # push default refspec to 2 remotes
>
> Can we do "git push --multiple" today?

You can have multiple destination URLs for a single remote nickname.
Wouldn't that be sufficient for regular publishing purposes?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 16:37                     ` Junio C Hamano
@ 2013-04-10 17:27                       ` Jeff King
  2013-04-10 18:54                         ` Junio C Hamano
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 17:27 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

On Wed, Apr 10, 2013 at 09:37:01AM -0700, Junio C Hamano wrote:

> > The missing case 4 is obviously:
> >
> >   dst=missing, refs=present
> > ...
> > Do you want to explain your thinking? I'm guessing it has to do with the
> > fact that choosing branch.*.remote is about trying to push to the
> > configured upstream (even though we traditionally do _not_ take into
> > account branch.*.merge when doing so).
> 
> With the branch.$name.remote, the user tells us "When I am on this
> branch, I want to talk to this remote".  When you did
> 
> 	git push -- master next ;# case #4
> 
> on branch maint, branch.maint.remote should not come into play.

I understand that's your position, but I don't understand _why_.

If branch.$name.remote is "when I am on this branch, I want to talk to
this remote", that rule is not be impacted by the presence of refspecs
at all.

If it meant "when I am on this branch, and I do not specify any
refspecs, then I would by default want to push this branch to that
remote", then your proposed behavior would make more sense. And if you
are using push.default=upstream, that is what happens.

But historically the default push has been "matching". So in your other
examples:

> Would we want to push our 'master' to branch.master.remote in a way 
> 
> 	git checkout master && git push
> 
> would do, while at the same time because we were told to do the same
> for 'next', we do the same as
> 
> 	git checkout next && git push

These do not have anything to do with pushing the checked-out branch in
particular. The first one may very well be pushing "next" to the remote
specified by branch.master.remote.

So I would argue that one of these two makes sense:

  1. branch.*.remote means "use this as the default remote on this
     branch, no matte which refs we are pushing"

  2. branch.*.remote is not respected at all for remote selection with
     "matching". It is used only when combined with branch.*.merge,
     which means that only the "upstream" mode would use it.

I advocated (1) in my previous message, but I would also be OK with (2),
even though it is a change from the current behavior. But what you are
suggesting seems like an inconsistent mix of the two.

> would do?  That would work if you give just branch names, but that
> is not a general enough definition to cover your case #4, e.g.
> 
> 	git push -- v1.2.3 master:refs/remotes/mothership/master
> 
> If we define case #4 to push to the remote.pushdefault (falling back
> to remote.default), this case would do what can simply be expected;
> if the earlier cases also push to that same place, ignoring
> branch.$name.remote for master and next, that would be consistent.

So I think what you are getting at is that branch.*.remote is about
saying "when we push X, it goes to remote Y". And with v1.2.3, we
obviously cannot have such a hint, because it is not a branch. But my
point is that is _not_ how it works today.  So if you want consistency,
we would also need to adjust how branch.*.remote interacts with
"matching".

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 16:38                   ` Junio C Hamano
@ 2013-04-10 17:29                     ` Jeff King
  0 siblings, 0 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 17:29 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

On Wed, Apr 10, 2013 at 09:38:26AM -0700, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > On Tue, Apr 09, 2013 at 04:13:32PM -0700, Jonathan Nieder wrote:
> >
> >> Random idea: today you can do
> >> 
> >> 	git push origin master; # push branch master to remote origin
> >> 	git push --multiple origin korg; # push default refspec to 2 remotes
> >
> > Can we do "git push --multiple" today?
> 
> You can have multiple destination URLs for a single remote nickname.
> Wouldn't that be sufficient for regular publishing purposes?

Yes, though that is different than specifying two different remotes,
which may have their own sets of default refspecs (i.e., what Jonathan
wrote above). If they are two URLs of the same configured remote, there
is no question that they should respect the same refspecs.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 17:27                       ` Jeff King
@ 2013-04-10 18:54                         ` Junio C Hamano
  2013-04-10 18:59                           ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10 18:54 UTC (permalink / raw)
  To: Jeff King
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

Jeff King <peff@peff.net> writes:

>> With the branch.$name.remote, the user tells us "When I am on this
>> branch, I want to talk to this remote".  When you did
>> 
>> 	git push -- master next ;# case #4
>> 
>> on branch maint, branch.maint.remote should not come into play.
>
> I understand that's your position, but I don't understand _why_.
>
> If branch.$name.remote is "when I am on this branch, I want to talk to
> this remote", that rule is not be impacted by the presence of refspecs
> at all.

So running the above while on 'maint' will send master and next to
the remote your "git push" would send to when run without any
refspecs?

That is internally consistent and understandable, and I have no
objection to it.  Certainly much better than basing the decision on
branch.{master,next}.remote as I thought you were suggesting to do.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 18:54                         ` Junio C Hamano
@ 2013-04-10 18:59                           ` Jeff King
  2013-04-10 19:31                             ` Ramkumar Ramachandra
  2013-04-12 22:14                             ` Junio C Hamano
  0 siblings, 2 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 18:59 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

On Wed, Apr 10, 2013 at 11:54:34AM -0700, Junio C Hamano wrote:

> > If branch.$name.remote is "when I am on this branch, I want to talk to
> > this remote", that rule is not be impacted by the presence of refspecs
> > at all.
> 
> So running the above while on 'maint' will send master and next to
> the remote your "git push" would send to when run without any
> refspecs?

Exactly. The remote selection is orthogonal to the refspecs provided,
and only cares about which branch you are on.

Which is still kind of weird, because why should the branch you are on
affect the default push location? But that is how default "matching" has
always behaved, and we would remain consistent with that.

> That is internally consistent and understandable, and I have no
> objection to it.  Certainly much better than basing the decision on
> branch.{master,next}.remote as I thought you were suggesting to do.

No, I am not suggesting that. I can see how such a command might be
useful (i.e. "push master to where it goes, next to where it goes",
where "goes" is defined by the upstream config). But that is not
remotely close to how "git push" works now, and would be inconsistent
with the other modes (e.g., matching, explicit refspecs, pushing
non-branches, etc).

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 18:59                           ` Jeff King
@ 2013-04-10 19:31                             ` Ramkumar Ramachandra
  2013-04-10 19:33                               ` Ramkumar Ramachandra
                                                 ` (2 more replies)
  2013-04-12 22:14                             ` Junio C Hamano
  1 sibling, 3 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 19:31 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> On Wed, Apr 10, 2013 at 11:54:34AM -0700, Junio C Hamano wrote:
>> > If branch.$name.remote is "when I am on this branch, I want to talk to
>> > this remote", that rule is not be impacted by the presence of refspecs
>> > at all.
>>
>> So running the above while on 'maint' will send master and next to
>> the remote your "git push" would send to when run without any
>> refspecs?
>
> Exactly. The remote selection is orthogonal to the refspecs provided,
> and only cares about which branch you are on.
>
> Which is still kind of weird, because why should the branch you are on
> affect the default push location? But that is how default "matching" has
> always behaved, and we would remain consistent with that.

git push -- master next; pushes to my current branch's
branch.<name>.pushremote?  Isn't that a disaster?

>> That is internally consistent and understandable, and I have no
>> objection to it.  Certainly much better than basing the decision on
>> branch.{master,next}.remote as I thought you were suggesting to do.
>
> No, I am not suggesting that. I can see how such a command might be
> useful (i.e. "push master to where it goes, next to where it goes",
> where "goes" is defined by the upstream config). But that is not
> remotely close to how "git push" works now, and would be inconsistent
> with the other modes (e.g., matching, explicit refspecs, pushing
> non-branches, etc).

Otherwise, I think we're consistent.  git push master; pushes the
refspec master (with no explicit :<dst> counterpart) to the "default
place to push to" (either depending on which branch I am, or global).
I think Junio was mixing up refspecs with refs (branches, and hence
branch configuration) earlier.  git push origin; pushes to "default
refspecs" on the remote origin.  By extension, git push; should push
"default respecs" to the "default place to push to".  The "default
refspecs" in this context is determined by push.default, which is the
problem.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:31                             ` Ramkumar Ramachandra
@ 2013-04-10 19:33                               ` Ramkumar Ramachandra
  2013-04-10 19:52                               ` Jeff King
  2013-04-10 19:53                               ` Ramkumar Ramachandra
  2 siblings, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 19:33 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> Otherwise, I think we're consistent.  git push master; pushes the
> refspec master (with no explicit :<dst> counterpart) to the "default
> place to push to" (either depending on which branch I am, or global).
> I think Junio was mixing up refspecs with refs (branches, and hence
> branch configuration) earlier.  git push origin; pushes to "default
> refspecs" on the remote origin.  By extension, git push; should push
> "default respecs" to the "default place to push to".  The "default
> refspecs" in this context is determined by push.default, which is the
> problem.

Major thinko here.  The problem is git push master; choosing the
"default place to push to" depending on what branch I'm in.  A plain
git push; is just fine.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:31                             ` Ramkumar Ramachandra
  2013-04-10 19:33                               ` Ramkumar Ramachandra
@ 2013-04-10 19:52                               ` Jeff King
  2013-04-10 20:05                                 ` Ramkumar Ramachandra
  2013-04-10 20:21                                 ` Junio C Hamano
  2013-04-10 19:53                               ` Ramkumar Ramachandra
  2 siblings, 2 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 19:52 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 01:01:33AM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> > On Wed, Apr 10, 2013 at 11:54:34AM -0700, Junio C Hamano wrote:
> >> > If branch.$name.remote is "when I am on this branch, I want to talk to
> >> > this remote", that rule is not be impacted by the presence of refspecs
> >> > at all.
> >>
> >> So running the above while on 'maint' will send master and next to
> >> the remote your "git push" would send to when run without any
> >> refspecs?
> >
> > Exactly. The remote selection is orthogonal to the refspecs provided,
> > and only cares about which branch you are on.
> >
> > Which is still kind of weird, because why should the branch you are on
> > affect the default push location? But that is how default "matching" has
> > always behaved, and we would remain consistent with that.
> 
> git push -- master next; pushes to my current branch's
> branch.<name>.pushremote?  Isn't that a disaster?

Maybe. But no more so than the current:

  git push

which may also push master and next to the same remote. As I said in an
earlier message, I would be OK with allowing both or neither, but
allowing one but not the other is even more confusing.

If we changed push.default=matching to ignore branch.*.remote, then that
would be consistent, and would probably be safer over all. It is a
regression, but I doubt that anybody was using branch.*.remote for this;
it really only makes sense with the "upstream" mode.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:31                             ` Ramkumar Ramachandra
  2013-04-10 19:33                               ` Ramkumar Ramachandra
  2013-04-10 19:52                               ` Jeff King
@ 2013-04-10 19:53                               ` Ramkumar Ramachandra
  2013-04-10 20:05                                 ` Jonathan Nieder
                                                   ` (2 more replies)
  2 siblings, 3 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 19:53 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> git push -- master next; pushes to my current branch's
> branch.<name>.pushremote?  Isn't that a disaster?

Actually, branch.<name>.pushremote already breaks the current design
in a way, as Junio pointed out in a different email: a push.default
set to anything except "current" is already nonsensical.  Why should
"matching" branches be pushed to the remote that my current branch
specifies?  That might well have their own branch.<name>.pushremote
configured, which should be respected.

We should fix this now.  I think the fault lies in the rather old
design of push.default.  Do you have any suggestions as what would
make sense here?  Ultimately, I think a git push; needs to pick
remotes for each refspec separately.  The orthogonal design is
definitely not right in my opinion.

As the author of branch.<name>.pushremote, I apologize for not having
caught this earlier.  I've been using push.default = current for a
long time, and don't often think about the other settings.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:53                               ` Ramkumar Ramachandra
@ 2013-04-10 20:05                                 ` Jonathan Nieder
  2013-04-10 20:11                                   ` Jeff King
  2013-04-10 20:05                                 ` Jeff King
  2013-04-10 20:27                                 ` Junio C Hamano
  2 siblings, 1 reply; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-10 20:05 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jeff King, Junio C Hamano, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> Ramkumar Ramachandra wrote:

>> git push -- master next; pushes to my current branch's
>> branch.<name>.pushremote?  Isn't that a disaster?
>
> Actually, branch.<name>.pushremote already breaks the current design
> in a way

I don't see a big problem here, actually.  What's so wrong with
branch.<name>.remote affecting what "git push" does?  If
branch.crazy-feature.remote is my-personal-remote and I run

	git push

and "[push] default = upstream", then it is obvious what the user
wanted to happen.  But what about when "[push] default = matching"?
Which of the following behaviors is correct?

 a) Error: you didn't tell me which remote to push to.
 b) Just behave like "git push my-personal-remote :".
 c) Ignore which branch is the current branch and behave like
    "git push origin :".

How about when "[push] default = current"?

Except that people might have scripts or habits tied to the current
behavior, any of (a), (b), and (c) sounds fine to me.  (b) is the
obvious choice for historical reasons.

Now if I rely on the proposed DWIM and run

	git push master

then the corresponding choices are:

 a) Error: you didn't tell me which remote to push to.
 b) Just behave like "git push my-personal-remote master".
 c) Behave like "git push origin master".
 
(b) is not a good choice there, but (a) and (c) look equally fine.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:52                               ` Jeff King
@ 2013-04-10 20:05                                 ` Ramkumar Ramachandra
  2013-04-10 20:21                                   ` Jeff King
  2013-04-10 20:21                                 ` Junio C Hamano
  1 sibling, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 20:05 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> Maybe. But no more so than the current:
>
>   git push
>
> which may also push master and next to the same remote.

I would argue that this was not really a problem in practice, until I
introduced branch.<name>.pushremote.

Let us imagine that I was working on artagnon/git.git (remote: ram), a
fork of git/git.git (remote: origin) earlier.  My fork contains the
link and implicit-push branches in addition to the master, next and pu
branches, which are present on both.  When I push from my
implicit-push branch with push.default = matching, I'm updating all
the matching refs on the remote ram (since branch.implicit-push.remote
is set to ram), which is fine.  Now, I git push while on branch
master.  My push is simply rejected, as I don't have write access to
the remote origin.

This is designed exactly for the read-only upstream, read-write fork
scenario.  If I had write access to upstream (where we're essentially
regression to a centralized model), we'd have some major confusion.

> As I said in an
> earlier message, I would be OK with allowing both or neither, but
> allowing one but not the other is even more confusing.

What is the point of allowing something internally consistent, but
nonsensical?  You should complain.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:53                               ` Ramkumar Ramachandra
  2013-04-10 20:05                                 ` Jonathan Nieder
@ 2013-04-10 20:05                                 ` Jeff King
  2013-04-10 20:19                                   ` Ramkumar Ramachandra
  2013-04-10 20:27                                 ` Junio C Hamano
  2 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 20:05 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 01:23:57AM +0530, Ramkumar Ramachandra wrote:

> Ramkumar Ramachandra wrote:
> > git push -- master next; pushes to my current branch's
> > branch.<name>.pushremote?  Isn't that a disaster?
> 
> Actually, branch.<name>.pushremote already breaks the current design
> in a way, as Junio pointed out in a different email: a push.default
> set to anything except "current" is already nonsensical.  Why should
> "matching" branches be pushed to the remote that my current branch
> specifies?  That might well have their own branch.<name>.pushremote
> configured, which should be respected.

I'm not sure that it should be respected. "master" is short for
"refs/heads/master:refs/heads/master", and does not mean "push master to
where I have it configured to go" at all.  That may be what the user
means, but changing how "git push" works is going to create
inconsistency with other cases.

> We should fix this now.  I think the fault lies in the rather old
> design of push.default.  Do you have any suggestions as what would
> make sense here?  Ultimately, I think a git push; needs to pick
> remotes for each refspec separately.  The orthogonal design is
> definitely not right in my opinion.

Right, the example above might include multiple remotes if pushremote is
respected. Or it might not come up with an answer at all for a tag.
If you do:

  git push -- v1.2.3 master

where does v1.2.3 go? To remote.pushdefault? That seems simple and
consistent, as there is no ref-specific pushremote defined. But I'd
guess that the user probably _wanted_ it to go to
branch.master.pushremote.

> As the author of branch.<name>.pushremote, I apologize for not having
> caught this earlier.  I've been using push.default = current for a
> long time, and don't often think about the other settings.

I don't think pushremote introduced the problem. It is much older than
that, and dates back to respecting branch.*.remote at all for pushes,
even though push.default=matching (and before we had push.default, it
was always matching) does not have anything to do with the current
branch.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:05                                 ` Jonathan Nieder
@ 2013-04-10 20:11                                   ` Jeff King
  2013-04-10 21:23                                     ` Jonathan Nieder
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 20:11 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Ramkumar Ramachandra, Junio C Hamano, Git List, Duy Nguyễn

On Wed, Apr 10, 2013 at 01:05:12PM -0700, Jonathan Nieder wrote:

> I don't see a big problem here, actually.  What's so wrong with
> branch.<name>.remote affecting what "git push" does?  If
> branch.crazy-feature.remote is my-personal-remote and I run
> 
> 	git push
> 
> and "[push] default = upstream", then it is obvious what the user
> wanted to happen.  But what about when "[push] default = matching"?
> Which of the following behaviors is correct?
> 
>  a) Error: you didn't tell me which remote to push to.
>  b) Just behave like "git push my-personal-remote :".
>  c) Ignore which branch is the current branch and behave like
>     "git push origin :".
> 
> How about when "[push] default = current"?
> 
> Except that people might have scripts or habits tied to the current
> behavior, any of (a), (b), and (c) sounds fine to me.  (b) is the
> obvious choice for historical reasons.

I think (b) could be quite surprising to a user. I suspect it hasn't
come up because people just don't work with a lot of different remotes
in practice.

> Now if I rely on the proposed DWIM and run
> 
> 	git push master
> 
> then the corresponding choices are:
> 
>  a) Error: you didn't tell me which remote to push to.
>  b) Just behave like "git push my-personal-remote master".
>  c) Behave like "git push origin master".
>  
> (b) is not a good choice there, but (a) and (c) look equally fine.

My complaint with anything but (b) is that you can't use a relatively
simple rule ("if you do not specify a remote, we fallback to defaults,
in this order"). Now the rule is different depending on what is in the
refspecs. If I say "git push HEAD", where should it go? Does it respect
branch.*.remote or not?

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:05                                 ` Jeff King
@ 2013-04-10 20:19                                   ` Ramkumar Ramachandra
  2013-04-10 20:24                                     ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 20:19 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> On Thu, Apr 11, 2013 at 01:23:57AM +0530, Ramkumar Ramachandra wrote:
>
>> Ramkumar Ramachandra wrote:
>> > git push -- master next; pushes to my current branch's
>> > branch.<name>.pushremote?  Isn't that a disaster?
>>
>> Actually, branch.<name>.pushremote already breaks the current design
>> in a way, as Junio pointed out in a different email: a push.default
>> set to anything except "current" is already nonsensical.  Why should
>> "matching" branches be pushed to the remote that my current branch
>> specifies?  That might well have their own branch.<name>.pushremote
>> configured, which should be respected.
>
> I'm not sure that it should be respected. "master" is short for
> "refs/heads/master:refs/heads/master", and does not mean "push master to
> where I have it configured to go" at all.  That may be what the user
> means, but changing how "git push" works is going to create
> inconsistency with other cases.

Yes, I know "master" refers to the refspec in the above, not the ref
(ie. branch).  Hence branch configuration should have nothing to do
with this.  That's just the way things currently are: doesn't mean
that it's perfect; and I'm just throwing ideas around.

>> We should fix this now.  I think the fault lies in the rather old
>> design of push.default.  Do you have any suggestions as what would
>> make sense here?  Ultimately, I think a git push; needs to pick
>> remotes for each refspec separately.  The orthogonal design is
>> definitely not right in my opinion.
>
> Right, the example above might include multiple remotes if pushremote is
> respected. Or it might not come up with an answer at all for a tag.
> If you do:
>
>   git push -- v1.2.3 master
>
> where does v1.2.3 go? To remote.pushdefault? That seems simple and
> consistent, as there is no ref-specific pushremote defined.

remote.pushdefault indeed.

> But I'd
> guess that the user probably _wanted_ it to go to
> branch.master.pushremote.

Huh, why?  Simply because he specified master alongside it?  How can
we infer what you said in a consistent system?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:05                                 ` Ramkumar Ramachandra
@ 2013-04-10 20:21                                   ` Jeff King
  2013-04-10 20:41                                     ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 20:21 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 01:35:34AM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> > Maybe. But no more so than the current:
> >
> >   git push
> >
> > which may also push master and next to the same remote.
> 
> I would argue that this was not really a problem in practice, until I
> introduced branch.<name>.pushremote.
> 
> Let us imagine that I was working on artagnon/git.git (remote: ram), a
> fork of git/git.git (remote: origin) earlier.  My fork contains the
> link and implicit-push branches in addition to the master, next and pu
> branches, which are present on both.  When I push from my
> implicit-push branch with push.default = matching, I'm updating all
> the matching refs on the remote ram (since branch.implicit-push.remote
> is set to ram), which is fine.  Now, I git push while on branch
> master.  My push is simply rejected, as I don't have write access to
> the remote origin.
> 
> This is designed exactly for the read-only upstream, read-write fork
> scenario.  If I had write access to upstream (where we're essentially
> regression to a centralized model), we'd have some major confusion.

I don't see how pushremote changes that. It was already a problem with
branch.*.remote, no?

I have a similar remote setup in my git.git repository. But all of my
branch.*.remote variables point to origin, because my branches are based
off of Junio's master. A matching push goes to the wrong place (and I
have screwed it up many times; it is nice that I do not have write
access to Junio's repository). The is broken without having pushremote
at all (and the proper fix is your remote.pushdefault).

> > As I said in an
> > earlier message, I would be OK with allowing both or neither, but
> > allowing one but not the other is even more confusing.
> 
> What is the point of allowing something internally consistent, but
> nonsensical?  You should complain.

If I were designing it today, I definitely think complaining is the
right thing to do. My only hesitation is the backwards compatibility.

If we are not going to break the existing behavior, I think it can be
argued that consistency and simplicity of the rules is important, so the
user can predict what will happen. But the more we discuss, the more I
think we should simply change the current behavior (to stop respecting
branch.* config with "matching"), which just seems wrong to me. Then we
can be simple and consistent, and do what the user probably intended.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:52                               ` Jeff King
  2013-04-10 20:05                                 ` Ramkumar Ramachandra
@ 2013-04-10 20:21                                 ` Junio C Hamano
  1 sibling, 0 replies; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10 20:21 UTC (permalink / raw)
  To: Jeff King
  Cc: Ramkumar Ramachandra, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King <peff@peff.net> writes:

> If we changed push.default=matching to ignore branch.*.remote, then that
> would be consistent, and would probably be safer over all. It is a
> regression, but I doubt that anybody was using branch.*.remote for this;
> it really only makes sense with the "upstream" mode.

True.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:19                                   ` Ramkumar Ramachandra
@ 2013-04-10 20:24                                     ` Jeff King
  2013-04-10 20:55                                       ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 20:24 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 01:49:54AM +0530, Ramkumar Ramachandra wrote:

> > Right, the example above might include multiple remotes if pushremote is
> > respected. Or it might not come up with an answer at all for a tag.
> > If you do:
> >
> >   git push -- v1.2.3 master
> >
> > where does v1.2.3 go? To remote.pushdefault? That seems simple and
> > consistent, as there is no ref-specific pushremote defined.
> 
> remote.pushdefault indeed.
> 
> > But I'd
> > guess that the user probably _wanted_ it to go to
> > branch.master.pushremote.
> 
> Huh, why?  Simply because he specified master alongside it?  How can
> we infer what you said in a consistent system?

That's kind of my point. Why would they put two refs together in a
single push command? Did they mean "I am pushing up master, and since I
just tagged it, send the tag along, too"? Or did they really mean to
push them to two different places? If so, why not just run two separate
push commands?

I am not saying git should guess that the user wanted the tag to along
with master. I am saying that the set of rules to come to that
conclusion is going to be too baroque for the user to understand, and
too often wrong in other cases, and that we should not go there.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 19:53                               ` Ramkumar Ramachandra
  2013-04-10 20:05                                 ` Jonathan Nieder
  2013-04-10 20:05                                 ` Jeff King
@ 2013-04-10 20:27                                 ` Junio C Hamano
  2013-04-10 21:15                                   ` Ramkumar Ramachandra
  2 siblings, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-10 20:27 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jeff King, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> As the author of branch.<name>.pushremote, I apologize for not having
> caught this earlier.  I've been using push.default = current for a
> long time, and don't often think about the other settings.

Possibly, but I do not know it is such a big issue.

On the other hand, a good thing is that the remote.pushdefault makes
perfect sense whether you use the upstream mode or the matching
mode.  I vaguely recall that I kept telling you that the overall
default should be there and per-branch stuff can come later if/as
needed, to which you resisted for a couple of rounds of reviews and
I couldn't quite figure out where the resistance was coming from.
Come to think of it, perhaps that might be rooted in the same
reason of not thinking about users of "matching" mode.  I dunno, and
I do not think it matters.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:21                                   ` Jeff King
@ 2013-04-10 20:41                                     ` Ramkumar Ramachandra
  2013-04-10 21:02                                       ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 20:41 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> On Thu, Apr 11, 2013 at 01:35:34AM +0530, Ramkumar Ramachandra wrote:
>
>> Jeff King wrote:
>> > Maybe. But no more so than the current:
>> >
>> >   git push
>> >
>> > which may also push master and next to the same remote.
>>
>> I would argue that this was not really a problem in practice, until I
>> introduced branch.<name>.pushremote.
>>
>> Let us imagine that I was working on artagnon/git.git (remote: ram), a
>> fork of git/git.git (remote: origin) earlier.  My fork contains the
>> link and implicit-push branches in addition to the master, next and pu
>> branches, which are present on both.  When I push from my
>> implicit-push branch with push.default = matching, I'm updating all
>> the matching refs on the remote ram (since branch.implicit-push.remote
>> is set to ram), which is fine.  Now, I git push while on branch
>> master.  My push is simply rejected, as I don't have write access to
>> the remote origin.
>>
>> This is designed exactly for the read-only upstream, read-write fork
>> scenario.  If I had write access to upstream (where we're essentially
>> regression to a centralized model), we'd have some major confusion.
>
> I don't see how pushremote changes that. It was already a problem with
> branch.*.remote, no?

Technically, it changes nothing.  pushremote is only an enabler for
more complex scenarios where git push; breaking user expectations is
magnified.

According to me, what branch.<name>.pushremote suddenly starts
supporting (apart from the use I intended for it) is each branch
having different read/ write access.  So, we're back to git.git where
Junio has graciously given me write support to pu, but not next or
master.  So I set up branch.master.pushremote and
branch.next.pushremote to ram and run git push; from pu.  Disaster:
the pu ref went through fine, but master and next failed to get pushed
despite me specifying a proper pushremote for them.

> I have a similar remote setup in my git.git repository. But all of my
> branch.*.remote variables point to origin, because my branches are based
> off of Junio's master. A matching push goes to the wrong place (and I
> have screwed it up many times; it is nice that I do not have write
> access to Junio's repository). The is broken without having pushremote
> at all (and the proper fix is your remote.pushdefault).

Yeah, I can't believe I lived without remote.pushdefault for this long.

> If we are not going to break the existing behavior, I think it can be
> argued that consistency and simplicity of the rules is important, so the
> user can predict what will happen. But the more we discuss, the more I
> think we should simply change the current behavior (to stop respecting
> branch.* config with "matching"), which just seems wrong to me. Then we
> can be simple and consistent, and do what the user probably intended.

So there are some push.default options that respect branch.* config
(ie. "current"), and others that don't (ie. "matching").  I would
argue that push.default is badly designed to begin with, so the
solution makes sense to me even if the patch is a bit of hack; we
never guaranteed that the various push.default options respect the
same configuration variables.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:24                                     ` Jeff King
@ 2013-04-10 20:55                                       ` Ramkumar Ramachandra
  2013-04-10 21:04                                         ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 20:55 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> On Thu, Apr 11, 2013 at 01:49:54AM +0530, Ramkumar Ramachandra wrote:
>> Huh, why?  Simply because he specified master alongside it?  How can
>> we infer what you said in a consistent system?
>
> That's kind of my point. Why would they put two refs together in a
> single push command? Did they mean "I am pushing up master, and since I
> just tagged it, send the tag along, too"? Or did they really mean to
> push them to two different places? If so, why not just run two separate
> push commands?

I disagree.  The protocol was built ground up to support updating
multiple refs in the same git push.  Running N separate push commands
is _not_ the same thing at all; it running N times as slowly aside.

Pushing multiple refs is a valid and cogent usecase (while multiple
remotes is not).  git is a distributed system: I make lots of changes
to various branches, tags and decide to push only when I'm taking a
break for lunch: at this point, I want to update all my refs on the
remote.  In other words, I batch up ref updates because git is _meant_
to do that: creating/ modifying/ moving/ deleting refs is super-fast
(and happens all the time), while pushing is a slow and dangerous
(because gc runs) operation.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:41                                     ` Ramkumar Ramachandra
@ 2013-04-10 21:02                                       ` Ramkumar Ramachandra
  2013-04-10 21:32                                         ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:02 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> Jeff King wrote:
>> If we are not going to break the existing behavior, I think it can be
>> argued that consistency and simplicity of the rules is important, so the
>> user can predict what will happen. But the more we discuss, the more I
>> think we should simply change the current behavior (to stop respecting
>> branch.* config with "matching"), which just seems wrong to me. Then we
>> can be simple and consistent, and do what the user probably intended.
>
> So there are some push.default options that respect branch.* config
> (ie. "current"), and others that don't (ie. "matching").  I would
> argue that push.default is badly designed to begin with, so the
> solution makes sense to me even if the patch is a bit of hack; we
> never guaranteed that the various push.default options respect the
> same configuration variables.

If we're going to break "matching" anyway, let's break it fully.  I
propose that we make it respect each individual branch's
branch.<name>.pushremote/ branch.<name>.remote and push the branch to
that remote.  That'll let us design a git push -- master
implicit-push; that actually makes sense.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:55                                       ` Ramkumar Ramachandra
@ 2013-04-10 21:04                                         ` Jeff King
  2013-04-10 21:11                                           ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Jeff King @ 2013-04-10 21:04 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 02:25:59AM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> > On Thu, Apr 11, 2013 at 01:49:54AM +0530, Ramkumar Ramachandra wrote:
> >> Huh, why?  Simply because he specified master alongside it?  How can
> >> we infer what you said in a consistent system?
> >
> > That's kind of my point. Why would they put two refs together in a
> > single push command? Did they mean "I am pushing up master, and since I
> > just tagged it, send the tag along, too"? Or did they really mean to
> > push them to two different places? If so, why not just run two separate
> > push commands?
> 
> I disagree.  The protocol was built ground up to support updating
> multiple refs in the same git push.  Running N separate push commands
> is _not_ the same thing at all; it running N times as slowly aside.

But I think all of this discussion just reinforces my point. We do not
have to agree on what the user intended. But the fact that we do not
agree means that out of a sample size of 2 users, we have 2 different
things the user expects to happen. If we choose a behavior and say "this
makes sense", then the other half of the users are going to be confused
or annoyed.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:04                                         ` Jeff King
@ 2013-04-10 21:11                                           ` Ramkumar Ramachandra
  2013-04-10 21:18                                             ` Jonathan Nieder
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:11 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Jeff King wrote:
> But I think all of this discussion just reinforces my point. We do not
> have to agree on what the user intended. But the fact that we do not
> agree means that out of a sample size of 2 users, we have 2 different
> things the user expects to happen. If we choose a behavior and say "this
> makes sense", then the other half of the users are going to be confused
> or annoyed.

Yes, disagreement is healthy.  My point is that we should have "sane"
defaults, and fine-grained configurability so that uses who disagree
can maintain their own configs.  In this case, respecting a
branch.*.remote for each branch is more fine-grained, while not doing
so is coarse and makes me unhappy.  Then again, we don't have to go
overboard and design another ten configuration variables, but we can
atleast improve on what we already have without breaking consistency
(but we have to minimally break backward compatibility).

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:27                                 ` Junio C Hamano
@ 2013-04-10 21:15                                   ` Ramkumar Ramachandra
  0 siblings, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jonathan Nieder, Git List, Duy Nguyễn

Junio C Hamano wrote:
> On the other hand, a good thing is that the remote.pushdefault makes
> perfect sense whether you use the upstream mode or the matching
> mode.  I vaguely recall that I kept telling you that the overall
> default should be there and per-branch stuff can come later if/as
> needed, to which you resisted for a couple of rounds of reviews and
> I couldn't quite figure out where the resistance was coming from.
> Come to think of it, perhaps that might be rooted in the same
> reason of not thinking about users of "matching" mode.  I dunno, and
> I do not think it matters.

remote.pushdefault is simple; it doesn't open up interesting
possibilities like branch.<name>.pushremote does (I mentioned
branch-specific r/w access somewhere else in the thread).  Because of
my obsession with "current", I never think of the repository as a
whole but each branch separately tracking a remote.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:11                                           ` Ramkumar Ramachandra
@ 2013-04-10 21:18                                             ` Jonathan Nieder
  2013-04-10 21:23                                               ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-10 21:18 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jeff King, Junio C Hamano, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:

>                                My point is that we should have "sane"
> defaults, and fine-grained configurability so that uses who disagree
> can maintain their own configs.

I don't agree with this principle.  I like a tool that behaves sanely
with little work and that is flexible enough to do hard things when
that's needed.  Neither of those attributes implies configurability,
except in those unfortunate cases where "behaving sanely with little
work on the user's part" has to involve a different behavior from
person to person.

When people disagree about sane defaults, that's a sign that we didn't
understand the problem well.  Often more thinking can lead to a
simpler answer.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:18                                             ` Jonathan Nieder
@ 2013-04-10 21:23                                               ` Ramkumar Ramachandra
  2013-04-10 21:29                                                 ` Jonathan Nieder
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:23 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Jeff King, Junio C Hamano, Git List, Duy Nguyễn

Jonathan Nieder wrote:
> When people disagree about sane defaults, that's a sign that we didn't
> understand the problem well.  Often more thinking can lead to a
> simpler answer.

Okay, let's see if we can all agree.

In a different email, you wrote:
>        git push master
> ...
>  a) Error: you didn't tell me which remote to push to.
>  b) Just behave like "git push my-personal-remote master".
>  c) Behave like "git push origin master".

Here, I'd argue for (d): push to branch.master.pushremote/
branch.master.remote/ remote.pushdefault/ origin.  If others agree on
this, we can break "matching" appropriately, like I proposed earlier,
to make everything consistent once again.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 20:11                                   ` Jeff King
@ 2013-04-10 21:23                                     ` Jonathan Nieder
  0 siblings, 0 replies; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-10 21:23 UTC (permalink / raw)
  To: Jeff King
  Cc: Ramkumar Ramachandra, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
> On Wed, Apr 10, 2013 at 01:05:12PM -0700, Jonathan Nieder wrote:

>> 	git push
>>
>> and "[push] default = upstream", then it is obvious what the user
>> wanted to happen.  But what about when "[push] default = matching"?
>> Which of the following behaviors is correct?
>>
>>  a) Error: you didn't tell me which remote to push to.
>>  b) Just behave like "git push my-personal-remote :".
>>  c) Ignore which branch is the current branch and behave like
>>     "git push origin :".
>>
>> How about when "[push] default = current"?
>>
>> Except that people might have scripts or habits tied to the current
>> behavior, any of (a), (b), and (c) sounds fine to me.  (b) is the
>> obvious choice for historical reasons.
>
> I think (b) could be quite surprising to a user. I suspect it hasn't
> come up because people just don't work with a lot of different remotes
> in practice.

Yeah, I think you're right.

I'll try writing a series to switch to (c) for [push] default = matching
and (a) for default = simple (and one of the two for default = current.
Not sure which yet).

Thanks,
Jonathan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:23                                               ` Ramkumar Ramachandra
@ 2013-04-10 21:29                                                 ` Jonathan Nieder
  2013-04-10 21:42                                                   ` Ramkumar Ramachandra
  0 siblings, 1 reply; 68+ messages in thread
From: Jonathan Nieder @ 2013-04-10 21:29 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jeff King, Junio C Hamano, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> Jonathan Nieder wrote:

>>        git push master
>> ...
>>  a) Error: you didn't tell me which remote to push to.
>>  b) Just behave like "git push my-personal-remote master".
>>  c) Behave like "git push origin master".
>
> Here, I'd argue for (d): push to branch.master.pushremote/
> branch.master.remote/ remote.pushdefault/ origin.

My first hunch is not to like this, since it means

	git push -- master next

might push to two different remotes and because it's not obvious
to me when it would be useful.

So I am still leaning toward the behavior Jeff suggested.  That said,
we're probably at the point where enough scenarios have been described
for someone to write a patch with a clear explanation about how their
proposed behavior takes care of them all.

Thanks,
Jonathan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:02                                       ` Ramkumar Ramachandra
@ 2013-04-10 21:32                                         ` Ramkumar Ramachandra
  0 siblings, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:32 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> If we're going to break "matching" anyway, let's break it fully.

Wait, let's not break anything.  Instead, let us invent a new
push.default that does this ref-to-remote matching, and make git push
-- master push-implicit; consistent with that.  Then "matching" can be
deprecated as usual.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:29                                                 ` Jonathan Nieder
@ 2013-04-10 21:42                                                   ` Ramkumar Ramachandra
  2013-04-10 21:56                                                     ` Jeff King
  0 siblings, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 21:42 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Jeff King, Junio C Hamano, Git List, Duy Nguyễn

Jonathan Nieder wrote:
> My first hunch is not to like this, since it means
>
>         git push -- master next
>
> might push to two different remotes and because it's not obvious
> to me when it would be useful.

Yes, it will push to two different remotes.  And why is it not useful?
 If we also had something corresponding to branch.<name>.merge for
push*, I would argue that this and branch.<name>.pushremote together
define how a branch should be pushed, independent of everything else.
Like I said earlier, I don't think of a git repository as a whole, but
rather a collection of upstream and forked branches.  Every branch is
always fetched  from its upstream (might or might not be the same as
fork) using branch.<name>.remote, and pushed to its fork using
branch.<name>.pushremote.  A git push; can use the context of the
current branch to select branches (along with their configurations) to
push, nothing more.  It should not apply the configuration of the
current branch to the other branches that it's pushing; that's just
wrong.

* Can we write this branch.<name>.pushmap, effectively overriding
branch.<name>.merge when in push.default = upstream and simple?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:42                                                   ` Ramkumar Ramachandra
@ 2013-04-10 21:56                                                     ` Jeff King
  2013-04-10 22:06                                                       ` Ramkumar Ramachandra
  2013-04-10 22:11                                                       ` Ramkumar Ramachandra
  0 siblings, 2 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 21:56 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 03:12:20AM +0530, Ramkumar Ramachandra wrote:

> Jonathan Nieder wrote:
> > My first hunch is not to like this, since it means
> >
> >         git push -- master next
> >
> > might push to two different remotes and because it's not obvious
> > to me when it would be useful.
> 
> Yes, it will push to two different remotes.  And why is it not useful?

It's not that it's not potentially useful. It's that it may be
surprising and annoying to users who did not want that.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:56                                                     ` Jeff King
@ 2013-04-10 22:06                                                       ` Ramkumar Ramachandra
  2013-04-10 22:16                                                         ` Jeff King
  2013-04-10 22:11                                                       ` Ramkumar Ramachandra
  1 sibling, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 22:06 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
> It's not that it's not potentially useful. It's that it may be
> surprising and annoying to users who did not want that.

... but this is a new syntax, and doesn't break any existing
expectations.  Why are you imagining what users will expect with a git
push -- master next; that hasn't been invented yet?  From "matching"?
 But we've made it very clear that it's going to change soon.  Users
can still use the git push origin master next; form as usual.  In my
opinion, this new syntax is incredibly useful if users set pushremote
properly.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 21:56                                                     ` Jeff King
  2013-04-10 22:06                                                       ` Ramkumar Ramachandra
@ 2013-04-10 22:11                                                       ` Ramkumar Ramachandra
  2013-04-10 22:23                                                         ` Jeff King
  1 sibling, 1 reply; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 22:11 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
> It's not that it's not potentially useful. It's that it may be
> surprising and annoying to users who did not want that.

Besides, I'm not able to imagine one scenario where this is the wrong
or annoying thing to do.  Can you provide an example?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 22:06                                                       ` Ramkumar Ramachandra
@ 2013-04-10 22:16                                                         ` Jeff King
  0 siblings, 0 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 22:16 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 03:36:10AM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> > It's not that it's not potentially useful. It's that it may be
> > surprising and annoying to users who did not want that.
> 
> ... but this is a new syntax, and doesn't break any existing
> expectations.  Why are you imagining what users will expect with a git
> push -- master next; that hasn't been invented yet?

Didn't I already say that I expected a different behavior than you are
proposing from "git push -- v1.2.3 master"? 

Yes, it is possible to lay out all of the rules in the manpage so that
the user can predict what will happen. But users do not always know or
remember all of those rules, especially if it "just works" most of the
time (e.g., they usually push two branches, but this time push a tag).
If a command is easy to screw up, people will screw it up, and get
surprised and annoyed when it happens. We can say "well, you should have
read the manpage", but it is much nicer if we can come up with a command
that is harder to screw up.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 22:11                                                       ` Ramkumar Ramachandra
@ 2013-04-10 22:23                                                         ` Jeff King
  2013-04-10 22:31                                                           ` Ramkumar Ramachandra
  2013-04-11  7:38                                                           ` Ramkumar Ramachandra
  0 siblings, 2 replies; 68+ messages in thread
From: Jeff King @ 2013-04-10 22:23 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

On Thu, Apr 11, 2013 at 03:41:33AM +0530, Ramkumar Ramachandra wrote:

> Jeff King wrote:
> > It's not that it's not potentially useful. It's that it may be
> > surprising and annoying to users who did not want that.
> 
> Besides, I'm not able to imagine one scenario where this is the wrong
> or annoying thing to do.  Can you provide an example?

To flesh out my earlier example:

  $ git clone https://github.com/upstream/project.git
  $ cd project
  $ hack hack hack; commit commit commit
  $ git tag -m 'something of note' my-tag
  $ git remote add me https://github.com/me/project.git
  $ git config branch.master.remote me
  $ git tag -m 'something of note'
  $ git push master my-tag

My intent there is publish both master and mytag, but my-tag goes to
origin. It's obvious if you think carefully about (and know) the rules,
and it's user error. But what fault do we take for designing a feature
that causes confusion?

Maybe I am the only one who might make that mistake, and it is a
non-issue. But I would be much happier if git said "hey, are you sure
you wanted to push to two different remotes?". At least by default.

-Peff

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 22:23                                                         ` Jeff King
@ 2013-04-10 22:31                                                           ` Ramkumar Ramachandra
  2013-04-11  7:38                                                           ` Ramkumar Ramachandra
  1 sibling, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-10 22:31 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
> To flesh out my earlier example:
>
>   $ git clone https://github.com/upstream/project.git
>   $ cd project
>   $ hack hack hack; commit commit commit
>   $ git tag -m 'something of note' my-tag
>   $ git remote add me https://github.com/me/project.git
>   $ git config branch.master.remote me
>   $ git tag -m 'something of note'
>   $ git push master my-tag
>
> My intent there is publish both master and mytag, but my-tag goes to
> origin. It's obvious if you think carefully about (and know) the rules,
> and it's user error. But what fault do we take for designing a feature
> that causes confusion?

Good example.  Sorry, I misunderstood your one-liner.  I agree that
this is confusing.  Tags are a bit of an outlier, and we have to think
of some way to behave sensibly with them.  I'll let you know if I
think of something in the next few hours.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 22:23                                                         ` Jeff King
  2013-04-10 22:31                                                           ` Ramkumar Ramachandra
@ 2013-04-11  7:38                                                           ` Ramkumar Ramachandra
  2013-04-11  7:45                                                             ` Ramkumar Ramachandra
  2013-04-11 21:40                                                             ` Junio C Hamano
  1 sibling, 2 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-11  7:38 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Jeff King wrote:
>   $ git clone https://github.com/upstream/project.git
>   $ cd project
>   $ hack hack hack; commit commit commit
>   $ git tag -m 'something of note' my-tag
>   $ git remote add me https://github.com/me/project.git
>   $ git config branch.master.remote me
>   $ git tag -m 'something of note'
>   $ git push master my-tag

Tags have nothing to do with branches, and it is illogical to respect
branch.* when pushing a tag.  You've illustrated a common case when
the user creates a tag on a specific branch and immediately pushes it.
 I would argue that optimizing our tools for this specific usecase
breaks the general case.  What if I create a branch on master, and
decide to push the tag after checking out implicit-push and doing some
work on it?  Does that not break user expectations?

In the "I push to the same place I pull from" (aka. single-remote)
case, there are never any problems and even "matching" works fine.
However, in the triangular workflow (aka. multiple-remote) case, you
must give git enough information about your workflow for it to DTRT.
I will argue that, in the above example, you have not configured git
for a multiple-remote case, and that you cannot expect it to DTRT
since you have supplied insufficient information.  As to how to
configure git for the general multiple-remote case:

Let us imagine that origin points to git/git.git (upstream), ram
points to artagnon/git.git and peff points to peff/git.git.  I fork
off from upstream and have various local branches that only have
corresponding refs in ram (say implicit-push).  Then, you fork off
from me, and have various local branches that only have corresponding
refs in peff (say implicit-push-next).  I have peff as a configured
remote, because I routinely review the changes you make to my fork.
In this case, I must have:

- push.default set to anything but matching, because matching makes no
sense in the multiple-remote scenario*.

- remote.default set to origin, because this is where I get new code
from for all branches.

- remote.pushdefault set to ram, because this is where I publish all
my refs to (whether branches or tags).  I might have local branches
that I will never publish, but that's a separate issue.  The point is
that all my tags will always be published here.

- branch.implicit-push.remote set to ram, because this is the correct
upstream for the implicit-push branch.

- branch.implicit-push-next.remote set to peff, because this is the
correct upstream for the implicit-push-next branch.

- branch.implicit-push-next.pushremote set to null**, because I will
never want to push this branch.

(Note that branch.implicit-push.pushremote is unnecessary because
remote.pushdefault takes care of that)

With these settings, git push will always DTRT when you specify
nothing, just a remote, or just a refspec.  Ofcourse, you can specify
both and be explicit (which is what we do now).  Does this make sense?
 Should we document this in gitworkflows.txt so that users know what
is expected of them when they move from a single-remote setup to a
multi-remote setup?

* I will definitely push for the deprecation of push.default=matching,
but I doubt we need to invent a new push.default.  current makes a lot
of sense to me personally.

** Yet to be invented.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-11  7:38                                                           ` Ramkumar Ramachandra
@ 2013-04-11  7:45                                                             ` Ramkumar Ramachandra
  2013-04-11 21:40                                                             ` Junio C Hamano
  1 sibling, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-11  7:45 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, Junio C Hamano, Git List, Duy Nguyễn

Ramkumar Ramachandra wrote:
> - branch.implicit-push-next.pushremote set to null**, because I will
> never want to push this branch.

Currently, I have a hacky workaround: I set
branch.implicit-push-next.pushremote to a remote that I don't have
write access to (ie. origin), effectively failing all my attempts to
push this branch.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-11  7:38                                                           ` Ramkumar Ramachandra
  2013-04-11  7:45                                                             ` Ramkumar Ramachandra
@ 2013-04-11 21:40                                                             ` Junio C Hamano
  2013-04-13  5:07                                                               ` Ramkumar Ramachandra
  1 sibling, 1 reply; 68+ messages in thread
From: Junio C Hamano @ 2013-04-11 21:40 UTC (permalink / raw)
  To: Ramkumar Ramachandra
  Cc: Jeff King, Jonathan Nieder, Git List, Duy Nguyễn

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Let us imagine that origin points to git/git.git (upstream), ram
> points to artagnon/git.git and peff points to peff/git.git.  I fork
> off from upstream and have various local branches that only have
> corresponding refs in ram (say implicit-push).  Then, you fork off
> from me, and have various local branches that only have corresponding
> refs in peff (say implicit-push-next).  I have peff as a configured
> remote, because I routinely review the changes you make to my fork.
> In this case, I must have:
>
> - push.default set to anything but matching, because matching makes no
> sense in the multiple-remote scenario*.

The "matching" style makes sense only when pushing to your default
publishing repository, _and_ your work style is to finish working on
all branches that matter before pushing things out.  Instead of
keeping a configuration file on your local end that says "here are
the branches I want to publish", you let the remote side remember
them for you.

When pushing into other kinds of repositories (e.g. you can update
some but not all of the branches, or you want to touch only some of
them and not others even if you have enough privilege to update any
of them) or when you do not "batch" and push out one branch as work
on it is done, while other branches that you would eventually
publish are still not ready, "matching" is not for you.

> - remote.default set to origin, because this is where I get new code
> from for all branches.

OK.

> - remote.pushdefault set to ram, because this is where I publish all
> my refs to (whether branches or tags).  I might have local branches
> that I will never publish, but that's a separate issue.  The point is
> that all my tags will always be published here.

Makes sense.  The variable is to name such a publishing location.

> - branch.implicit-push.remote set to ram, because this is the correct
> upstream for the implicit-push branch.

If "implicit-push" branch at "ram" is updated by other people and
you may have to pull back from, you would need this for "git pull"
(without arguments) while on that branch, I guess.  But I got the
impression from your scenario that "ram" won't be updated by anybody
but you.

So I am guessing that this may not be needed.

> - branch.implicit-push-next.remote set to peff, because this is the
> correct upstream for the implicit-push-next branch.

Makes sense.  You are building on top of his work.

> - branch.implicit-push-next.pushremote set to null**, because I will
> never want to push this branch.

This becomes necessary only if you use push.default set to "current"
(or "upstream").  If you mistakenly say "git push" (no other
arguments), without this configuration you will end up pushing the
branch out.

With "matching", because "ram" would not have this branch (you
decided not to publish it), "git push" on this branch won't push it
out.

It may be that adding push.default=current-but-do-not-create-anew
could help.  It is a cross between 'matching' and 'current', to say
"consider pushing out the current one, but only when the other side
already has one", and may help people who do not "batch".

> (Note that branch.implicit-push.pushremote is unnecessary because
> remote.pushdefault takes care of that)

True.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-10 18:59                           ` Jeff King
  2013-04-10 19:31                             ` Ramkumar Ramachandra
@ 2013-04-12 22:14                             ` Junio C Hamano
  1 sibling, 0 replies; 68+ messages in thread
From: Junio C Hamano @ 2013-04-12 22:14 UTC (permalink / raw)
  To: Jeff King
  Cc: Jonathan Nieder, Ramkumar Ramachandra, Git List, Duy Nguyễn

Jeff King <peff@peff.net> writes:

> Which is still kind of weird, because why should the branch you are on
> affect the default push location? But that is how default "matching" has
> always behaved, and we would remain consistent with that.

I agree that what makes us behave "kind of weird" is that the
current branch is used to look up branch.$name.{remote,pushremote}
when pushing. I do not think "matching" [*1*] has anything to do
with it.

The per-branch configuration, branch.$name.{remote,pushremote}, says
"this branch interacts with a remote that is different from what I
normally interact with".

It is excusable for branch.$name.remote to take the current branch
into account, when it is used to govern the fetch-integrate side
(i.e.  not used as a fall-back for branch.$name.pushremote).  In
order to affect that configured local branch, e.g. "git pull" to
merge other's work, you need to have that named branch checked out
in your working tree.  Triggering the effect of the configuration
based on which branch is checked out makes more sense because of
that reason when you are fetching.

It does not make much sense to use the current branch as the key to
look it up when you are pushing things out. If anything, what is
being pushed out should be what determines where it goes.

But that is a realization that comes after you think the issue long
and hard enough. To a casual end user, I think it is an equally or
even more natural expectation a "git push" would pick the destination
based on what branch you are currently on, as that is what happens
when he runs the command without any argument.


[Footnote]

*1* The "matching" semantics is to support the workflow for people
who batch things up. You perfect _all_ your branches that matter to
the public, and push all of them in one go. If you do not finish a
work on one branch and push out when other branches are not yet
ready, you do not want your push to be limited to the current
branch. And you do not have to "configure" what branches should be
visible to the public. Instead, you have _your_ remote remember it
for you: what are already there are the ones that are updated.

The "current", "upstream", etc. are to support folks who want to
push work done on a single branch out as soon as it is done, even
though the other branches are in no shape to be pushed out.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [ITCH] Specify refspec without remote
  2013-04-11 21:40                                                             ` Junio C Hamano
@ 2013-04-13  5:07                                                               ` Ramkumar Ramachandra
  0 siblings, 0 replies; 68+ messages in thread
From: Ramkumar Ramachandra @ 2013-04-13  5:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Jonathan Nieder, Git List, Duy Nguyễn

Junio C Hamano wrote:
> When pushing into other kinds of repositories (e.g. you can update
> some but not all of the branches, or you want to touch only some of
> them and not others even if you have enough privilege to update any
> of them) or when you do not "batch" and push out one branch as work
> on it is done, while other branches that you would eventually
> publish are still not ready, "matching" is not for you.

I agree that we need to get a "batching" push.default corresponding to
"matching" for multiple-remote setups.  However, I think we should
hold it off until my implicit-push patch is finished.  After using it
for a few days, I'll get a good idea about what this new push.default
setting should look like.

> If "implicit-push" branch at "ram" is updated by other people and
> you may have to pull back from, you would need this for "git pull"
> (without arguments) while on that branch, I guess.  But I got the
> impression from your scenario that "ram" won't be updated by anybody
> but you.
>
> So I am guessing that this may not be needed.

In my opinion, it is a fundamental mistake to have more than one
person working on a branch.  There is one exception to this rule: it
is alright when there are only two people working on it, and one of
them is a "reliable fast-forward-only read-only upstream".  Let me
illustrate this with an example: I sometimes find myself working on
the master branch of git.git (fetch from origin: git/git.git, publish
to ram: artagnon/git.git).  This is because origin/master is an
"reliable fast-forward-only read-only upstream" (read-only in the
sense that it can only be updated with a git fetch).  My interaction
with it is limited to 'git rebase origin/master' on the master branch.
 I will never find myself manipulating it, and the rebase will never
fail unless my patches conflict with the new upstream.

As to why the setting is needed: I often work on more than one device*,
and I suspect a lot of people do this today.  I always fetch all
changes on my private branches before beginning work, unless I want to
end up in a confusing mess (I often rewrite history).

> This becomes necessary only if you use push.default set to "current"
> (or "upstream").  If you mistakenly say "git push" (no other
> arguments), without this configuration you will end up pushing the
> branch out.

Right.  The objective is to get 'git push' to _always_ DTRT.

> It may be that adding push.default=current-but-do-not-create-anew
> could help.  It is a cross between 'matching' and 'current', to say
> "consider pushing out the current one, but only when the other side
> already has one", and may help people who do not "batch".

Hm.  I would argue that exploding push.default options is unhealthy,
and that we should move towards thinking of more fine-grained control
with different orthogonal options.  I'll first do it for pull
(autostash has been in progress for some time); then we can port the
relevant options to push.

* I still haven't made much progress on a design for config-sharing.  I
think I'm missing something big.

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2013-04-13  5:08 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-18 16:58 [ITCH] Specify refspec without remote Ramkumar Ramachandra
2013-03-18 17:08 ` Jeff King
2013-03-19  9:58   ` Ramkumar Ramachandra
2013-03-19 10:02     ` Jeff King
2013-03-19 11:33   ` Duy Nguyen
2013-03-19 11:53     ` Ramkumar Ramachandra
2013-03-19 12:15       ` Duy Nguyen
2013-03-19 13:03         ` Holger Hellmuth (IKS)
2013-03-19 11:58     ` Holger Hellmuth (IKS)
2013-03-19 15:43       ` Junio C Hamano
2013-03-19 15:43     ` Junio C Hamano
2013-04-09 11:44   ` Ramkumar Ramachandra
2013-04-09 17:31     ` Junio C Hamano
2013-04-09 17:39       ` Ramkumar Ramachandra
2013-04-09 17:58         ` Junio C Hamano
2013-04-09 18:03           ` Ramkumar Ramachandra
2013-04-09 18:08             ` Ramkumar Ramachandra
2013-04-09 19:29             ` Junio C Hamano
2013-04-09 23:13               ` Jonathan Nieder
2013-04-09 23:14                 ` Jonathan Nieder
2013-04-10  1:19                 ` Junio C Hamano
2013-04-10  4:13                   ` Jeff King
2013-04-10 16:37                     ` Junio C Hamano
2013-04-10 17:27                       ` Jeff King
2013-04-10 18:54                         ` Junio C Hamano
2013-04-10 18:59                           ` Jeff King
2013-04-10 19:31                             ` Ramkumar Ramachandra
2013-04-10 19:33                               ` Ramkumar Ramachandra
2013-04-10 19:52                               ` Jeff King
2013-04-10 20:05                                 ` Ramkumar Ramachandra
2013-04-10 20:21                                   ` Jeff King
2013-04-10 20:41                                     ` Ramkumar Ramachandra
2013-04-10 21:02                                       ` Ramkumar Ramachandra
2013-04-10 21:32                                         ` Ramkumar Ramachandra
2013-04-10 20:21                                 ` Junio C Hamano
2013-04-10 19:53                               ` Ramkumar Ramachandra
2013-04-10 20:05                                 ` Jonathan Nieder
2013-04-10 20:11                                   ` Jeff King
2013-04-10 21:23                                     ` Jonathan Nieder
2013-04-10 20:05                                 ` Jeff King
2013-04-10 20:19                                   ` Ramkumar Ramachandra
2013-04-10 20:24                                     ` Jeff King
2013-04-10 20:55                                       ` Ramkumar Ramachandra
2013-04-10 21:04                                         ` Jeff King
2013-04-10 21:11                                           ` Ramkumar Ramachandra
2013-04-10 21:18                                             ` Jonathan Nieder
2013-04-10 21:23                                               ` Ramkumar Ramachandra
2013-04-10 21:29                                                 ` Jonathan Nieder
2013-04-10 21:42                                                   ` Ramkumar Ramachandra
2013-04-10 21:56                                                     ` Jeff King
2013-04-10 22:06                                                       ` Ramkumar Ramachandra
2013-04-10 22:16                                                         ` Jeff King
2013-04-10 22:11                                                       ` Ramkumar Ramachandra
2013-04-10 22:23                                                         ` Jeff King
2013-04-10 22:31                                                           ` Ramkumar Ramachandra
2013-04-11  7:38                                                           ` Ramkumar Ramachandra
2013-04-11  7:45                                                             ` Ramkumar Ramachandra
2013-04-11 21:40                                                             ` Junio C Hamano
2013-04-13  5:07                                                               ` Ramkumar Ramachandra
2013-04-10 20:27                                 ` Junio C Hamano
2013-04-10 21:15                                   ` Ramkumar Ramachandra
2013-04-12 22:14                             ` Junio C Hamano
2013-04-10  3:50                 ` Jeff King
2013-04-10 13:22                   ` Ramkumar Ramachandra
2013-04-10 15:56                     ` Jeff King
2013-04-10 16:38                   ` Junio C Hamano
2013-04-10 17:29                     ` Jeff King
2013-04-10 13:19                 ` Ramkumar Ramachandra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.