{"thread":{"id":"26432","subject":"Re: [1.8.0] Provide proper remote ref namespaces","startedAt":"2011-02-07T03:35:31Z","lastAt":"2011-02-07T03:35:31Z","messageCount":1,"participants":["Johan Herland"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"160572","messageId":"201102070435.31674.johan@herland.net","threadId":"26432","inReplyTo":null,"subject":"Re: [1.8.0] Provide proper remote ref namespaces","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2011-02-07T03:35:31Z","receivedAt":"2011-02-07T03:35:31Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"(resend without HTML part; I apologize for the inconvenience)\n\nOn Monday 07 February 2011, Dmitry Potapov wrote:\n> On Sun, Feb 06, 2011 at 11:12:51PM +0100, Johan Herland wrote:\n> There are two sorts of tags:\n> - local tags, which are never intended to be shared with others but used\n>   by users to mark some points in the working repository.\n> - global tags, which are just _social_convention_ about what the current\n>   project considers as official versions. Without social convention, they\n>   make no sense.\n\nAgreed.\n\n> > The core of this discussion is where we want to place Git in the space\n> > between \"technically correct\" and \"socially conventional\", where the\n> > former means owning up to the fact that each repo really is its own\n> > namespace, and there's no way around that in a proper DVCS, and the\n> > latter means building social convention into our tools, thereby making\n> > it harder to deal with the few unconventional cases (like my two\n> > semi-related repos case).\n> \n> Tags like words are social convention, which are used for communication\n> between people participated in a project. But accordingly to you, it\n> seems somehow \"technically correct\" to invent their own words in Humpty\n> Dumpty's ways:\n> \n> 'When I use a word,' Humpty Dumpty said, in rather a scornful tone, 'it\n> means just what I choose it to mean — neither more nor less.'\n> \n> I am afraid you got the wrong idea about \"proper DVCS\", because DVCS\n> does not imply that there is no social convention. It just means that\n> there is no single authority that dictates everything. Like with words,\n> there is no single authority that assigns meaning to new words, but\n> that does not mean that you cannot just say \"When I use a word... \"\n> if you want to be understood by others.\n\nI think there is a misunderstanding in my use of the phrase \"technically \ncorrect\". I use it to merely state what is a theoretical truth: In a DVCS \nworld there is no single authority that dictates the meaning of a tag name.\n\nI do not mean that \"technically correct\" is inherently _better_ than the \nalternative (maybe \"theoretically true\" is a better phrase). I certainly do \nNOT mean that the Humpty Dumpty approach is somehow more desirable than \nfollowing project conventions. To the contrary, I very much _support_ the \nidea of project-wide tags. I'm merely stating that the technical facts of a \nDVCS makes it _theoretically_ impossible to enforce project-wide agreement \non tag names.\n\nOf course, in _practice_ we use project-wide tags without problems all the \ntime. And they obviously form a _semantic_ namespace that spans the entire \nproject. I don't disagree with you here.\n\nWhere we disagree is whether Git should base its tag refs on the \n_theoretically_true_ model, or on the _common_practice_ model. Of course, \nthe real solution lies somewhere in between the two extremes:\n\nI propose that even though we base Git on the theoretical DVCS truths, we \ntry very hard to make it Just Work (tm) in the common case (especially \nmaking sure that existing use cases are preserved as much as possible).\n\nAs I understand your view (I do apologize if I somehow misrepresent it), you \nwant Git to assume that the common practice of one semantic namespace is \nfollowed. Furthermore, you also want to enforce that practice where \npossible, while still improving the handling of the uncommon (but \ntheoretically inevitable) case (warning and presumably guiding the user when \na tag conflict occurs).\n\n> > AFAICS, my proposal does not harm the common case (unambiguous tags are\n> > still interpreted unambiguously, even if they may exist in multiple\n> > namespaces), while it _does_ help the uncommon case (by allowing\n> > ambiguous tags to co-exist in the same repo).\n> \n> It hurts the common case in a few ways:\n> 1. It breaks existing user scripts\n\nYes, but that was sort of in the pretext of this thread ;)\n\nSeriously, though, we should of course try to keep as many scripts as \npossible working smoothly. For instance, existing remotes will not be \nupdated, so everything should keep working for them. It shall also be \npossible to use old-style refspecs when creating new remotes, meaning that \nwhatever scripts depend on the old-style refspecs can be upgraded at \nleisure. We could even add a config variable choosing between old-style \n(default) and new-style refspecs.\n\nWith this in place, I believe the user script breakage will be minimal. If \nthere is still significant breakage, we should reconsider the relevant part \nof the proposal.\n\n> 2. It complicates things for users (as Matthieu wrote above).\n\nI guess this depends on your POV. Fundamentally, I do NOT want to change how \npeople refer to tags. I only want to provide them the possibility of doing \nso when ambiguity is present.\n\n> 3. git fetch cannot report a tag clash if it happens\n\nYes it can: For each tag fetched from the remote, if resolving its shorthand \nname (\"v1.7.4\") results in ambiguity (i.e. there exists a conflicting tag \nelsewhere in this repo), then warn the user about this conflict, and explain \nhow to refer to each tag candidate using the full ref name. Also explain how \nthe user may resolve the ambiguity by creating a local tag \n(\"refs/tags/v1.7.4\") pointing to the preferred target.\n\n> I believe that the right interface when the common case is simple, but\n> an uncommon case is still possible to handle. I don't think that\n> currently git meets this criterion, but making tag namespaces based on\n> the remote name strikes me as a really bad idea. Tags are attributes of\n> a project and not particular remote.\n\nYes they are (in pratice), and no they aren't (in theory). See above.\n\n> > My proposal tries very hard to present a single namespace\n> > _semantically_ to the user in the common case (when tags are\n> > unambiguous). I'd even go as far as proposing that \"git tag -l\" should\n> > by default list only a single shortened tag name in the cases where\n> > there are multiple unambiguous alternatives.\n> \n> IMHO, it is very confusing, especially for people whose script was\n> suddenly broken by those namespaces.\n\nI believe script breakage can be minimized. See above.\n\n> > Alternatively, I'd suggest a compromise (already mentioned elsewhere in\n> > this thread) where we add a config variable tags.preferredRemote\n> > (defaults to \"origin\") which allows you to directly select which\n> > namespace you consider official. You could even implement this as\n> > physically copying\n> > refs/remotes/${tag.preferredRemote}/tags/* into refs/tags/*.\n> \n> It seems you do not understand the problem that I am trying to say all\n> way along: there is more than one repo from which I fetch tags, and\n> because they are belong to the same project, they should be in the same\n> namespace.\n> \n> So, IMHO, the proper solution should be ability to specify the desired\n> namespace for any remote repository, like this:\n> \n> remote.<name>.tagNameSpace = foo\n\nInteresting. I'm not sure what \"foo\" means in this context. Would I use it \nlike this?:\n\n    remote.origin.tagNameSpace = refs/tags\n\n(to place origin's tags in refs/tags/*)\n\nIf so, what's the difference between this option, and using this?:\n\n    remote.origin.fetch = refs/tags/*:refs/tags/*\n\n> So, those who want to have many namespaces should be able to that\n> easily, but forcing multiple namespaces on those who have a single\n> namespace semantically is simple wrong. Not to mention that it breaks\n> existing scripts for no good reason.\n\nIn practice, this discussion boils down to whether we should use\n\n    remote.origin.fetch = refs/tags/*:refs/remotes/origin/tags/*\nor\n    remote.origin.fetch = refs/tags/*:refs/tags/*\n\nas the default refspec for tags. AFAICS, we both agree that whichever \nrefspec is chosen by default, it should be possible for the user to (fairly \neasily) override, and use the other refspec instead.\n\nWith that, my main concern about this part of the proposal is satisfied: \nPutting remote tags in separate namespaces will be easy to accomplish (if \nnot the default behavior).\n\n\nThanks for the feedback,\n\n...Johan\n\n\nPS: I'd be interested if you have a suggestion for how to deal with the \nissue presented by Nicolas' elsewhere in this thread. Quoting:\n\nThe extraordinary misfeature of the tag namespace at the moment comes \nfrom the fact that whenever you add a remote repo to fetch, and do fetch \nit, then your flat tag namespace gets polluted with all the tags the \nremote might have.  If you decide to delete some of those remote \nbranches, the tags that came with it are still there and \nindistinguishable from other tags making it a real pain to sort out.\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"}]}