doc: clarify "explicitly given" in push.default
diff mbox series

Message ID 20200125200554.GC5519@coredump.intra.peff.net
State New
Headers show
Series
  • doc: clarify "explicitly given" in push.default
Related show

Commit Message

Jeff King Jan. 25, 2020, 8:05 p.m. UTC
On Sat, Jan 25, 2020 at 08:38:04AM +0100, Bert Wesarg wrote:

> thanks for this pointer. My initial pointer was the help for push.default:
> 
>  From git-config(1):
> 
>        push.default
>            Defines the action git push should take if no refspec is explicitly
>            given. Different values are well-suited for specific workflows; for
> 
> Thus I expected, that this takes effect, when just calling 'git push'.

Yeah, I agree "explicitly given" is vague there. Perhaps the patch below
is worth doing?

> What I actually want to achieve, is to track a remote branch with a
> different name locally, but 'git push' should nevertheless push to
> tracked remote branch.
> 
> In my example above, befor adding the 'push.origin.push' refspec, rename the branch:
> 
>     $ git branch -m local
>     $ git push --dry-run
>       To ../bare.git
>        * [new branch]      local -> local
> 
> Is it possible that this pushes to the tracked branch automatically,
> and because I have multiple such branches, without the use of a push
> refspec.

I think if push.default is set to "upstream" then it would do what you
want as long as you set the upstream of "local" (e.g., by doing "git
branch --set-upstream-to=origin/master local).

There's another way of doing this, which is when you have a "triangular"
flow: you might pull changes from origin/master into your local branch
X, but then push them elsewhere. Usually this would be pushing to a
branch named X on a different remote than origin (e.g., your public fork
of upstream on a server). And for that you can set branch.X.pushRemote.

There's no corresponding triangular config branch.X.pushBranch to push
to a different name than "X" on the remote. And while I do think it
would be rare to want it, I could imagine a case (you have a triangular
flow where everybody shares a central repo, but you want to push to some
local namespace within it; usually people do that now by just making the
namespace part of their local branch names, too).

Anyway, here's the documentation patch.

-- >8 --
Subject: [PATCH] doc: clarify "explicitly given" in push.default

The documentation for push.default mentions that it is used if no
refspec is "explicitly given". Let's clarify that giving a refspec on
the command-line _or_ in the config will override it.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/config/push.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Bert Wesarg Jan. 27, 2020, 7 a.m. UTC | #1
On 25.01.20 21:05, Jeff King wrote:
> On Sat, Jan 25, 2020 at 08:38:04AM +0100, Bert Wesarg wrote:
> 
>> thanks for this pointer. My initial pointer was the help for push.default:
>>
>>   From git-config(1):
>>
>>         push.default
>>             Defines the action git push should take if no refspec is explicitly
>>             given. Different values are well-suited for specific workflows; for
>>
>> Thus I expected, that this takes effect, when just calling 'git push'.
> 
> Yeah, I agree "explicitly given" is vague there. Perhaps the patch below
> is worth doing?
> 
>> What I actually want to achieve, is to track a remote branch with a
>> different name locally, but 'git push' should nevertheless push to
>> tracked remote branch.
>>
>> In my example above, befor adding the 'push.origin.push' refspec, rename the branch:
>>
>>      $ git branch -m local
>>      $ git push --dry-run
>>        To ../bare.git
>>         * [new branch]      local -> local
>>
>> Is it possible that this pushes to the tracked branch automatically,
>> and because I have multiple such branches, without the use of a push
>> refspec.
> 
> I think if push.default is set to "upstream" then it would do what you
> want as long as you set the upstream of "local" (e.g., by doing "git
> branch --set-upstream-to=origin/master local).

Thanks. This pushes only the current branch and honors the 'rename'.

> 
> There's another way of doing this, which is when you have a "triangular"
> flow: you might pull changes from origin/master into your local branch
> X, but then push them elsewhere. Usually this would be pushing to a
> branch named X on a different remote than origin (e.g., your public fork
> of upstream on a server). And for that you can set branch.X.pushRemote.
> 
> There's no corresponding triangular config branch.X.pushBranch to push
> to a different name than "X" on the remote. And while I do think it
> would be rare to want it, I could imagine a case (you have a triangular
> flow where everybody shares a central repo, but you want to push to some
> local namespace within it; usually people do that now by just making the
> namespace part of their local branch names, too).
> 
> Anyway, here's the documentation patch.
> 
> -- >8 --
> Subject: [PATCH] doc: clarify "explicitly given" in push.default
> 
> The documentation for push.default mentions that it is used if no
> refspec is "explicitly given". Let's clarify that giving a refspec on
> the command-line _or_ in the config will override it.
> 
> Signed-off-by: Jeff King <peff@peff.net>
> ---
>   Documentation/config/push.txt | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/config/push.txt b/Documentation/config/push.txt
> index 0a0e000569..554ab44b4c 100644
> --- a/Documentation/config/push.txt
> +++ b/Documentation/config/push.txt
> @@ -1,6 +1,7 @@
>   push.default::
>   	Defines the action `git push` should take if no refspec is
> -	explicitly given.  Different values are well-suited for
> +	explicitly given (either on the command-line or via a
> +	`remote.*.push` config option). Different values are well-suited for
>   	specific workflows; for instance, in a purely central workflow
>   	`upstream` is probably what you want.  Possible values are:
> 

I would rather talk about 'implicitly given', if it is via a `remote.*.push` config option:

  	Defines the action `git push` should take if no refspec is
-	explicitly given.  Different values are well-suited for
-	specific workflows; for instance, in a purely central workflow
-	(i.e. the fetch source is equal to the push destination),
-	`upstream` is probably what you want.  Possible values are:
+	neither explicitly (on the command-line) nor implicitly (via a
+	`remote.*.push` config option) given. Different values are
+	well-suited for specific workflows; for instance, in a purely
+	central workflow (i.e. the fetch source is equal to the push
+	destination), `upstream` is probably what you want.  Possible
+	values are:


Bert
Jeff King Jan. 27, 2020, 7:02 a.m. UTC | #2
On Mon, Jan 27, 2020 at 08:00:22AM +0100, Bert Wesarg wrote:

> > diff --git a/Documentation/config/push.txt b/Documentation/config/push.txt
> > index 0a0e000569..554ab44b4c 100644
> > --- a/Documentation/config/push.txt
> > +++ b/Documentation/config/push.txt
> > @@ -1,6 +1,7 @@
> >   push.default::
> >   	Defines the action `git push` should take if no refspec is
> > -	explicitly given.  Different values are well-suited for
> > +	explicitly given (either on the command-line or via a
> > +	`remote.*.push` config option). Different values are well-suited for
> >   	specific workflows; for instance, in a purely central workflow
> >   	`upstream` is probably what you want.  Possible values are:
> > 
> 
> I would rather talk about 'implicitly given', if it is via a `remote.*.push` config option:
> 
>  	Defines the action `git push` should take if no refspec is
> -	explicitly given.  Different values are well-suited for
> -	specific workflows; for instance, in a purely central workflow
> -	(i.e. the fetch source is equal to the push destination),
> -	`upstream` is probably what you want.  Possible values are:
> +	neither explicitly (on the command-line) nor implicitly (via a
> +	`remote.*.push` config option) given. Different values are
> +	well-suited for specific workflows; for instance, in a purely
> +	central workflow (i.e. the fetch source is equal to the push
> +	destination), `upstream` is probably what you want.  Possible
> +	values are:

Yeah, that sounds fine. Want to wrap it up with as a patch with a commit
message?

-Peff
Bert Wesarg Jan. 27, 2020, 7:48 p.m. UTC | #3
Dear Jeff,

On 27.01.20 08:00, Bert Wesarg wrote:
> On 25.01.20 21:05, Jeff King wrote:
>> On Sat, Jan 25, 2020 at 08:38:04AM +0100, Bert Wesarg wrote:
>>
>>> thanks for this pointer. My initial pointer was the help for push.default:
>>>
>>>   From git-config(1):
>>>
>>>         push.default
>>>             Defines the action git push should take if no refspec is explicitly
>>>             given. Different values are well-suited for specific workflows; for
>>>
>>> Thus I expected, that this takes effect, when just calling 'git push'.
>>
>> Yeah, I agree "explicitly given" is vague there. Perhaps the patch below
>> is worth doing?
>>
>>> What I actually want to achieve, is to track a remote branch with a
>>> different name locally, but 'git push' should nevertheless push to
>>> tracked remote branch.
>>>
>>> In my example above, befor adding the 'push.origin.push' refspec, rename the branch:
>>>
>>>      $ git branch -m local
>>>      $ git push --dry-run
>>>        To ../bare.git
>>>         * [new branch]      local -> local
>>>
>>> Is it possible that this pushes to the tracked branch automatically,
>>> and because I have multiple such branches, without the use of a push
>>> refspec.
>>
>> I think if push.default is set to "upstream" then it would do what you
>> want as long as you set the upstream of "local" (e.g., by doing "git
>> branch --set-upstream-to=origin/master local).
> 
> Thanks. This pushes only the current branch and honors the 'rename'.

while this works …

> 
>>
>> There's another way of doing this, which is when you have a "triangular"
>> flow: you might pull changes from origin/master into your local branch
>> X, but then push them elsewhere. Usually this would be pushing to a
>> branch named X on a different remote than origin (e.g., your public fork
>> of upstream on a server). And for that you can set branch.X.pushRemote.

… it does not play well if you have have both flows in one repository. And I do have both flows. I track the upstream 'master' in the local branch 'Y' and I have also a branch 'X' which is based on 'Y' but should be pushed to a different remote as branch 'Y'. I have configured 'branch.X.pushRemote = triangular' but with 'push.default' set to 'upstream' I get this when:

     $ git push triangular
     fatal: You are pushing to remote 'triangular', which is not the upstream of
     your current branch 'X', without telling me what to push
     to update which remote branch.

In this simple case, without a renaming, I would expect that 'git push' just works. May be just fallback to 'simple' if 'upstream' does not resolve to a fully qualified push?

Best,
Bert
Bert Wesarg Jan. 27, 2020, 8:53 p.m. UTC | #4
On 27.01.20 20:48, Bert Wesarg wrote:
> Dear Jeff,
> 
> On 27.01.20 08:00, Bert Wesarg wrote:
>> On 25.01.20 21:05, Jeff King wrote:
>>> On Sat, Jan 25, 2020 at 08:38:04AM +0100, Bert Wesarg wrote:
>>>
>>>> thanks for this pointer. My initial pointer was the help for push.default:
>>>>
>>>>   From git-config(1):
>>>>
>>>>         push.default
>>>>             Defines the action git push should take if no refspec is explicitly
>>>>             given. Different values are well-suited for specific workflows; for
>>>>
>>>> Thus I expected, that this takes effect, when just calling 'git push'.
>>>
>>> Yeah, I agree "explicitly given" is vague there. Perhaps the patch below
>>> is worth doing?
>>>
>>>> What I actually want to achieve, is to track a remote branch with a
>>>> different name locally, but 'git push' should nevertheless push to
>>>> tracked remote branch.
>>>>
>>>> In my example above, befor adding the 'push.origin.push' refspec, rename the branch:
>>>>
>>>>      $ git branch -m local
>>>>      $ git push --dry-run
>>>>        To ../bare.git
>>>>         * [new branch]      local -> local
>>>>
>>>> Is it possible that this pushes to the tracked branch automatically,
>>>> and because I have multiple such branches, without the use of a push
>>>> refspec.
>>>
>>> I think if push.default is set to "upstream" then it would do what you
>>> want as long as you set the upstream of "local" (e.g., by doing "git
>>> branch --set-upstream-to=origin/master local).
>>
>> Thanks. This pushes only the current branch and honors the 'rename'.
> 
> while this works …
> 
>>
>>>
>>> There's another way of doing this, which is when you have a "triangular"
>>> flow: you might pull changes from origin/master into your local branch
>>> X, but then push them elsewhere. Usually this would be pushing to a
>>> branch named X on a different remote than origin (e.g., your public fork
>>> of upstream on a server). And for that you can set branch.X.pushRemote.
> 
> … it does not play well if you have have both flows in one repository. And I do have both flows. I track the upstream 'master' in the local branch 'Y' and I have also a branch 'X' which is based on 'Y' but should be pushed to a different remote as branch 'Y'. I have configured 'branch.X.pushRemote = triangular' but with 'push.default' set to 'upstream' I get this when:
> 
>      $ git push triangular
>      fatal: You are pushing to remote 'triangular', which is not the upstream of
>      your current branch 'X', without telling me what to push
>      to update which remote branch.
> 
> In this simple case, without a renaming, I would expect that 'git push' just works. May be just fallback to 'simple' if 'upstream' does not resolve to a fully qualified push?

Falling back to simple/current seems to work for my case:

diff --git a/builtin/push.c b/builtin/push.c
index 6dbf0f0bb7..6b2fac7977 100644 builtin/push.c
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -259,7 +259,10 @@ static void setup_default_push_refspecs(struct remote *remote)
                 break;
  
         case PUSH_DEFAULT_UPSTREAM:
-               setup_push_upstream(remote, branch, triangular, 0);
+               if (triangular)
+                       setup_push_current(remote, branch);
+               else
+                       setup_push_upstream(remote, branch, triangular, 0);
                 break;
  
         case PUSH_DEFAULT_CURRENT:

It has some fallouts in the test suite, obviously. But is this something we should pursue at all?

Bert
Jeff King Jan. 27, 2020, 11:14 p.m. UTC | #5
On Mon, Jan 27, 2020 at 08:48:01PM +0100, Bert Wesarg wrote:

> > > There's another way of doing this, which is when you have a "triangular"
> > > flow: you might pull changes from origin/master into your local branch
> > > X, but then push them elsewhere. Usually this would be pushing to a
> > > branch named X on a different remote than origin (e.g., your public fork
> > > of upstream on a server). And for that you can set branch.X.pushRemote.
> 
> … it does not play well if you have have both flows in one repository.
> And I do have both flows. I track the upstream 'master' in the local
> branch 'Y' and I have also a branch 'X' which is based on 'Y' but
> should be pushed to a different remote as branch 'Y'. I have
> configured 'branch.X.pushRemote = triangular' but with 'push.default'
> set to 'upstream' I get this when:
> 
>     $ git push triangular
>     fatal: You are pushing to remote 'triangular', which is not the upstream of
>     your current branch 'X', without telling me what to push
>     to update which remote branch.
> 
> In this simple case, without a renaming, I would expect that 'git
> push' just works. May be just fallback to 'simple' if 'upstream' does
> not resolve to a fully qualified push?

I thought the point of "simple" was to be even more restrictive than
"upstream".

At any rate, your setup is sufficiently complicated that I think you'd
be better off adding a branch.X.pushRef feature (essentially a refspec
to be used just on branch X, though since the source side is implied,
it's really just a destination ref).

-Peff
Bert Wesarg Jan. 28, 2020, 8:48 p.m. UTC | #6
On Tue, Jan 28, 2020 at 12:15 AM Jeff King <peff@peff.net> wrote:
>
> On Mon, Jan 27, 2020 at 08:48:01PM +0100, Bert Wesarg wrote:
>
> > > > There's another way of doing this, which is when you have a "triangular"
> > > > flow: you might pull changes from origin/master into your local branch
> > > > X, but then push them elsewhere. Usually this would be pushing to a
> > > > branch named X on a different remote than origin (e.g., your public fork
> > > > of upstream on a server). And for that you can set branch.X.pushRemote.
> >
> > … it does not play well if you have have both flows in one repository.
> > And I do have both flows. I track the upstream 'master' in the local
> > branch 'Y' and I have also a branch 'X' which is based on 'Y' but
> > should be pushed to a different remote as branch 'Y'. I have
> > configured 'branch.X.pushRemote = triangular' but with 'push.default'
> > set to 'upstream' I get this when:
> >
> >     $ git push triangular
> >     fatal: You are pushing to remote 'triangular', which is not the upstream of
> >     your current branch 'X', without telling me what to push
> >     to update which remote branch.
> >
> > In this simple case, without a renaming, I would expect that 'git
> > push' just works. May be just fallback to 'simple' if 'upstream' does
> > not resolve to a fully qualified push?
>
> I thought the point of "simple" was to be even more restrictive than
> "upstream".
>
> At any rate, your setup is sufficiently complicated that I think you'd
> be better off adding a branch.X.pushRef feature (essentially a refspec
> to be used just on branch X, though since the source side is implied,
> it's really just a destination ref).

thanks. I will try to come up with a patch.

Bert

>
> -Peff

Patch
diff mbox series

diff --git a/Documentation/config/push.txt b/Documentation/config/push.txt
index 0a0e000569..554ab44b4c 100644
--- a/Documentation/config/push.txt
+++ b/Documentation/config/push.txt
@@ -1,6 +1,7 @@ 
 push.default::
 	Defines the action `git push` should take if no refspec is
-	explicitly given.  Different values are well-suited for
+	explicitly given (either on the command-line or via a
+	`remote.*.push` config option). Different values are well-suited for
 	specific workflows; for instance, in a purely central workflow
 	(i.e. the fetch source is equal to the push destination),
 	`upstream` is probably what you want.  Possible values are: