Johan Herland [off-list ref] writes:
Let me try to summarize my views on how refnames should work in Git, to
see if we can identify where we differ on the principles (or if we, in
fact, differ at all):
Thanks; I think I already said where I think we differ in a separate
message, but a short version is that the point of remote.$nick.fetch
mapping is to solve "The remote may call a ref $this, which is not
the refname I want to or can use in my repository, so here is the
rule to use when importing it in my local namespace. With the
mapping, I can name the ref in my local namespace conveniently."
E.g. their "refs/heads/master" cannot be our "refs/heads/master" at
the same time, so use "refs/heads/origin/master".
The result of the above mapping, be it remotes/origin/master or
remotes/origin/heads/master, should be designed to be useful for the
local use of the ref in question. If you further need to remap it
when using it locally, there is something wrong in the mapping you
defined in your remote.$nick.fetch mapping in the first place.
We do not force any structure under refs/remotes/; it is left
entirely up to the user, even though we would like to suggest the
best current practice by teaching "clone" and "remote add" to lay
them out in a certain way.
Another thing is that refs/remotes/ is not special at all. If notes
hierarchies taken from a remote need to be somewhere other than
refs/notes/, it is perfectly fine to introduce refs/remote-notes/ if
that is the best layout when using them locally. What is special is
refs/heads/ in that they are the _only_ refs you can check out to
the working tree and directly advance them by working on the working
tree files.
I would support disallowing multi-level remote names, although I don't
know if it is commonly used, and would break many existing users.
I somewhat doubt it.
We very much anticipated the use of multi-level branch names from
the very beginning and have support (e.g. in "for-each-ref" and
"branch --list") to group/filter them according to prefixes, but I
do not think there is anywhere we consciously try to give support
for multi-level remote names to treat groups of remotes that share
the same prefix.
quoted
*2* Perhaps "bar" in the above is spelled "topics", and the
hierarchy may be used to collect non-integration single topic
branches from more than one remote. An example that is more in
line with such a usage might be:
[remote "jh"]
fetch = +refs/heads/*:refs/remotes/topics/heads/jh/*
[remote "jk"]
fetch = +refs/heads/*:refs/remotes/topics/heads/jk/*
[remote "fc"]
fetch = +refs/heads/*:refs/remotes/topics/heads/fc/*
and I would expect "git merge topics/jh/rbranch" to merge the
"refs/remotes/topics/heads/jh/rbranch" topic branch.
I like the use case, but not necessarily your expectation. ;-)
With the above configuration, and my series as-is, you could simply do
"git merge jh/rbranch" to merge the "refs/remotes/topics/heads/jh/rbranch"
topic branch.
That dropping of 'topics/' is the issue. The user wanted to group
them under 'topics/' hierarchy and made a conscous effort to set up
the fetch refspec to map these refs there. These are done all for
convenience when she deals with refs in her namespace in the
repository. What justification do we have to second guess the user
and force her to drop it when naming these refs?
Furthermore, I don't see why you want/need the extra
"heads/" level in the refspec.
Just like you wanted to have separate kinds of refs under a single
remote, the layout is grouping kinds of refs other than branch heads
related to the "topics" (as opposed to "integration branches").
On Mon, May 6, 2013 at 7:06 PM, Junio C Hamano [off-list ref] wrote:
Johan Herland [off-list ref] writes:
quoted
Let me try to summarize my views on how refnames should work in Git, to
see if we can identify where we differ on the principles (or if we, in
fact, differ at all):
Thanks; I think I already said where I think we differ in a separate
message, but a short version is that the point of remote.$nick.fetch
mapping is to solve "The remote may call a ref $this, which is not
the refname I want to or can use in my repository, so here is the
rule to use when importing it in my local namespace. With the
mapping, I can name the ref in my local namespace conveniently."
E.g. their "refs/heads/master" cannot be our "refs/heads/master" at
the same time, so use "refs/remotes/origin/master".
The result of the above mapping, be it remotes/origin/master or
remotes/origin/heads/master, should be designed to be useful for the
local use of the ref in question. If you further need to remap it
when using it locally, there is something wrong in the mapping you
defined in your remote.$nick.fetch mapping in the first place.
Ok, so whereas I consider the refspec to be "king", and that the expansion
from convenient shorthands to full remote-tracking refnames should be
derived from the chosen refspec, you would (if I understand you correctly)
rather have a constant (i.e. independent of remotes and refspecs) set of
rules for expanding shorthands to full refnames, and if the user chooses
refspecs that don't mesh well with those rules, then that is the user's
problem, and not Git's.
We do not force any structure under refs/remotes/; it is left
entirely up to the user, even though we would like to suggest the
best current practice by teaching "clone" and "remote add" to lay
them out in a certain way.
If we were to suggest +refs/heads/*:refs/remotes/origin/heads/* as the
best practice, I assume you do want "origin/master" to keep working. And
since you do not want to use the configured refspec when expanding
"origin/master" into "refs/remotes/origin/heads/master", then I assume
you would rather add a hardcoded (what I call a "textual expansion" in
my patches) rule that would map "$nick/$name" into
/refs/remotes/$nick/heads/$name
But isn't the existence of such a rule evidence of us trying to impose
(or at least hint) at a certain structure for refs/remotes/*?
In light of this, I'm interested in your thoughts about the following
related problem that I've just started looking at:
git branch -r shows the remote-tracking branches in this repo. Currently,
AFAICS, this just spits out all refs under refs/remotes/*. This behavior
must clearly be modified if we are to allow remote-tracking tags at
refs/remotes/$remote/tags/* (they currently show up in "git branch -r",
but shouldn't). One could say that the filter should merely change from
refs/remotes/* to refs/remotes/*/heads/*, but this would break for
existing (old-style) remotes. Should we add a heuristic for detecting when
to use refs/remotes/* vs. refs/remotes/*/heads/* as a filter?
My approach would be to iterate through the configured remotes, and for
each remote list all refs that match the RHS of the refspec whose LHS is
refs/heads/*. This would work for both old- and new-style remotes with
no heuristics.
If you agree that my approach is correct for enumerating remote-tracking
branches, then what is different about using the refspec when expanding
remote-tracking refs in general?
In other words, given the following configuration:
[remote "origin"]
+refs/heads/*:refs/foo/bar/baz/*
[remote "foo"]
+refs/heads/*:refs/remotes/origin/heads/*
1. In your opininon, is refs/foo/bar/baz/master a remote-tracking branch?
2. Should refs/foo/bar/baz/master be listed by "git branch -r"?
3. Should the "origin/master" shorthand notation expand to
refs/remotes/origin/heads/master from remote foo, or
refs/foo/bar/baz/master from remote origin?
...Johan
--
Johan Herland, [off-list ref]
www.herland.net