From: Junio C Hamano <hidden> Date: 2016-06-15 22:42:22
Pavel Roskin [off-list ref] writes:
This is not a ready-to-use proposal, but I think my message can prompt
useful changes in GIT or in the "porcelain".
...
I think it would be convenient to have git remember the remote branch
for the given local branch. git should know that if HEAD points to
"local-B", "git-fetch" should fetch from "remote-B", not from "origin".
I am in favor of the general direction this is going. Something
like this was mentioned on the list in the past twice (I think
Johannes was involved in the discussion but I do not remember
the details offhand).
My understanding is that Cogito uses $GIT_DIR/branches/$name
file as a configuration file per branch - currently it only
records which remote repository's what remote branch the local
branch $name interfaces with.
The $GIT_DIR/remotes/$name file is to describe each remote
repository, and it _wants_ to be able to describe all the
branches we are interested in, primarily because uploading and
downloading multiple, related heads at once is more efficient.
How remote branches are kept track of with the local tracking
branch, and how remote branches are updated from the local
branch heads, are described by Push/Pull lines there.
As you pointed out, we do not have a convenient way to tell git
where you typically merge things from per local branch. There
are different patterns I've seen:
- Promiscous. For example, "master" branch of Linus repository
pulls from many subsystem maintainers. Linus could have one
"remotes" file per subsystem maintainer he often pulls from
(and "for-linus" branch name in each remote repository tends
to stay the same), and unlike the rest of us he does not seem
to pull into many local branches. The current "remotes"
setup is really optimized for this mode of usage (you can use
"remotes" without having local tracking branches).
- Merging topic branches into "master" (or "release") branch
and "next" (or "testing") branch -- inside local repository.
- CVS-like remote tracking. A single "primary" remote branch
is tracked using local "origin", merged into local "master"
and pushed back to the remote. Both Cogito-like branches/
setup and having a single $GIT_DIR/remotes/origin file with
single Push/Pull line would work equally well.
- Multiple subsystem maintainer trees tracked in the same local
repository. Most generally, two local branches per each
remote head can be used (one tracking branch to fetch into,
another to build your changes based on it). Alternatively,
you can use one local branch per each remote head without
using any tracking branch.
Your proposal to give default branch to pull from per the local
branch would help only the last case. The first one you do not
switch between local branches at all and pull from many
different places; the second is to merge from different topic
branches from time to time and does not benefit from fixed
configuration; the third does not even need configuration.
Maybe you would want something like this.
In $GIT_DIR/config:
[pull]
origin = linus for master
origin = irq-pio of libata for ata-irq-pio
origin = pata-drivers of libata for ata-pata
In $GIT_DIR/remotes/linus:
URL: git://git.kernel.org/.../torvalds/linux-2.6.git
Pull: refs/heads/master:refs/heads/linus
In $GIT_DIR/remotes/libata
URL: git://git.kernel.org/.../jgarzik/libata-dev.git
Pull: refs/heads/irq-pio:refs/remotes/libata/irq-pio
Pull: refs/heads/pata-drivers:refs/remotes/libata/pata-drivers
This is to maintain three local branches: master, ata-irq-pio
and ata-pata.
You are obviously interested in the mainline Linus kernel, so
while you are on your "master" branch, we will look for
"pull.origin .* for master" and find out you would want
remotes/linus file to be used. His "master" is copied to your
local "linus" branch, and merged into your "master" branch.
$ git pull
becomes equivalent to:
$ git pull linus
You are also interested in the libata work by Jeff, and while
you are on your ata-pata branch
$ git pull
becomes roughly equivalent to:
$ git pull libata pata-drivers
While we are on the topic, it _might_ be worthwhile to think
about revamping the syntax of $GIT_DIR/remotes file, maybe even
breaking backward compatibility. The Pull: lines can be
independently specified which gives flexibility, but I suspect
local tracking branches from the same remote tend to live in the
same place; IOW, you would probably not do something like:
URL: git://git.kernel.org/.../jgarzik/libata-dev.git
Pull: refs/heads/irq-pio:refs/remotes/libata/irq-pio
Pull: refs/heads/pata-drivers:refs/heads/pata-drivers
in practice.
From: Pavel Roskin <hidden> Date: 2016-06-15 22:42:22
Hello, Junio!
On Fri, 2006-03-31 at 19:05 -0800, Junio C Hamano wrote:
- Multiple subsystem maintainer trees tracked in the same local
repository. Most generally, two local branches per each
remote head can be used (one tracking branch to fetch into,
another to build your changes based on it). Alternatively,
you can use one local branch per each remote head without
using any tracking branch.
Your proposal to give default branch to pull from per the local
branch would help only the last case.
Exactly. I tried to track the main Linus repository and Jeff Garzik's
netdev in one place. Then I discovered that my repository if full of
unintended merges made by "stg pull".
The first one you do not
switch between local branches at all and pull from many
different places; the second is to merge from different topic
branches from time to time and does not benefit from fixed
configuration; the third does not even need configuration.
Maybe you would want something like this.
In $GIT_DIR/config:
[pull]
origin = linus for master
origin = irq-pio of libata for ata-irq-pio
origin = pata-drivers of libata for ata-pata
First of all, using "origin" on every line carries to little
information.
Secondly, I think the relationship should be between a local development
branch and a local tracking branch. After all, all remote data is
placed on a local tracking branch first. It's better not to jump over
layers of abstraction. Suppose I want to update "masterB". I tell git
to sync "originB" first. git already has rules what to do if it should
sync "originB". Let's not supersede those rules.
I would write the config like this:
[branch-upstream]
master = linus
ata-irq-pio = irq-pio
ata-pata = pata-drivers
While we are on the topic, it _might_ be worthwhile to think
about revamping the syntax of $GIT_DIR/remotes file, maybe even
breaking backward compatibility. The Pull: lines can be
independently specified which gives flexibility, but I suspect
local tracking branches from the same remote tend to live in the
same place; IOW, you would probably not do something like:
URL: git://git.kernel.org/.../jgarzik/libata-dev.git
Pull: refs/heads/irq-pio:refs/remotes/libata/irq-pio
Pull: refs/heads/pata-drivers:refs/heads/pata-drivers
in practice.
Sorry, I don't understand this part.
--
Regards,
Pavel Roskin
From: Josef Weidendorfer <hidden> Date: 2016-06-15 22:42:22
On Saturday 01 April 2006 06:18, Pavel Roskin wrote:
On Fri, 2006-03-31 at 19:05 -0800, Junio C Hamano wrote:
quoted
Maybe you would want something like this.
In $GIT_DIR/config:
[pull]
origin = linus for master
origin = irq-pio of libata for ata-irq-pio
origin = pata-drivers of libata for ata-pata
Let me try to understand this: the general idea is that
pull.origin = [<refspec> of] <remote> for <branch>
specifies the default action of git-pull if we are on <branch>, ie.
a "git pull" then runs "git pull <remote> [<refspec>]".
So the example above, if .git/remotes/linus would contain two
refspecs, and you are on the branch of the 2nd refspec, it would
do the wrong thing: merge the 1st refspec with current branch.
So I think this is not useful, and if we use above syntax, we
should make the refspec mandatory.
However. I think a syntax mentioning only 2 local branches is better:
pull.origin = <local upstream for branch> for <branch>
Perhaps I have misunderstood the proposal?
First of all, using "origin" on every line carries to little
information.
"origin" is part of the case-insensitive alphanum key, which is the same
for all config values in Junio's proposal. Especially, you can
not use it for head names. So this is fine.
Perhaps we could make a shorther alternative form for the above where
the key part has not to be specified on every line with a rule like
if the line does not match /^\S+="/, the full line is the value
Then, above could be written as
[pull.origin]
linus for master
irq-pio of libata for ata-irq-pio
pata-drivers of libata for ata-pata
However, that's only syntactical sugar.
Secondly, I think the relationship should be between a local development
branch and a local tracking branch.
Agree.
It is also useful to specify this relation if the upstream is purely a
local branch, e.g. when branching off a local branch, and you want to
pull in changes from the local upstream.
This works automatically if git-pull only does upstream fetching if
there is a remote branch associated. The default action of git-fetch
similar could be "fetch the upstream branch, if that tracks a remote
branch", using the same configuration.
After all, all remote data is
placed on a local tracking branch first. It's better not to jump over
layers of abstraction. Suppose I want to update "masterB". I tell git
to sync "originB" first. git already has rules what to do if it should
sync "originB". Let's not supersede those rules.
Junio's proposal has the advantage that you do not have to search in all
files in .git/remotes (and even .git/branches) for the remote branch that
maps to a given local branch.
But that is not the big issue.
I would write the config like this:
[branch-upstream]
master = linus
ata-irq-pio = irq-pio
ata-pata = pata-drivers
That is not working, as said above. But with above syntax extension,
with s/=/for/ it would be fine.
It would be nice to also support the topic branches, ie. to be able
to specify all topic branches for a branch, and make "git-pull" default
to an octopus merge of the topic branches.
However, "git-pull" can not distinguish between "merge upstream" and
"merge topic branches". Yet, specifying multiple default branches should
be possible.
quoted
While we are on the topic, it _might_ be worthwhile to think
about revamping the syntax of $GIT_DIR/remotes file, maybe even
breaking backward compatibility. The Pull: lines can be
independently specified which gives flexibility, but I suspect
local tracking branches from the same remote tend to live in the
same place; IOW, you would probably not do something like:
URL: git://git.kernel.org/.../jgarzik/libata-dev.git
Pull: refs/heads/irq-pio:refs/remotes/libata/irq-pio
Pull: refs/heads/pata-drivers:refs/heads/pata-drivers
in practice.
What is the idea instead?
I think the current syntax is fine, as it is very flexible.
The reasoning about tracking remote branches in the same place
is a porcelain issue to be set up by git-clone.
Perhaps you are missing a remotes editor command?
Josef
From: Petr Baudis <hidden> Date: 2016-06-15 22:42:23
Dear diary, on Sun, Apr 02, 2006 at 06:17:29PM CEST, I got a letter
where Josef Weidendorfer [off-list ref] said that...
quoted
I would write the config like this:
[branch-upstream]
master = linus
ata-irq-pio = irq-pio
ata-pata = pata-drivers
That is not working, as said above. But with above syntax extension,
with s/=/for/ it would be fine.
I'm sorry but I'm slow and I don't see it - why wouldn't this work?
(Except that the key name is case insensitive, which isn't too big a
deal IMHO.)
I for one think that the 'for'-syntax is insane - it's unreadable (your
primary query is by far most likely to be "what's the upstream when on
branch X", not "what branches is this upstream for"), would convolute
the configuration file syntax unnecessarily and would possibly also
complicate the git-repo-config interface. Pavel's syntax is much nicer.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Right now I am having amnesia and deja-vu at the same time. I think
I have forgotten this before.
From: Josef Weidendorfer <hidden> Date: 2016-06-15 22:42:23
On Friday 14 April 2006 18:16, you wrote:
Dear diary, on Sun, Apr 02, 2006 at 06:17:29PM CEST, I got a letter
where Josef Weidendorfer [off-list ref] said that...
quoted
quoted
I would write the config like this:
[branch-upstream]
master = linus
ata-irq-pio = irq-pio
ata-pata = pata-drivers
That is not working, as said above. But with above syntax extension,
with s/=/for/ it would be fine.
I'm sorry but I'm slow and I don't see it - why wouldn't this work?
(Except that the key name is case insensitive, which isn't too big a
deal IMHO.)
Hmm...
* IMHO "keys are case insensitive" is enough to not qualify for branch
names: currently, branch names are case sensitive, and with above syntax you
effectively change this rule (you can not distinguish upstreams for "master"
vs. "MASTER").
* a dot currently seems to be allowed in branch names. For config keys, the
dot separates subkeys.
* I thought it is a convention for config keys to be alphanum only,
eg. "/" isn't allowed, too (which is mandatory for branch names).
Unfortunately, I found nothing about allowed chars for config keys in the
documentation.
I for one think that the 'for'-syntax is insane - it's unreadable (your
primary query is by far most likely to be "what's the upstream when on
branch X", not "what branches is this upstream for"), would convolute
the configuration file syntax unnecessarily and would possibly also
complicate the git-repo-config interface.
As far as I remember, the "... for ..." syntax was suggested by Linus for the
proxy.command config a long time ago. The original proposal there was to
use an URL as key part (as far as I can remember).
That said,
Pavel's syntax is much nicer.
... I agree with you here.
My suggestion would be to allow an optional syntax in the config file which is mapped
by git-repo-config to the normalized "... for ..."-scheme.
Eg. it should not be mandatory to specify "for ..." after the value of a key.
So instead of
branch.upstream = linus for master
you should be able to say
[branch]
upstream for master = linus
Josef