From: Paolo Bonzini <hidden> Date: 2016-06-15 22:46:58
Hi all, I just upgraded to git 1.6.3 and found this new little gem
called push.default...
Now, having gone through an attempt of proposing a different semantics
for "git push", this stroke me as total nonsense, because now we have
two totally incompatible ways to specify push refspecs.
A sensible implementation would have been something like this:
1) Also in 1.6.3, invent a special refspec for "tracking", something
like "HEAD>" (of course this is not a special case; "refs/heads/*>"
would also work, yadda yadda)
2) Also in 1.6.3, add a "--push={current,tracking,matching,mirror}"
option to "git remote add" that would set up a push refspec without the
need to actually know refspec syntax. (--mirror would become just a
synonym for --push=mirror).
3) Possibly, in 1.6.3 make "git clone" add a "push = :" line for the
origin branch. This was actually suggested in a patch by myself.
4) in 1.6.4 or 1.7.0, make "git push" fail outright if there is no push
line, with text suggesting
For remotes that you will create in the future, please use the
`--push' argument to `git remote add'. For existing remotes,
you can use the following command to obtain the same behavior as
git 1.6.3:
git config --add remote.origin.push :
For alternative configurations, please look at the release notes
for git 1.6.4.
so that it's a quick cut'n'paste into the shell to fix this (though once
per repository).
I know it's my fault that I did not follow the development of git last
March, but I could not help ranting that it is extremely wrong to
specify what to push without a refspec (in the configuration, not in the
command line -- the cmdlines can always have more "porcelain" attached
to them).
(1) and (2) in particular can still be straightened, and (4) too maybe.
I can work on the implementation if we agree on the details.
Paolo
From: Junio C Hamano <hidden> Date: 2016-06-15 22:46:58
Paolo Bonzini [off-list ref] writes:
1) Also in 1.6.3, invent a special refspec for "tracking", something
like "HEAD>" (of course this is not a special case; "refs/heads/*>"
would also work, yadda yadda)
You cannot do anything "in 1.6.3"; The ship has already left the port.
You can set push.default to "tracking" and have it take effect for all
remotes you interact with from your repository (set remote.$name.push for
some remotes you do not want this to take effect). Instead, you could
leave push.default to "matching" and define remote.$name.push with the
"push tracking" magic you are going to invent for a specific remote.
Both arrangements can do the same thing, so even if your "HEAD>" is never
supported, there is no functionality loss (similarly, if we did not have
"push.default", we would be Ok if we had your "HEAD>" magic). Depending
on which one you would want to use for majority of remotes you interact
with, you would want both.
So in that sense, I do not think the current situation is such a "total
nonsense" as you seem to be painting it [*1*]. It just does not have the
other half of the story that you are bringing up now.
In other words, I do not have objection to your "HEAD>" at the conceptual
level. At the syntax level, I suspect people will have suggestions for
better alternatives.
In retrospect, because a push refspec (or "magic" you will be adding) for
a specific remote is called "remote.$name.push", it might have been a
better idea to use "remote.push" instead of "push.default" as the name of
the configuration variable. Then the rules can become
* if you ask explicitly from the command line, it wins;
* otherwise, if you have remote.$name,push, it is used;
* otherwise, if you have remote.push, it is used;
* otherwise, the default is "matching".
which is slightly nicer to read, than the current situation where the
third rule talks about push.default instead.
2) Also in 1.6.3, add a "--push={current,tracking,matching,mirror}"
option to "git remote add" that would set up a push refspec without
the need to actually know refspec syntax. (--mirror would become just
a synonym for --push=mirror).
This is probably sensible if/when we do (1).
But here I have to qualify what I mean by (1). I am not married to the
idea of using remote.$name.push at all. I view (1) as solving this issue:
Currently with push.default, we can only set push.default to
something other than "matching" and have specific remote override
that with remote.$name.push with a more concrete refspec, if we
want to have the magic 'tracking push' semantics.
We want to have a way to say "for this and that particular
remotes, use the magic tracking push" in a more direct way.
And hiding the detail of how this "direct way" is implemented from the end
user is a good idea.
3) Possibly, in 1.6.3 make "git clone" add a "push = :" line for the
origin branch. This was actually suggested in a patch by myself.
This contradicts with (1), I think. The default after cloning is
"matching", and if one wants to change it to "track", one not just needs
to set push.default but also needs to remove/twaek remote.origin.push
if you add such a line.
So I do not think this one makes much sense.
4) in 1.6.4 or 1.7.0, make "git push" fail outright if there is no
push line, with text suggesting
This was already part of one possible option for push.default (change the
built-in default to 'nothing-and-warn') when it was introduced, wasn't it?
Instead of suggesting to configure remote.$name.push, it would suggest to
set push.default to a desired value, which I think is a more sensible
thing to do.
[Footnote]
*1* ... even though I admit that I am not convinced 'push "tracking"'
makes much sense for me to begin with, because pushing a branch to the
branch it forked from rarely if ever makes sense in my workflow. But I
can see 'push "tracking"' makes sense in some situations and people seem
to want to do this, so we have already added push.default.
From: Paolo Bonzini <hidden> Date: 2016-06-15 22:46:58
You cannot do anything "in 1.6.3"; The ship has already left the port.
Yes, that was me reasoning out loud.
quoted
4) in 1.6.4 or 1.7.0, make "git push" fail outright if there is no
push line, with text suggesting
This was already part of one possible option for push.default (change the
built-in default to 'nothing-and-warn') when it was introduced, wasn't it?
Instead of suggesting to configure remote.$name.push, it would suggest to
set push.default to a desired value, which I think is a more sensible
thing to do.
Yes, that was also reasoning out loud. It makes sense.
Anyway, suggestion will be helpful for the "tracking" behavior refspec
syntax.
Thanks for the remarks,
Paolo
From: Finn Arne Gangstad <hidden> Date: 2016-06-15 22:46:58
On Mon, Jun 22, 2009 at 12:02:33PM +0200, Paolo Bonzini wrote:
Hi all, I just upgraded to git 1.6.3 and found this new little gem
called push.default...
[...]
You should have been here when we discussed this! :)
1) Also in 1.6.3, invent a special refspec for "tracking", something
like "HEAD>" (of course this is not a special case; "refs/heads/*>"
would also work, yadda yadda)
Yes, this is a weakness righ now - the only way to get tracking
semantics is to set push.default. I could not find a very good way of
specifying this. We currently have the magic refspecs : and
HEAD. Adding a ">" to "HEAD>" would be annoying I think, since it has
to be quoted in the shell.
Maybe we can use ":" as an escape, it is not allowed in refspecs.
Something like "::tracking" (and we cold also have "::matching",
"::current" and so on for completeness)
2) Also in 1.6.3, add a "--push={current,tracking,matching,mirror}"
option to "git remote add" that would set up a push refspec without the
need to actually know refspec syntax. (--mirror would become just a
synonym for --push=mirror).
Sounds like a good idea, the options would also make sense to push I think,
so you can "git push [--current|tracking|...] ".
3) Possibly, in 1.6.3 make "git clone" add a "push = :" line for the
origin branch. This was actually suggested in a patch by myself.
This would destroy the intention of my patch, it would render the
configuration variable pointless I think (and would also silently push
matching).
4) in 1.6.4 or 1.7.0, make "git push" fail outright if there is no push
line, with text suggesting [...]
Hopefully we can get to this stage, that a unconfigured "git push"
gives a small message, indicating how to configure it, and not push
anything. Most "oldtimers" should have configured this already, so it
should not break many setups.
- Finn Arne
From: Paolo Bonzini <hidden> Date: 2016-06-15 22:46:59
Finn Arne Gangstad wrote:
On Mon, Jun 22, 2009 at 12:02:33PM +0200, Paolo Bonzini wrote:
quoted
Hi all, I just upgraded to git 1.6.3 and found this new little gem
called push.default...
[...]
You should have been here when we discussed this! :)
Yes, mea culpa. But I would have expected a *lot* more discussion from
what I remembered about the git list and community. :-)
quoted
1) Also in 1.6.3, invent a special refspec for "tracking", something
like "HEAD>" (of course this is not a special case; "refs/heads/*>"
would also work, yadda yadda)
Yes, this is a weakness righ now - the only way to get tracking
semantics is to set push.default. I could not find a very good way of
specifying this. We currently have the magic refspecs : and
HEAD. Adding a ">" to "HEAD>" would be annoying I think, since it has
to be quoted in the shell.
Yes, > has the disadvantage of quoting.
Maybe we can use ":" as an escape, it is not allowed in refspecs.
Something like "::tracking" (and we cold also have "::matching",
"::current" and so on for completeness)
But that would lose the possibility to use wildcards.
Before going on, can you explain your use case for --push=tracking (in a
case where --push=current wouldn't do the same)?
quoted
4) in 1.6.4 or 1.7.0, make "git push" fail outright if there is no push
line, with text suggesting [...]
Hopefully we can get to this stage, that a unconfigured "git push"
gives a small message, indicating how to configure it, and not push
anything. Most "oldtimers" should have configured this already, so it
should not break many setups.
Agreed. Possibly with a "git remote" command to add a push refspec.
Paolo
From: Finn Arne Gangstad <hidden> Date: 2016-06-15 22:46:59
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
Before going on, can you explain your use case for --push=tracking (in a
case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
E.g. some remotes have only a single active branch called "master",
and you have to name it something else locally, or several people have
local branches called "beta", and you have to name it something like
"fred-beta" locally if you are working on fred's beta.
- Finn Arne
From: Andreas Ericsson <hidden> Date: 2016-06-15 22:46:59
Finn Arne Gangstad wrote:
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
quoted
Before going on, can you explain your use case for --push=tracking (in a
case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
E.g. some remotes have only a single active branch called "master",
and you have to name it something else locally, or several people have
local branches called "beta", and you have to name it something like
"fred-beta" locally if you are working on fred's beta.
Umm. Why not name it after the feature you're working on instead of the
branch you started from? That way, you get fred/beta (assuming you've
added Fred's repo as a remote named "fred" ofcourse) and all your
branches have names that never (in theory) clash with any of your
upstreams.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
From: Paolo Bonzini <hidden> Date: 2016-06-15 22:46:59
Finn Arne Gangstad wrote:
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
quoted
Before going on, can you explain your use case for --push=tracking (in a
case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
Yes, but when using multiple remotes is it really common that:
1) I have the permission to push to them (as opposed to sending a pull
request)? If I have permission to push only to the mob branch, for
example, I would still set my tracking branch to the master branch.
2) I *do* want to push to them often? If I use tracking for my topic
branches, push.default=tracking seems a sure way to big mess when I do
"git push" on the wrong branch. Instead, with push.default=current "git
push" would just tell me "new branch created" and then I can do "git
push branch-name:" to delete the newly created branch.
I don't remember who it was, but when I tried changing the behavior for
"git push" someone screamed loudly that fetching and pushing are two
different things, and making things work uniformly across the two is not
necessarily correct. The details probably were different, but I think
that I am saying the same now.
Paolo
From: Finn Arne Gangstad <hidden> Date: 2016-06-15 22:46:59
On Tue, Jun 23, 2009 at 03:21:06PM +0200, Andreas Ericsson wrote:
Finn Arne Gangstad wrote:
quoted
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
quoted
Before going on, can you explain your use case for --push=tracking
(in a case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
E.g. some remotes have only a single active branch called "master",
and you have to name it something else locally, or several people have
local branches called "beta", and you have to name it something like
"fred-beta" locally if you are working on fred's beta.
Umm. Why not name it after the feature you're working on instead of the
branch you started from? That way, you get fred/beta (assuming you've
added Fred's repo as a remote named "fred" ofcourse) and all your
branches have names that never (in theory) clash with any of your
upstreams.
Maybe I misunderstand what you are saying, but: The point is that you
can not name it the same as on the remote. So the names are different,
and --current will not work.
- Finn Arne
From: Andreas Ericsson <hidden> Date: 2016-06-15 22:46:59
Finn Arne Gangstad wrote:
On Tue, Jun 23, 2009 at 03:21:06PM +0200, Andreas Ericsson wrote:
quoted
Finn Arne Gangstad wrote:
quoted
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
quoted
Before going on, can you explain your use case for --push=tracking
(in a case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
E.g. some remotes have only a single active branch called "master",
and you have to name it something else locally, or several people have
local branches called "beta", and you have to name it something like
"fred-beta" locally if you are working on fred's beta.
Umm. Why not name it after the feature you're working on instead of the
branch you started from? That way, you get fred/beta (assuming you've
added Fred's repo as a remote named "fred" ofcourse) and all your
branches have names that never (in theory) clash with any of your
upstreams.
Maybe I misunderstand what you are saying, but: The point is that you
can not name it the same as on the remote. So the names are different,
and --current will not work.
I think our workflows differ quite drastically, as I very rarely see
the need to push more than one branch. When I do, it's for repositories
where I'm the ultimate upstream, so I only have one remote that I
actually *can* push to at all.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
From: Finn Arne Gangstad <hidden> Date: 2016-06-15 22:46:59
On Tue, Jun 23, 2009 at 03:28:04PM +0200, Paolo Bonzini wrote:
Finn Arne Gangstad wrote:
quoted
On Tue, Jun 23, 2009 at 02:59:10PM +0200, Paolo Bonzini wrote:
[...]
quoted
Before going on, can you explain your use case for --push=tracking
(in a case where --push=current wouldn't do the same)?
The idea with "tracking" is to push the current branch to wherever it
would pull from, making push & pull "equivalent" in some sense.
This is different from "current" if you have/choose to name the local
branch something else than the remote branch. This happens a lot when
using multiple remotes.
Yes, but when using multiple remotes is it really common that:
1) I have the permission to push to them (as opposed to sending a pull
request)? If I have permission to push only to the mob branch, for
example, I would still set my tracking branch to the master branch.
I don't know how common it is, but it is certainly not unheard of. You
have a shared public server, and a group-shared public server and so
on. You only need a single shared public server for this to make sense
however.
2) I *do* want to push to them often? If I use tracking for my topic
branches, push.default=tracking seems a sure way to big mess when I do
"git push" on the wrong branch.
In our shared repositories, we have a few protected branches that only
integrators can push to, so no one else can accidentally push to
them. These are typically the branches that it makes sense to track
"by default".
If a group sets up a shared public branch, it is typically for
working together on some feature. There are very few surprises if
the group works like this:
1. Do some modifications
2. git commit
3. git pull [--rebase]
4. git push
5. goto 1 ..
For people used to CVS, this is a nice way to start working with git.
It requires --tracking to work properly though (--current only works
if you remember to use the same branch name).
Instead, with push.default=current "git
push" would just tell me "new branch created" and then I can do "git
push branch-name:" to delete the newly created branch.
Well, you need to add the name of the remote. And while not exactly
impossible to find, for the target audience it may be a bit more
cumbersome than it should be:
branch: git symbolic-ref HEAD | sed -e s=refs/heads/==
remote: git config branch.<branch>.remote
And if you want to figure out what the branch you pulled from is
named, you have to do something like
git config branch.<branch>.merge | sed -e s=refs/heads/==
I don't remember who it was, but when I tried changing the behavior for
"git push" someone screamed loudly that fetching and pushing are two
different things, and making things work uniformly across the two is not
necessarily correct. The details probably were different, but I think
that I am saying the same now.
Different use cases want different things from push. If you are the top
level integrator of a project and are trying to keep 3 remotes in sync
with your master repository, "matching" seems to be what you want.
If you are a leaf-node worker pushing to a public repository, it
isn't. But --tracking may be a valid choice sometimes (and is, in some
sense, very close to SCMs people may be used to).
- Finn Arne
From: Paolo Bonzini <hidden> Date: 2016-06-15 22:46:59
quoted
1) I have the permission to push to them (as opposed to sending a pull
request)? If I have permission to push only to the mob branch, for
example, I would still set my tracking branch to the master branch.
2) I *do* want to push to them often? If I use tracking for my topic
branches, push.default=tracking seems a sure way to big mess when I do
"git push" on the wrong branch.
In our shared repositories, we have a few protected branches that only
integrators can push to, so no one else can accidentally push to
them. These are typically the branches that it makes sense to track
"by default".
Yes, on the other hand you cannot push to them, so talking about them
in the context if push.default is moot. :-)
If a group sets up a shared public branch, it is typically for
working together on some feature.
For people used to CVS, this is a nice way to start working with git.
It requires --tracking to work properly though (--current only works
if you remember to use the same branch name).
Ok, this *is* a usecase. Your local branch is named as a feature but
it pushes into master. Thanks, I have something to reason about now.
:-)
Paolo