{"thread":{"id":"38006","subject":"git-fetch: default globally to --no-tags","startedAt":"2014-11-19T03:05:23Z","lastAt":"2014-11-19T20:32:09Z","messageCount":6,"participants":["Brian Norris","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"252176","messageId":"20141119030523.GO22361@norris-Latitude-E6410","threadId":"38006","inReplyTo":null,"subject":"git-fetch: default globally to --no-tags","fromName":"Brian Norris","fromEmail":"computersforpeace@gmail.com","sentAt":"2014-11-19T03:05:23Z","receivedAt":"2014-11-19T03:05:23Z","isPatch":false,"sender":{"key":"computersforpeace@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2268082?v=4"},"body":"Hi,\n\nI have one main concern, and I can envision a few ways that git could\nsolve it. I also see that there has been some previous discussion on\nreltaed topics over the years, but as far as I can tell, nothing has\nactually been implemented to address my concern.\n\n--- My concern ---\n\nWhen I fetch from a remote repository, the only ways to\nprevent fetching tags are:\n\n  1) git fetch --no-tags <name>\n\n  2) git config remote.<name>.tagopt --no-tags; git fetch <name>\n\nThe former requires extra typing for a case that (arguably) should be\nthe default. The latter requires configuration for each repository. This\ndoesn't scale well, if a user desires this behavior on all repositories\nthey use.\n\nI'd prefer something like this, to change the default tag-fetching\nbehavior globally:\n\n  git config --global remote.tagopt --no-tags\n\nThe closest I see is that I can disable tag-fetching globally on a\nper-remote name basis:\n\n  git config --global remote.<name>.tagopt --no-tags\n\nThis brings me to a potential bug report:\n\n--- Bug ---\n\nWhen trying to use the remote.<name>.tagopt configuration option\nglobally, I get something like this:\n\n  $ git config --global remote.test.tagopt --no-tags\n  $ git remote update\n  ...\n  Fetching test\n  fatal: 'test' does not appear to be a git repository\n  fatal: Could not read from remote repository.\n\n  Please make sure you have the correct access rights\n  and the repository exists.\n  error: Could not fetch test\n  ...\n\nExpected behavior: if the local repository does not have a remote named\n'test', then no additional output should be printed. If the local\nrepository has a remote named test, then it should be fetched with the\n--no-tags option.\n\nActual behavior: git prints warnings about the 'test' remote, just\nbecause there is no remote named 'test.'\n\n--- Motivations ---\n\nThis is all motivated by the fact that tag namespacing is completely\nbroken in git. Tags are globally namespaced, and in a true DVCS\nenvironment, any particular developer has no control over another\ndeveloper's tag naming conventions. So this namespace can easily become\npolluted, reducing the usefulness of tags as a whole [1]. This problem\nseems to have been acknowledged, and proposals appeared a few years ago\n[2]. But I don't see any solution for tag namespacing.\n\nSo, my current approach is to try to limit the damage done by\naccidentally fetching tags. Unfortunately, I can't find any good\nsupported mechanisms to help me in the previous two sections.\n\n--- TL;DR ---\n\nMy email boils down to two questions:\n\n  (A) Has there been progress on implementing a proposal like in [2]?\n\n  (B) Can we allow disabling (auto)tag-fetching globally? Like:\n\n        git config --global remote.tagopt --no-tags\n\nThanks,\nBrian\n\n[1] I could elaborate with some horror stories, to describe how this\n    becomes a day-to-day nuisance in using git for me, but I'll avoid\n    the details for now. Please accept that this is a usability bug.\n\n[2]\n    http://article.gmane.org/gmane.comp.version-control.git/165799\n    http://article.gmane.org/gmane.comp.version-control.git/165885\n"},{"id":"252189","messageId":"20141119184220.GA9569@peff.net","threadId":"38006","inReplyTo":"20141119030523.GO22361@norris-Latitude-E6410","subject":"Re: git-fetch: default globally to --no-tags","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-19T18:42:20Z","receivedAt":"2014-11-19T18:42:20Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Nov 18, 2014 at 07:05:23PM -0800, Brian Norris wrote:\n\n> When I fetch from a remote repository, the only ways to\n> prevent fetching tags are:\n> \n>   1) git fetch --no-tags <name>\n> \n>   2) git config remote.<name>.tagopt --no-tags; git fetch <name>\n\nYes, there is no way to globally specify --no-tags. I don't see it as a\nproblem to add something like that.\n\n> The former requires extra typing for a case that (arguably) should be\n> the default.\n\nI don't understand this assumption, though. Why don't you want to fetch\ntags from the remote side? Wouldn't this break something as simple as:\n\n  git clone git://git.kernel.org/pub/scm/git/git.git\n  cd git\n  git checkout v2.1.3\n\n(Actually, no, it wouldn't, because clone side-steps the usual\ntag-following procedure, but wouldn't you expect the same thing to work\nafter a fetch in an existing repository?)\n\n(And now having read all the way to the bottom of your email, I at least\nsee why you dislike tags. But I am not convinced that turning them off\ncompletely does not come with its own set of usability problems).\n\n> I'd prefer something like this, to change the default tag-fetching\n> behavior globally:\n> \n>   git config --global remote.tagopt --no-tags\n\nYeah, that would make sense to me (I do not know _why_ you would want to\ndo it, but it would be consistent with other parts of git). If you are\nadding a new config option, though, please do not follow the odd and\nconfusing \"tagopt\" config value, and make a boolean remote.autofollowtags\nor something.\n\n> --- Bug ---\n> \n> When trying to use the remote.<name>.tagopt configuration option\n> globally, I get something like this:\n> \n>   $ git config --global remote.test.tagopt --no-tags\n>   $ git remote update\n>   ...\n>   Fetching test\n>   fatal: 'test' does not appear to be a git repository\n>   fatal: Could not read from remote repository.\n> \n>   Please make sure you have the correct access rights\n>   and the repository exists.\n>   error: Could not fetch test\n>   ...\n> \n> Expected behavior: if the local repository does not have a remote named\n> 'test', then no additional output should be printed. If the local\n> repository has a remote named test, then it should be fetched with the\n> --no-tags option.\n> \n> Actual behavior: git prints warnings about the 'test' remote, just\n> because there is no remote named 'test.'\n\nThat is the expected behavior (sort of). Any time you define a single\nkey in a remote, that remote \"exists\", whether there is a remote.*.url\nkey for it or not. You can use that to set options for remotes you\nspecify only as a URL, though I do not know how widely-used that feature\nis.\n\nIOW, git is not complaining here that there is no remote named 'test'.\nIt is complaining that you have defined a remote called 'test', whose\nURL defaults to 'test' (because you did not specify one in the config),\nand that there is no repo called test. If you defined it as:\n\n  git config --global remote.git://github.com/git/git.tagopt --no-tags\n\nthat would \"work\" in the sense that \"git remote update\" would download\ngit in every repository. ;)\n\nI think one could argue that \"git remote update\" should probably skip\nremotes for which no url is defined (but we _do_ still want to treat\nthem as remotes internally, so that when you \"git fetch ...\", we apply\nthe config correctly).\n\n> --- Motivations ---\n> \n> This is all motivated by the fact that tag namespacing is completely\n> broken in git. Tags are globally namespaced, and in a true DVCS\n> environment, any particular developer has no control over another\n> developer's tag naming conventions. So this namespace can easily become\n> polluted, reducing the usefulness of tags as a whole [1]. This problem\n> seems to have been acknowledged, and proposals appeared a few years ago\n> [2]. But I don't see any solution for tag namespacing.\n\nI don't know if I would say \"completely broken\", as it mostly gets the\njob done. But yes, there are other ways of doing it that would have\nadvantages.\n\n> My email boils down to two questions:\n> \n>   (A) Has there been progress on implementing a proposal like in [2]?\n\nNot really, no. If you'd like to work on it, I'm sure people would be\nhappy to review patches.\n\n>   (B) Can we allow disabling (auto)tag-fetching globally? Like:\n> \n>         git config --global remote.tagopt --no-tags\n\nThat seems reasonable to me to use remote.* as defaults for all remotes.\n\n-Peff\n"},{"id":"252190","messageId":"xmqqr3wzrpur.fsf@gitster.dls.corp.google.com","threadId":"38006","inReplyTo":"20141119030523.GO22361@norris-Latitude-E6410","subject":"Re: git-fetch: default globally to --no-tags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T18:45:48Z","receivedAt":"2014-11-19T18:45:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brian Norris <computersforpeace@gmail.com> writes:\n\n> --- TL;DR ---\n\nYou usually have TL;DR at the beginning to help people save time;\nhaving it at the end forces the whole thing to be read and would not\nhelp anybody. ;-)\n\n> My email boils down to two questions:\n>\n>   (A) Has there been progress on implementing a proposal like in [2]?\n\nI do not think so, and also I do not agree that \"mirror everybody\nelse's ref hierarchy into separate namespaces\" is necessarily a good\nidea, especially for tags, whose reason of existence is to give\npeople a way to have anchoring points they agree on to have a shared\nworld view necessary to move things forward.\n\nIn other words, talks in [2] are attempting to solve a wrong\nproblem.  The problem people want to solve is to have a mechanism to\nkeep private anchoring points that are not necessarily shared\nproject wide, which tags in refs/tags hierarchy is *not*.\n\nLike it or not, tags are meant to be used for globally shared\nanchoring points and the whole machinery (e.g. \"fetch\" that\nauto-follows tags, \"clone\" that gives refs/tags*:refs/tags/*\nrefspec) is geared towards supporting that use pattern, which will\nbe broken by moving tags to per-remote namespace.\n\nI can see \"git tag --local foo\" that creates refs/local-tags/foo\nand also adding a mechanism to propagate local-tags/ hierarchy just\nlike heads/ hierarchy is propagated per-remote as a solution to that\nproblem that does not break the \"release tags\" use case, though.\n\n>   (B) Can we allow disabling (auto)tag-fetching globally? Like:\n>\n>         git config --global remote.tagopt --no-tags\n\nUsing remote.<variable> as a fallback for remote.<remote>.<variable>\nmay be a useful addition, not limited to <variable>==tagopt case.\n\nThis is a tangent, but it is an important one because we are talking\nabout \"tagopt\" specifically.  I think we should start deprecating\n\"*.tagopt --[no-]tags\".  It started as a quick-and-dirty hack back\nwhen \"git fetch\" was a shell script Porcelain, where it made it easy\nto write things like this in its implementation:\n\n\ttagOpt=$(git config \"remote.$name.tagopt\")\n        git fetch $tagOpt $name $args\n\nwhich gives an impression that any command line option can go there\n(e.g.  as if you could set \"remote.*.tagopt = --frotz --no-tags\")\nand \"git fetch\" implementation, even after it is redone in C, must\nforever parse it as if it is part of a shell command line\n(e.g. splitting at $IFS, unquoting the shell quotes and interpreting\nas if they came in argv[]).\n\nThis is ugly and simply unmaintainable, and we should transition\naway from that, by doing something like:\n\n (1) Add remote.*.tags configuration, which defaults to 'follow',\n     but can be set to 'true' or 'false'.  Accept '--tags' as a\n     synonym to 'true' and '--no-tags' as a synonym to 'false'.\n\n     * when set to 'follow', allow auto-following tags (the default).\n     * when set to 'true', act as if --tags is given.\n     * when set to 'false', act as if --no-tags is given.\n\n (2) Deprecate remote.*.tagopt configuration.  When it is used, give\n     a warning about deprecation and encourage users to move to\n     remote.*.tags setting.\n\n (3) Wait for several release cycles.\n\n (4) Remove remote.*.tags configuration support at a major version\n     boundary.\n\nNeedless to say, support for remote.<variable> as a fallback for\nremote.<remote>.<variable> for any <variable> can be done in\nparallel to this tangent topic.\n"},{"id":"252194","messageId":"20141119185708.GA9908@peff.net","threadId":"38006","inReplyTo":"xmqqr3wzrpur.fsf@gitster.dls.corp.google.com","subject":"Re: git-fetch: default globally to --no-tags","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-19T18:57:09Z","receivedAt":"2014-11-19T18:57:09Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Nov 19, 2014 at 10:45:48AM -0800, Junio C Hamano wrote:\n\n> > My email boils down to two questions:\n> >\n> >   (A) Has there been progress on implementing a proposal like in [2]?\n> \n> I do not think so, and also I do not agree that \"mirror everybody\n> else's ref hierarchy into separate namespaces\" is necessarily a good\n> idea, especially for tags, whose reason of existence is to give\n> people a way to have anchoring points they agree on to have a shared\n> world view necessary to move things forward.\n> \n> In other words, talks in [2] are attempting to solve a wrong\n> problem.  The problem people want to solve is to have a mechanism to\n> keep private anchoring points that are not necessarily shared\n> project wide, which tags in refs/tags hierarchy is *not*.\n> \n> Like it or not, tags are meant to be used for globally shared\n> anchoring points and the whole machinery (e.g. \"fetch\" that\n> auto-follows tags, \"clone\" that gives refs/tags*:refs/tags/*\n> refspec) is geared towards supporting that use pattern, which will\n> be broken by moving tags to per-remote namespace.\n> \n> I can see \"git tag --local foo\" that creates refs/local-tags/foo\n> and also adding a mechanism to propagate local-tags/ hierarchy just\n> like heads/ hierarchy is propagated per-remote as a solution to that\n> problem that does not break the \"release tags\" use case, though.\n\nI am not sure I agree here that the discussions in [2] were not handling\nthis case. Here you are arguing for the tag-writer to distinguish\nbetween two separate namespaces: global and local.\n\nBut I think the proposals in [2] were about pushing that logic into the\nlookup phase. That is, pulling in all of the remote's tags as\n\"refs/remotes/origin/tags/*\", and then at lookup time checking multiple\nlocations for tags (and preferring your local \"refs/tags\" to what is\npulled from a remote).\n\nI think that system is better because it gives flexibility in resolution\nto the viewer of the tags, not the writer. E.g., consider a project that\nis merging two different sub-projects, project1 and project2. Each of\nthe sub-projects has their own global namespace with v1.0, v2.0, etc.\nThey would never use local-tags; these are meant to be in a per-project\nglobal namespace.\n\nBut the superproject is pulling them both together; if it uses\nrefs/tags, the global namespaces will clash. Instead, it would be more\nconvenitn to have refs/remotes/project1/tags and so on. And then a\nlookup of \"v1.0\" can either prefer project1 to project2, vice-versa, or\neven respect neither. But the point is that the desired outcome is in\nthe eye of the beholder, not the writer.\n\n> This is a tangent, but it is an important one because we are talking\n> about \"tagopt\" specifically.  I think we should start deprecating\n> \"*.tagopt --[no-]tags\".\n\nThanks for writing this out. I touched on it in the other email I sent,\nbut did not explain it very well. The transition you mentioned here is\nexactly what I was thinking of.\n\n-Peff\n"},{"id":"252200","messageId":"xmqqa93nrldf.fsf@gitster.dls.corp.google.com","threadId":"38006","inReplyTo":"20141119185708.GA9908@peff.net","subject":"Re: git-fetch: default globally to --no-tags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T20:22:36Z","receivedAt":"2014-11-19T20:22:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Nov 19, 2014 at 10:45:48AM -0800, Junio C Hamano wrote:\n>\n>> ... tags are meant to be used for globally shared\n>> anchoring points and the whole machinery (e.g. \"fetch\" that\n>> auto-follows tags, \"clone\" that gives refs/tags*:refs/tags/*\n>> refspec) is geared towards supporting that use pattern, which will\n>> be broken by moving tags to per-remote namespace.\n>> \n>> I can see \"git tag --local foo\" that creates refs/local-tags/foo\n>> and also adding a mechanism to propagate local-tags/ hierarchy just\n>> like heads/ hierarchy is propagated per-remote as a solution to that\n>> problem that does not break the \"release tags\" use case, though.\n>\n> I am not sure I agree here that the discussions in [2] were not handling\n> this case. Here you are arguing for the tag-writer to distinguish\n> between two separate namespaces: global and local.\n>\n> But I think the proposals in [2] were about pushing that logic into the\n> lookup phase. That is, pulling in all of the remote's tags as\n> \"refs/remotes/origin/tags/*\", and then at lookup time checking multiple\n> locations for tags (and preferring your local \"refs/tags\" to what is\n> pulled from a remote).\n\nWith a separate local-tags hierarchy, the look-up part still has to\nbe enhanced.  After doing \"git tag v2.0\" and \"git tag -l snapshot00\",\nyou would want to be able to say \"git log snapshot00..v2.0\" and have\nthese found.\n\nIf you don't allow a private local-tags hierarchy, then those who\nmake releases are burdened to be very careful not to contaminate\ntheir public repository --- \"git tag snapshot00\" cannot be used by\nthem lightly just to mark their private state, if their day\ntypically is concluded with \"git push --follow-tags\", as that will\npush out the \"tags\" that are meant to be private.\n\nAside from the mantra that it is a good thing to reduce the workload\nfor people closer to the center of the project (hence likely to be\nbottleneck to slow down others) and a separate local-tags hierarchy\nis a way to achieve that, a separate local-tags hierarchy also helps\npeople who do not make releases by letting them easily differenciate\nthe global tags they get from the project and the tags they and\nother project participants create as private markers (their own will\nbe found in refs/local-tags, others' in refs/remotes/$pal/local-tags).\n\n> ...\n> But the superproject is pulling them both together; if it uses\n> refs/tags, the global namespaces will clash. Instead, it would be more\n> convenitn to have refs/remotes/project1/tags and so on.\n\nYeah, but isn't it an orthogonal issue?  refs/tags/project{1,2}/*\nwould be what I would recommend to use for \"global\" stuff whose\npurpose is to give people a shared world view.\n"},{"id":"252202","messageId":"20141119203208.GA11053@peff.net","threadId":"38006","inReplyTo":"xmqqa93nrldf.fsf@gitster.dls.corp.google.com","subject":"Re: git-fetch: default globally to --no-tags","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-19T20:32:09Z","receivedAt":"2014-11-19T20:32:09Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Nov 19, 2014 at 12:22:36PM -0800, Junio C Hamano wrote:\n\n> With a separate local-tags hierarchy, the look-up part still has to\n> be enhanced.  After doing \"git tag v2.0\" and \"git tag -l snapshot00\",\n> you would want to be able to say \"git log snapshot00..v2.0\" and have\n> these found.\n> \n> If you don't allow a private local-tags hierarchy, then those who\n> make releases are burdened to be very careful not to contaminate\n> their public repository --- \"git tag snapshot00\" cannot be used by\n> them lightly just to mark their private state, if their day\n> typically is concluded with \"git push --follow-tags\", as that will\n> push out the \"tags\" that are meant to be private.\n\nIt's not that I want to disallow a private local-tags hierarchy. It's\njust that I consider it a completely orthogonal feature. In other words,\nthe problem of tags in a global namespace is not solved at all by\nlocal-tags. It just helps people keep things out of the global namespace\nthat they did not want to be there in the first place[1]. It does\nnothing for viewers who need to coalesce multiple global tag namespaces\n(either from multiple projects, or \"proposals\" of global tags they have\npulled in from other non-canonical repositories).\n\n> > But the superproject is pulling them both together; if it uses\n> > refs/tags, the global namespaces will clash. Instead, it would be more\n> > convenitn to have refs/remotes/project1/tags and so on.\n> \n> Yeah, but isn't it an orthogonal issue?  refs/tags/project{1,2}/*\n> would be what I would recommend to use for \"global\" stuff whose\n> purpose is to give people a shared world view.\n\nHow do they get that split? They cannot use tag auto-following, which\nputs the tags in the global refs/tags.\n\nCertainly it can be done with git _today_ by setting up the appropriate\nrefspecs. I think this is more about making things useful out of the\nbox. \n\n-Peff\n\n[1] I am actually not convinced that the mixing of local and global tags\n    is a huge problem in practice. We do not push tags by default, so\n    local tags tend to stay local. OTOH, I think the world would be a\n    better place if \"git push --follow-tags\" were the default, which\n    would entail somehow separating global from local tags.\n"}]}