Re: [1.8.0] Provide proper remote ref namespaces

From: Johan Herland <hidden>
Date: 2016-06-15 22:50:31

(resend without HTML part; I apologize for the inconvenience)

On Monday 07 February 2011, Dmitry Potapov wrote:
On Sun, Feb 06, 2011 at 11:12:51PM +0100, Johan Herland wrote:
There are two sorts of tags:
- local tags, which are never intended to be shared with others but used
  by users to mark some points in the working repository.
- global tags, which are just _social_convention_ about what the current
  project considers as official versions. Without social convention, they
  make no sense.
Agreed.
quoted
The core of this discussion is where we want to place Git in the space
between "technically correct" and "socially conventional", where the
former means owning up to the fact that each repo really is its own
namespace, and there's no way around that in a proper DVCS, and the
latter means building social convention into our tools, thereby making
it harder to deal with the few unconventional cases (like my two
semi-related repos case).
Tags like words are social convention, which are used for communication
between people participated in a project. But accordingly to you, it
seems somehow "technically correct" to invent their own words in Humpty
Dumpty's ways:

'When I use a word,' Humpty Dumpty said, in rather a scornful tone, 'it
means just what I choose it to mean — neither more nor less.'

I am afraid you got the wrong idea about "proper DVCS", because DVCS
does not imply that there is no social convention. It just means that
there is no single authority that dictates everything. Like with words,
there is no single authority that assigns meaning to new words, but
that does not mean that you cannot just say "When I use a word... "
if you want to be understood by others.
I think there is a misunderstanding in my use of the phrase "technically 
correct". I use it to merely state what is a theoretical truth: In a DVCS 
world there is no single authority that dictates the meaning of a tag name.

I do not mean that "technically correct" is inherently _better_ than the 
alternative (maybe "theoretically true" is a better phrase). I certainly do 
NOT mean that the Humpty Dumpty approach is somehow more desirable than 
following project conventions. To the contrary, I very much _support_ the 
idea of project-wide tags. I'm merely stating that the technical facts of a 
DVCS makes it _theoretically_ impossible to enforce project-wide agreement 
on tag names.

Of course, in _practice_ we use project-wide tags without problems all the 
time. And they obviously form a _semantic_ namespace that spans the entire 
project. I don't disagree with you here.

Where we disagree is whether Git should base its tag refs on the 
_theoretically_true_ model, or on the _common_practice_ model. Of course, 
the real solution lies somewhere in between the two extremes:

I propose that even though we base Git on the theoretical DVCS truths, we 
try very hard to make it Just Work (tm) in the common case (especially 
making sure that existing use cases are preserved as much as possible).

As I understand your view (I do apologize if I somehow misrepresent it), you 
want Git to assume that the common practice of one semantic namespace is 
followed. Furthermore, you also want to enforce that practice where 
possible, while still improving the handling of the uncommon (but 
theoretically inevitable) case (warning and presumably guiding the user when 
a tag conflict occurs).
quoted
AFAICS, my proposal does not harm the common case (unambiguous tags are
still interpreted unambiguously, even if they may exist in multiple
namespaces), while it _does_ help the uncommon case (by allowing
ambiguous tags to co-exist in the same repo).
It hurts the common case in a few ways:
1. It breaks existing user scripts
Yes, but that was sort of in the pretext of this thread ;)

Seriously, though, we should of course try to keep as many scripts as 
possible working smoothly. For instance, existing remotes will not be 
updated, so everything should keep working for them. It shall also be 
possible to use old-style refspecs when creating new remotes, meaning that 
whatever scripts depend on the old-style refspecs can be upgraded at 
leisure. We could even add a config variable choosing between old-style 
(default) and new-style refspecs.

With this in place, I believe the user script breakage will be minimal. If 
there is still significant breakage, we should reconsider the relevant part 
of the proposal.
2. It complicates things for users (as Matthieu wrote above).
I guess this depends on your POV. Fundamentally, I do NOT want to change how 
people refer to tags. I only want to provide them the possibility of doing 
so when ambiguity is present.
3. git fetch cannot report a tag clash if it happens
Yes it can: For each tag fetched from the remote, if resolving its shorthand 
name ("v1.7.4") results in ambiguity (i.e. there exists a conflicting tag 
elsewhere in this repo), then warn the user about this conflict, and explain 
how to refer to each tag candidate using the full ref name. Also explain how 
the user may resolve the ambiguity by creating a local tag 
("refs/tags/v1.7.4") pointing to the preferred target.
I believe that the right interface when the common case is simple, but
an uncommon case is still possible to handle. I don't think that
currently git meets this criterion, but making tag namespaces based on
the remote name strikes me as a really bad idea. Tags are attributes of
a project and not particular remote.
Yes they are (in pratice), and no they aren't (in theory). See above.
quoted
My proposal tries very hard to present a single namespace
_semantically_ to the user in the common case (when tags are
unambiguous). I'd even go as far as proposing that "git tag -l" should
by default list only a single shortened tag name in the cases where
there are multiple unambiguous alternatives.
IMHO, it is very confusing, especially for people whose script was
suddenly broken by those namespaces.
I believe script breakage can be minimized. See above.
quoted
Alternatively, I'd suggest a compromise (already mentioned elsewhere in
this thread) where we add a config variable tags.preferredRemote
(defaults to "origin") which allows you to directly select which
namespace you consider official. You could even implement this as
physically copying
refs/remotes/${tag.preferredRemote}/tags/* into refs/tags/*.
It seems you do not understand the problem that I am trying to say all
way along: there is more than one repo from which I fetch tags, and
because they are belong to the same project, they should be in the same
namespace.

So, IMHO, the proper solution should be ability to specify the desired
namespace for any remote repository, like this:

remote.<name>.tagNameSpace = foo
Interesting. I'm not sure what "foo" means in this context. Would I use it 
like this?:

    remote.origin.tagNameSpace = refs/tags

(to place origin's tags in refs/tags/*)

If so, what's the difference between this option, and using this?:

    remote.origin.fetch = refs/tags/*:refs/tags/*
So, those who want to have many namespaces should be able to that
easily, but forcing multiple namespaces on those who have a single
namespace semantically is simple wrong. Not to mention that it breaks
existing scripts for no good reason.
In practice, this discussion boils down to whether we should use

    remote.origin.fetch = refs/tags/*:refs/remotes/origin/tags/*
or
    remote.origin.fetch = refs/tags/*:refs/tags/*

as the default refspec for tags. AFAICS, we both agree that whichever 
refspec is chosen by default, it should be possible for the user to (fairly 
easily) override, and use the other refspec instead.

With that, my main concern about this part of the proposal is satisfied: 
Putting remote tags in separate namespaces will be easy to accomplish (if 
not the default behavior).


Thanks for the feedback,

...Johan


PS: I'd be interested if you have a suggestion for how to deal with the 
issue presented by Nicolas' elsewhere in this thread. Quoting:

The extraordinary misfeature of the tag namespace at the moment comes 
from the fact that whenever you add a remote repo to fetch, and do fetch 
it, then your flat tag namespace gets polluted with all the tags the 
remote might have.  If you decide to delete some of those remote 
branches, the tags that came with it are still there and 
indistinguishable from other tags making it a real pain to sort out.

-- 
Johan Herland, [off-list ref]
www.herland.net
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help