Re: git-fetch: default globally to --no-tags

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: git-fetch: default globally to --no-tags

From: Junio C Hamano <hidden>
Date: 2016-06-15 23:02:59

Brian Norris [off-list ref] writes:
quoted hunk
--- TL;DR ---
You usually have TL;DR at the beginning to help people save time;
having it at the end forces the whole thing to be read and would not
help anybody. ;-)
My email boils down to two questions:

  (A) Has there been progress on implementing a proposal like in [2]?
I do not think so, and also I do not agree that "mirror everybody
else's ref hierarchy into separate namespaces" is necessarily a good
idea, especially for tags, whose reason of existence is to give
people a way to have anchoring points they agree on to have a shared
world view necessary to move things forward.

In other words, talks in [2] are attempting to solve a wrong
problem.  The problem people want to solve is to have a mechanism to
keep private anchoring points that are not necessarily shared
project wide, which tags in refs/tags hierarchy is *not*.

Like it or not, tags are meant to be used for globally shared
anchoring points and the whole machinery (e.g. "fetch" that
auto-follows tags, "clone" that gives refs/tags*:refs/tags/*
refspec) is geared towards supporting that use pattern, which will
be broken by moving tags to per-remote namespace.

I can see "git tag --local foo" that creates refs/local-tags/foo
and also adding a mechanism to propagate local-tags/ hierarchy just
like heads/ hierarchy is propagated per-remote as a solution to that
problem that does not break the "release tags" use case, though.
  (B) Can we allow disabling (auto)tag-fetching globally? Like:

        git config --global remote.tagopt --no-tags
Using remote.<variable> as a fallback for remote.<remote>.<variable>
may be a useful addition, not limited to <variable>==tagopt case.

This is a tangent, but it is an important one because we are talking
about "tagopt" specifically.  I think we should start deprecating
"*.tagopt --[no-]tags".  It started as a quick-and-dirty hack back
when "git fetch" was a shell script Porcelain, where it made it easy
to write things like this in its implementation:

	tagOpt=$(git config "remote.$name.tagopt")
        git fetch $tagOpt $name $args

which gives an impression that any command line option can go there
(e.g.  as if you could set "remote.*.tagopt = --frotz --no-tags")
and "git fetch" implementation, even after it is redone in C, must
forever parse it as if it is part of a shell command line
(e.g. splitting at $IFS, unquoting the shell quotes and interpreting
as if they came in argv[]).

This is ugly and simply unmaintainable, and we should transition
away from that, by doing something like:

 (1) Add remote.*.tags configuration, which defaults to 'follow',
     but can be set to 'true' or 'false'.  Accept '--tags' as a
     synonym to 'true' and '--no-tags' as a synonym to 'false'.

     * when set to 'follow', allow auto-following tags (the default).
     * when set to 'true', act as if --tags is given.
     * when set to 'false', act as if --no-tags is given.

 (2) Deprecate remote.*.tagopt configuration.  When it is used, give
     a warning about deprecation and encourage users to move to
     remote.*.tags setting.

 (3) Wait for several release cycles.

 (4) Remove remote.*.tags configuration support at a major version
     boundary.

Needless to say, support for remote.<variable> as a fallback for
remote.<remote>.<variable> for any <variable> can be done in
parallel to this tangent topic.

Re: git-fetch: default globally to --no-tags

From: Jeff King <hidden>
Date: 2016-06-15 23:02:59

On Wed, Nov 19, 2014 at 10:45:48AM -0800, Junio C Hamano wrote:
quoted
My email boils down to two questions:

  (A) Has there been progress on implementing a proposal like in [2]?
I do not think so, and also I do not agree that "mirror everybody
else's ref hierarchy into separate namespaces" is necessarily a good
idea, especially for tags, whose reason of existence is to give
people a way to have anchoring points they agree on to have a shared
world view necessary to move things forward.

In other words, talks in [2] are attempting to solve a wrong
problem.  The problem people want to solve is to have a mechanism to
keep private anchoring points that are not necessarily shared
project wide, which tags in refs/tags hierarchy is *not*.

Like it or not, tags are meant to be used for globally shared
anchoring points and the whole machinery (e.g. "fetch" that
auto-follows tags, "clone" that gives refs/tags*:refs/tags/*
refspec) is geared towards supporting that use pattern, which will
be broken by moving tags to per-remote namespace.

I can see "git tag --local foo" that creates refs/local-tags/foo
and also adding a mechanism to propagate local-tags/ hierarchy just
like heads/ hierarchy is propagated per-remote as a solution to that
problem that does not break the "release tags" use case, though.
I am not sure I agree here that the discussions in [2] were not handling
this case. Here you are arguing for the tag-writer to distinguish
between two separate namespaces: global and local.

But I think the proposals in [2] were about pushing that logic into the
lookup phase. That is, pulling in all of the remote's tags as
"refs/remotes/origin/tags/*", and then at lookup time checking multiple
locations for tags (and preferring your local "refs/tags" to what is
pulled from a remote).

I think that system is better because it gives flexibility in resolution
to the viewer of the tags, not the writer. E.g., consider a project that
is merging two different sub-projects, project1 and project2. Each of
the sub-projects has their own global namespace with v1.0, v2.0, etc.
They would never use local-tags; these are meant to be in a per-project
global namespace.

But the superproject is pulling them both together; if it uses
refs/tags, the global namespaces will clash. Instead, it would be more
convenitn to have refs/remotes/project1/tags and so on. And then a
lookup of "v1.0" can either prefer project1 to project2, vice-versa, or
even respect neither. But the point is that the desired outcome is in
the eye of the beholder, not the writer.
This is a tangent, but it is an important one because we are talking
about "tagopt" specifically.  I think we should start deprecating
"*.tagopt --[no-]tags".
Thanks for writing this out. I touched on it in the other email I sent,
but did not explain it very well. The transition you mentioned here is
exactly what I was thinking of.

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help