[1.8.0] Remote tag namespace

classic Classic list List threaded Threaded
105 messages Options
1234 ... 6
Reply | Threaded
Open this post in threaded view
|

[1.8.0] Remote tag namespace

Duy Nguyen
On Tue, Feb 1, 2011 at 11:16 AM, Nicolas Pitre <[hidden email]> wrote:
> On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
>> Another random wish, which does not come with a proposal. How about
>> tag namespace (ie. tags from a remote stay in remote namespace)?
>
> Please make this into a proper proposal.  this would be indeed a huge
> improvement.

OK I'm not familiar with tag code, but I can try.

Proposal:

Reserve refs/remote-tags namespace to store tags from remotes. Its
structure is the same as in refs/remotes. When pulling tags, put them
in refs/remote-tags/<remote> instead of refs/tags.
Tag dereference code will be taught about refs/remote-tags with
similar deref order as in remote branches.

Config branch.*.globalTags (perhaps takes a pattern?) may be defined
to create refs/tags/* in addition to refs/remote-tags/<remote>/* when
fetching tags.

Migration plan:

refs/remote-tags will be used to store new tags unconditionally, which
means there will be duplicates with the already-fetched tags in global
namespace. Perhaps we can check if they point to the same sha-1, then
choose not to annoy users with ambiguous tag messages?

I suggest to add config compatibility.remoteTagNamespace, default to
false, which retains current behavior (i.e. also create tags in global
namespace in addition to refs/remote-tags). After 1.8.0 (or a few more
cycles) the default value becomes true. Users who wish to keep old
behavior can put "false" in their ~/.gitconfig.

After a few years, remove support for the config key. Unrecognized
compatibility.* keys will abort program. Users are forced to new
behavior. I don't know, we may want to start annoy users that have the
config key set a few cycles before we drop support.
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Leo Razoumov
On Tue, Feb 1, 2011 at 05:44, Nguyen Thai Ngoc Duy <[hidden email]> wrote:

> On Tue, Feb 1, 2011 at 11:16 AM, Nicolas Pitre <[hidden email]> wrote:
>> On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
>>> Another random wish, which does not come with a proposal. How about
>>> tag namespace (ie. tags from a remote stay in remote namespace)?
>>
>> Please make this into a proper proposal.  this would be indeed a huge
>> improvement.
>
> OK I'm not familiar with tag code, but I can try.
>
> Proposal:
>

Remote tag namespace is a great feature long overdue in git. Due to
git's current flat tag namespace I am forced to make my tags
artificially long like
"my_project_repo_name/v-1.2.3".

Looking forward to remote tag namespace -- sooner the better!

--Leo--
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Marc Branchaud
In reply to this post by Duy Nguyen
On 11-02-01 05:44 AM, Nguyen Thai Ngoc Duy wrote:
> On Tue, Feb 1, 2011 at 11:16 AM, Nicolas Pitre <[hidden email]> wrote:
>> On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
>>> Another random wish, which does not come with a proposal. How about
>>> tag namespace (ie. tags from a remote stay in remote namespace)?
>>
>> Please make this into a proper proposal.  this would be indeed a huge
>> improvement.
>
> OK I'm not familiar with tag code, but I can try.

OK, that teaches me to read through _all_ the unread messages before posting!

Needless to say, I support this proposal.

> Proposal:
>
> Reserve refs/remote-tags namespace to store tags from remotes. Its
> structure is the same as in refs/remotes. When pulling tags, put them
> in refs/remote-tags/<remote> instead of refs/tags.
> Tag dereference code will be taught about refs/remote-tags with
> similar deref order as in remote branches.

I suggested a different home for the tags, but I don't have any insight into
what makes the most sense.  I'll defer to wiser folk on this.

> Config branch.*.globalTags (perhaps takes a pattern?) may be defined
> to create refs/tags/* in addition to refs/remote-tags/<remote>/* when
> fetching tags.

I may be getting into the weeds prematurely here, but why put the config item
under branch.* ?  Or did you mean remote.*.globalTags?  Personally, I don't
see a need for this.  I'd rather have the rev-parse machinery search in
remote tag namespaces if it can't find anything local.

> Migration plan:
>
> refs/remote-tags will be used to store new tags unconditionally, which
> means there will be duplicates with the already-fetched tags in global
> namespace. Perhaps we can check if they point to the same sha-1, then
> choose not to annoy users with ambiguous tag messages?

(Again with the weeds...)  I don't think we could do that.  I'd want to be
able to have my own (local) tags that refer to the same commits as one or
more remote tags, and I'd want to see them all.

Better for "git tag" to learn scoping options like "git branch": -a and -r.
(Hmm, maybe git-tag's current -a could become -A...)

> I suggest to add config compatibility.remoteTagNamespace, default to
> false, which retains current behavior (i.e. also create tags in global
> namespace in addition to refs/remote-tags). After 1.8.0 (or a few more
> cycles) the default value becomes true. Users who wish to keep old
> behavior can put "false" in their ~/.gitconfig.
>
> After a few years, remove support for the config key. Unrecognized
> compatibility.* keys will abort program. Users are forced to new
> behavior. I don't know, we may want to start annoy users that have the
> config key set a few cycles before we drop support.

Sounds good.  I'd vote for a faster transition, but that's just me.  :)

                M.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Duy Nguyen
On Tue, Feb 1, 2011 at 10:07 PM, Marc Branchaud <[hidden email]> wrote:
>> Config branch.*.globalTags (perhaps takes a pattern?) may be defined
>> to create refs/tags/* in addition to refs/remote-tags/<remote>/* when
>> fetching tags.
>
> I may be getting into the weeds prematurely here, but why put the config item
> under branch.* ?  Or did you mean remote.*.globalTags?  Personally, I don't
> see a need for this.  I'd rather have the rev-parse machinery search in
> remote tag namespaces if it can't find anything local.

Ahh.. yeah it's remote.*.globalTags. I don't know, some people might
find current behavior useful. So instead of dropping it entirely, I'd
limit it to certain remotes.

>
>> Migration plan:
>>
>> refs/remote-tags will be used to store new tags unconditionally, which
>> means there will be duplicates with the already-fetched tags in global
>> namespace. Perhaps we can check if they point to the same sha-1, then
>> choose not to annoy users with ambiguous tag messages?
>
> (Again with the weeds...)  I don't think we could do that.  I'd want to be
> able to have my own (local) tags that refer to the same commits as one or
> more remote tags, and I'd want to see them all.

For listing tags (I forgot this) I think we just follow how git-branch
does it: show only local tags unless -r (or some other option) is
given. What I meant in the above paragraph is "some-ref" can refer to
refs/tags/some-ref or refs/remotes/foo/tags/some-ref, but I was wrong
on this. The latter can only be referred by foo/some-ref or with
migration support in your proposal.

>
> Better for "git tag" to learn scoping options like "git branch": -a and -r.
> (Hmm, maybe git-tag's current -a could become -A...)

When tags are put in remote namespace (wherever it actually is),
git-tag must learn -r like git-branch. I think option name change for
-a is too late though. When "git-ng" rewrite project comes (that is
after libgit2 replaces git core), we may have everything consistent
again.

PS. I bet git-ng would start after Wine 2.0 is released.
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Jeff King
In reply to this post by Duy Nguyen
On Tue, Feb 01, 2011 at 05:44:50PM +0700, Nguyen Thai Ngoc Duy wrote:

> OK I'm not familiar with tag code, but I can try.
>
> Proposal:
>
> Reserve refs/remote-tags namespace to store tags from remotes. Its
> structure is the same as in refs/remotes. When pulling tags, put them
> in refs/remote-tags/<remote> instead of refs/tags.
> Tag dereference code will be taught about refs/remote-tags with
> similar deref order as in remote branches.

There are similar questions around remote notes refs. Should there also
be a refs/remote-notes? And there was some discussion recently about
fetching remote replace refs.

Should we perhaps be massaging refs/remotes into a structure to handle
all of these things? Like:

  refs/remotes/origin/HEAD (-> refs/remotes/origin/heads/master)
  refs/remotes/origin/heads/master
  refs/remotes/origin/tags/v1.7.4
  refs/remotes/origin/notes/commit
  refs/remotes/origin/replace/f67e92af477a2255b64a1ece33d9d126e763fe9b

i.e., make refs/remotes/* an actual mirror of selected parts of the
remote's refs/ hierarchy. And then figure out sane rules for merging
those namespaces into the ref lookup procedure. For heads and tags,
probably some tweaking of the lookup rules in dwim_ref; for
replacements, probably you would want to manually say "I am interested
in this replace" and copy or symref-link it into your refs/ hierarchy.
And probably something similar with notes.

Obviously I haven't thought it all the way through, but it just seems a
shame not to deal with other similar issues when looking at tags.

-Peff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Sverre Rabbelier-2
Heya,

On Tue, Feb 1, 2011 at 19:14, Jeff King <[hidden email]> wrote:
> i.e., make refs/remotes/* an actual mirror of selected parts of the
> remote's refs/ hierarchy. And then figure out sane rules for merging
> those namespaces into the ref lookup procedure.

Jeff, Nguy, are either of you interested in writing up a new/modifying
this proposal to be about namespacing everything? I think it
definitely makes sense to have a namespace for notes, replaces, as
well as tags, especially since it would also allow us to propagate
these by default (at least to the refs/remotes namespace), and think
it's a good idea to go all the way if we're going to do this at all
(or we'll have the same discussion again later for notes and replaces,
and whatever comes after that).

--
Cheers,

Sverre Rabbelier
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Johan Herland
In reply to this post by Jeff King
On Tuesday 01 February 2011, Jeff King wrote:

> On Tue, Feb 01, 2011 at 05:44:50PM +0700, Nguyen Thai Ngoc Duy wrote:
> > OK I'm not familiar with tag code, but I can try.
> >
> > Proposal:
> >
> > Reserve refs/remote-tags namespace to store tags from remotes. Its
> > structure is the same as in refs/remotes. When pulling tags, put them
> > in refs/remote-tags/<remote> instead of refs/tags.
> > Tag dereference code will be taught about refs/remote-tags with
> > similar deref order as in remote branches.
>
> There are similar questions around remote notes refs. Should there also
> be a refs/remote-notes? And there was some discussion recently about
> fetching remote replace refs.
>
> Should we perhaps be massaging refs/remotes into a structure to handle
> all of these things? Like:
>
>   refs/remotes/origin/HEAD (-> refs/remotes/origin/heads/master)
>   refs/remotes/origin/heads/master
>   refs/remotes/origin/tags/v1.7.4
>   refs/remotes/origin/notes/commit
>   refs/remotes/origin/replace/f67e92af477a2255b64a1ece33d9d126e763fe9b
>
> i.e., make refs/remotes/* an actual mirror of selected parts of the
> remote's refs/ hierarchy. And then figure out sane rules for merging
> those namespaces into the ref lookup procedure. For heads and tags,
> probably some tweaking of the lookup rules in dwim_ref; for
> replacements, probably you would want to manually say "I am interested
> in this replace" and copy or symref-link it into your refs/ hierarchy.

I fully agree.

In addition - as discussed in http://thread.gmane.org/gmane.comp.version-
control.git/160503/focus=160795 - we should also tweak the refspec format to
make tag auto-following explicit in the refspec.

> And probably something similar with notes.

(going slightly offtopic with the notes discussion here)

I've been thinking that notes should be organized much in the same fashion
as branches/heads. There should be remote notes refs that should only be
updated from the remote, and there should be local notes refs in
refs/notes/*. You should be able to configure upstream relationships between
local notes refs and remote notes refs (e.g. notes.foo.remote and
notes.foo.merge), and auto-merge them on "git notes pull".


Have fun! :)

...Johan

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

[1.8.0] Provide proper remote ref namespaces

Johan Herland
In reply to this post by Sverre Rabbelier-2
On Wednesday 02 February 2011, Sverre Rabbelier wrote:
> On Tue, Feb 1, 2011 at 19:14, Jeff King <[hidden email]> wrote:
> > i.e., make refs/remotes/* an actual mirror of selected parts of the
> > remote's refs/ hierarchy. And then figure out sane rules for merging
> > those namespaces into the ref lookup procedure.
>
> Jeff, Nguy, are either of you interested in writing up a new/modifying
> this proposal to be about namespacing everything?

Here's my go at phrasing this in a proposal format. Feel free to revise and
resend:


Proposal:

Currently, git stores remote refs in the local repo by default as follows:

  Remote repo    ->   Local repo
  ---------------------------------------------------------
  HEAD                refs/remotes/$remote/HEAD  (implicit)
  refs/heads/*        refs/remotes/$remote/*
  refs/tags/*         refs/tags/*                (implicit, autofollow)
  refs/replace/*      (TBD)
  refs/notes/*        (TBD)

Several users report that they are confused by the difference in how heads
and tags are mapped, and by the implicit mappings that are not mentioned in
the configured refspecs. Also, as users want to share ever more different
types of refs (replace refs and notes refs have been discussed recently),
the existing ref mappings (aka. refspecs) do not suggest a natural/intuitive
mapping for the new ref types.

Instead, we should change the default ref mappings into the following:

  Remote repo    ->   Local repo
  --------------------------------------------------
  HEAD                refs/remotes/$remote/HEAD
  refs/heads/*        refs/remotes/$remote/heads/*
  refs/tags/*         refs/remotes/$remote/tags/*
  refs/replace/*      refs/remotes/$remote/replace/*
  refs/notes/*        refs/remotes/$remote/notes/*

In short, we make refs/remotes/$remote/* an actual mirror of selected parts
of the remote's refs/* hierarchy. This provides consistent namespaces for
remote refs that naturally allows adding new ref types in the future.

This change obviously affects our ref-handling code:

- Remote tags are now stored separate from local tags. When looking up a
shorthand tag name (e.g. v1.7.4), we should consult local tags
(refs/tags/v1.7.4) before remote tags (refs/remotes/*/tags/v1.7.4 [1]). See
[2] for more details.

- Remote heads have moved into refs/remotes/$remote/heads/*, hence
invalidating shorthand remote head names, like "origin/master". We should
change the lookup code, so that a shorthand ref of the form "$remote/$head"
where "$remote" happens to match a configured remote is eventually expanded
into lookup for "refs/remotes/$remote/heads/$head" [3].

- We might want to generalize the handling of "$remote/$head" into allowing
shorthands like "$remote/$tag", "$remote/$replace" and "$remote/$note" as
well (provided, of course, that they match unambiguously).

- All fetch refspecs should be given explicitly.

Sub-proposal: While we are changing the default refspecs, we should also
consider whether we want to keep the auto-following behavior that Git
currently does for tags (don't fetch tags that refer to objects not
otherwise fetched by another refspec). If we simply make an explicit
"+refs/tags/*:refs/remotes/$remote/tags/*" refspec, we will lose the auto-
following behavior. If we do want to keep the auto-following behavior, we
could for example add a "~" prefix to the refspec to trigger auto-following
behavior (i.e. this refspec only applies to refs that happen to point at
objects fetched by way of a different refspec). See
http://thread.gmane.org/gmane.comp.version-control.git/160503/focus=160795 
for more details.


Risks:

Existing scripts/programs may make assumptions about the layout of remote
refs without consulting the configured refspecs. However, such
scripts/programs may also break today when non-default refspecs are used.

When remotes have conflicting tags (same tag name points to different
objects), and the tag name does not exist locally (in refs/tags/*), looking
up the shorthand tag name will result in an "ambiguous ref" error (instead
of silently adopting whichever tag was fetched first). Although many
consider this an improvement on the current behavior, there may be scenarios
where this causes problems in external scripts/programs.

Existing scripts/programs that assume and depend on the current implicit
refspecs (or the tag auto-following behavior), might encounter problems when
we drop these in favor of explicit refspecs.


Migration plan:

The main part of this proposal is simply changing the default refspecs. As
such, the proposal can be simulated in current Git versions by setting up
custom refspecs according to the above table of ref mappings.

In v1.8.0, we should default to the new default refspecs when creating new
remotes. However, existing remotes (created pre-v1.8.0) must continue to
work as before, so we cannot simply remove the implicit refspecs (or tag
auto-following). Instead we need to make sure that the implicit refspecs is
NOT applied to the new-style remotes. Identifying new-style vs. old-style
remotes can be done by looking at the refspec itself (old-style:
"refs/remotes/$remote/*", new-style: "refs/remotes/$remote/heads/*"), or
(worst case) by introducing a config variable specifying the desired
behavior (defaulting to old-style).

When adding the new rules for looking up shorthand refs (described above),
we should carefully verify that these won't cause regressions when applied
to old-style refspecs in existing repos.

In a later major version we can consider removing the (by then ancient)
implicit refspecs, and any other outdated compatibility measures code in our
ref lookup code.


Have fun! :)

...Johan


[1]: The "refs/remotes/*/tags/v1.7.4" is not hardcoded, but rather the
(default) result of mapping "refs/tags/v1.7.4" through each remote's
refspecs as defined in the config.

[2]: When looking up a shorthand tag name (e.g. v1.7.4): If a local tag
(refs/tags/v1.7.4) is found, then we have an unambiguous match. If no local
tag is found, we look up the tag name in all configured remotes (using the
method described in [1]). If the tag name exists in one or more remotes, and
those remotes all agree on its ultimate object name (after applying e.g.
^{commit} or whatever is appropriate in the context of the lookup), then we
also have an unambiguous match. However, if the tag name exists in multiple
remotes, and they do NOT all agree on its ultimate object name, then the
shorthand tag name is ambiguous and the lookup fails. The user can always
resolve this ambiguity by creating a local tag (refs/tags/v1.7.4) pointing
to the desired object.

[3]: As in [1], the "refs/remotes/$remote/heads/$head" is not hardcoded, but
rather the result of mapping "refs/heads/$head" through the refspecs for
$remote as defined in the config.

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Santi Béjar-2
On Wed, Feb 2, 2011 at 3:21 AM, Johan Herland <[hidden email]> wrote:

> On Wednesday 02 February 2011, Sverre Rabbelier wrote:
>> On Tue, Feb 1, 2011 at 19:14, Jeff King <[hidden email]> wrote:
>> > i.e., make refs/remotes/* an actual mirror of selected parts of the
>> > remote's refs/ hierarchy. And then figure out sane rules for merging
>> > those namespaces into the ref lookup procedure.
>>
>> Jeff, Nguy, are either of you interested in writing up a new/modifying
>> this proposal to be about namespacing everything?
>
> Here's my go at phrasing this in a proposal format. Feel free to revise and
> resend:
>

+1

>
> Proposal:
>
> Currently, git stores remote refs in the local repo by default as follows:
>
>  Remote repo    ->   Local repo
>  ---------------------------------------------------------
>  HEAD                refs/remotes/$remote/HEAD  (implicit)
>  refs/heads/*        refs/remotes/$remote/*
>  refs/tags/*         refs/tags/*                (implicit, autofollow)
>  refs/replace/*      (TBD)
>  refs/notes/*        (TBD)
>
> Several users report that they are confused by the difference in how heads
> and tags are mapped, and by the implicit mappings that are not mentioned in
> the configured refspecs. Also, as users want to share ever more different
> types of refs (replace refs and notes refs have been discussed recently),
> the existing ref mappings (aka. refspecs) do not suggest a natural/intuitive
> mapping for the new ref types.
>
> Instead, we should change the default ref mappings into the following:
>
>  Remote repo    ->   Local repo
>  --------------------------------------------------
>  HEAD                refs/remotes/$remote/HEAD
>  refs/heads/*        refs/remotes/$remote/heads/*
>  refs/tags/*         refs/remotes/$remote/tags/*
>  refs/replace/*      refs/remotes/$remote/replace/*
>  refs/notes/*        refs/remotes/$remote/notes/*

[...]

> - We might want to generalize the handling of "$remote/$head" into allowing
> shorthands like "$remote/$tag", "$remote/$replace" and "$remote/$note" as
> well (provided, of course, that they match unambiguously).

[...]

> [2]: When looking up a shorthand tag name (e.g. v1.7.4): If a local tag
> (refs/tags/v1.7.4) is found, then we have an unambiguous match. If no local
> tag is found, we look up the tag name in all configured remotes (using the
> method described in [1]). If the tag name exists in one or more remotes, and
> those remotes all agree on its ultimate object name (after applying e.g.
> ^{commit} or whatever is appropriate in the context of the lookup), then we
> also have an unambiguous match. However, if the tag name exists in multiple
> remotes, and they do NOT all agree on its ultimate object name, then the
> shorthand tag name is ambiguous and the lookup fails. The user can always
> resolve this ambiguity by creating a local tag (refs/tags/v1.7.4) pointing
> to the desired object.

And the other way around. What would be the output of "git name-rev" ,
"git describe", "--decorate", and such? $remote/tags/$tag?
$remote/$tag? $tag?

I would say $remote/$tag for "git name-rev" and "--decorate" but $tag
for "git describe" as it is usually used to create files, i.e.
git-1.7.4.261.g705f.tar.gz. And I think many people, me included, do
not expect to have an / in the "git describe" output, at least in the
default output (in contrast with the --all flag).

Another point to consider is if we want a default remote for tags, a
config tags.defaultRemote (TBD), defaulting to origin, specifying the
default remote for tags. There would be a hierarchy: local tags,
default remote tags, remote tags. With this if one tag is on multiple
remote the tag from the default remote always wins.

In this way all the tag related input/output would no change much. For
example all the decoration would be $tag instead of origin/tag.

HTH,
Santi
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Johan Herland
On Wednesday 02 February 2011, Santi Béjar wrote:

> On Wednesday 02 February 2011, Johan Herland wrote:
> > Proposal:
> >
> > Currently, git stores remote refs in the local repo by default as
> > follows:
> >
> >  Remote repo    ->   Local repo
> >  ---------------------------------------------------------
> >  HEAD                refs/remotes/$remote/HEAD  (implicit)
> >  refs/heads/*        refs/remotes/$remote/*
> >  refs/tags/*         refs/tags/*         (implicit, autofollow)
> >  refs/replace/*      (TBD)
> >  refs/notes/*        (TBD)
> >
> > Instead, we should change the default ref mappings into the
> > following:
> >
> >  Remote repo    ->   Local repo
> >  --------------------------------------------------
> >  HEAD                refs/remotes/$remote/HEAD
> >  refs/heads/*        refs/remotes/$remote/heads/*
> >  refs/tags/*         refs/remotes/$remote/tags/*
> >  refs/replace/*      refs/remotes/$remote/replace/*
> >  refs/notes/*        refs/remotes/$remote/notes/*
>
> [...]
>
> > - We might want to generalize the handling of "$remote/$head" into
> > allowing shorthands like "$remote/$tag", "$remote/$replace" and
> > "$remote/$note" as well (provided, of course, that they match
> > unambiguously).
>
> [...]
>
> > [2]: When looking up a shorthand tag name (e.g. v1.7.4): If a local
> > tag (refs/tags/v1.7.4) is found, then we have an unambiguous match.
> > If no local tag is found, we look up the tag name in all configured
> > remotes (using the method described in [1]). If the tag name exists
> > in one or more remotes, and those remotes all agree on its ultimate
> > object name (after applying e.g. ^{commit} or whatever is
> > appropriate in the context of the lookup), then we also have an
> > unambiguous match. However, if the tag name exists in multiple
> > remotes, and they do NOT all agree on its ultimate object name,
> > then the shorthand tag name is ambiguous and the lookup fails. The
> > user can always resolve this ambiguity by creating a local tag
> > (refs/tags/v1.7.4) pointing to the desired object.
>
> And the other way around. What would be the output of "git name-rev"
> , "git describe", "--decorate", and such? $remote/tags/$tag?
> $remote/$tag? $tag?
>
> I would say $remote/$tag for "git name-rev" and "--decorate" but $tag
> for "git describe" as it is usually used to create files, i.e.
> git-1.7.4.261.g705f.tar.gz. And I think many people, me included, do
> not expect to have an / in the "git describe" output, at least in the
> default output (in contrast with the --all flag).

Thanks for raising an important point.

I don't buy the file name creation argument, as 'describe' is used from
many different contexts, and file name creation is nowhere documented
as one of its primary objectives.

Still, the objective of 'describe' is to create a human-readable string
that tries to say something meaningful about a commit in relation to
its preceding history, while at the same time uniquely identifying the
commit. The "uniquely identifying" part is taken care of by
the "-g<SHA1>" part of the output, while the initial "<tagname>-<n>"
part makes it human-friendly. Therefore, we only care that the
<tagname> is fairly unambiguous in the mind of the reader. From this
perspective, which of the alternatives makes more sense? I would
disqualify "$remote/$tag" and "$remote/tags/$tag", since the $remote
name is repo-specific, and 'describe' output is often passed around
between multiple developers/repos. Hence, I think that "$tag" is a good
choice for 'describe'. If "$tag" is ambiguous in the current repo, then
an "ambiguous tag" tag warning can be printed, but I would still
use "$tag".

When it comes to 'name-rev' and '--decorate', those are (AFAICS) much
more repo-specific, and seldom passed between users. Also, they don't
have the "-g<SHA1>" part from the 'describe' output. Hence, in this
case, I consider unique identification (unambiguity) much more
important than not displaying $remote names. Therefore, I'd propose
using the shortest unambiguous alternative.

> Another point to consider is if we want a default remote for tags, a
> config tags.defaultRemote (TBD), defaulting to origin, specifying the
> default remote for tags. There would be a hierarchy: local tags,
> default remote tags, remote tags. With this if one tag is on multiple
> remote the tag from the default remote always wins.
>
> In this way all the tag related input/output would no change much.
> For example all the decoration would be $tag instead of origin/tag.

Agreed, tags.defaultRemote (or tags.preferredRemote if I'm allowed to
bikeshed) may be a valuable addition. Another way to achieve this would
be to explicitly copy tags from the preferred remote (e.g. origin)
directly into refs/tags. I.e. in addition to the (new) default tag
refspec

        +refs/tags/*:refs/remotes/origin/tags/*

you could add an _additional_ refspec

        refs/tags/*:refs/tags/*

that would also copy all of origin's tags directly into your local tag
namespace.


Thanks for the feedback! :)

...Johan

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Santi Béjar-2
On Wed, Feb 2, 2011 at 4:51 PM, Johan Herland <[hidden email]> wrote:

> On Wednesday 02 February 2011, Santi Béjar wrote:
>> On Wednesday 02 February 2011, Johan Herland wrote:
>> > Proposal:
>> >
>> > Currently, git stores remote refs in the local repo by default as
>> > follows:
>> >
>> >  Remote repo    ->   Local repo
>> >  ---------------------------------------------------------
>> >  HEAD                refs/remotes/$remote/HEAD  (implicit)
>> >  refs/heads/*        refs/remotes/$remote/*
>> >  refs/tags/*         refs/tags/*         (implicit, autofollow)
>> >  refs/replace/*      (TBD)
>> >  refs/notes/*        (TBD)
>> >
>> > Instead, we should change the default ref mappings into the
>> > following:
>> >
>> >  Remote repo    ->   Local repo
>> >  --------------------------------------------------
>> >  HEAD                refs/remotes/$remote/HEAD
>> >  refs/heads/*        refs/remotes/$remote/heads/*
>> >  refs/tags/*         refs/remotes/$remote/tags/*
>> >  refs/replace/*      refs/remotes/$remote/replace/*
>> >  refs/notes/*        refs/remotes/$remote/notes/*
>>
>> [...]
>>
>> > - We might want to generalize the handling of "$remote/$head" into
>> > allowing shorthands like "$remote/$tag", "$remote/$replace" and
>> > "$remote/$note" as well (provided, of course, that they match
>> > unambiguously).
>>
>> [...]
>>
>> > [2]: When looking up a shorthand tag name (e.g. v1.7.4): If a local
>> > tag (refs/tags/v1.7.4) is found, then we have an unambiguous match.
>> > If no local tag is found, we look up the tag name in all configured
>> > remotes (using the method described in [1]). If the tag name exists
>> > in one or more remotes, and those remotes all agree on its ultimate
>> > object name (after applying e.g. ^{commit} or whatever is
>> > appropriate in the context of the lookup), then we also have an
>> > unambiguous match. However, if the tag name exists in multiple
>> > remotes, and they do NOT all agree on its ultimate object name,
>> > then the shorthand tag name is ambiguous and the lookup fails. The
>> > user can always resolve this ambiguity by creating a local tag
>> > (refs/tags/v1.7.4) pointing to the desired object.
>>
>> And the other way around. What would be the output of "git name-rev"
>> , "git describe", "--decorate", and such? $remote/tags/$tag?
>> $remote/$tag? $tag?
>>
>> I would say $remote/$tag for "git name-rev" and "--decorate" but $tag
>> for "git describe" as it is usually used to create files, i.e.
>> git-1.7.4.261.g705f.tar.gz. And I think many people, me included, do
>> not expect to have an / in the "git describe" output, at least in the
>> default output (in contrast with the --all flag).
>
> Thanks for raising an important point.
>
> I don't buy the file name creation argument, as 'describe' is used from
> many different contexts, and file name creation is nowhere documented
> as one of its primary objectives.

Yes, I know it is used from many different contexts, but one important
one is the creation of the tar files, even git.git's Makefile assumes
this. But as at the end we agree...

>
> Still, the objective of 'describe' is to create a human-readable string
> that tries to say something meaningful about a commit in relation to
> its preceding history, while at the same time uniquely identifying the
> commit. The "uniquely identifying" part is taken care of by
> the "-g<SHA1>" part of the output, while the initial "<tagname>-<n>"
> part makes it human-friendly. Therefore, we only care that the
> <tagname> is fairly unambiguous in the mind of the reader. From this
> perspective, which of the alternatives makes more sense? I would
> disqualify "$remote/$tag" and "$remote/tags/$tag", since the $remote
> name is repo-specific, and 'describe' output is often passed around
> between multiple developers/repos. Hence, I think that "$tag" is a good
> choice for 'describe'. If "$tag" is ambiguous in the current repo, then
> an "ambiguous tag" tag warning can be printed, but I would still
> use "$tag".
>
> When it comes to 'name-rev' and '--decorate', those are (AFAICS) much
> more repo-specific, and seldom passed between users. Also, they don't
> have the "-g<SHA1>" part from the 'describe' output. Hence, in this
> case, I consider unique identification (unambiguity) much more
> important than not displaying $remote names. Therefore, I'd propose
> using the shortest unambiguous alternative.

I agree. Something like this I had in mind :)


>
>> Another point to consider is if we want a default remote for tags, a
>> config tags.defaultRemote (TBD), defaulting to origin, specifying the
>> default remote for tags. There would be a hierarchy: local tags,
>> default remote tags, remote tags. With this if one tag is on multiple
>> remote the tag from the default remote always wins.
>>
>> In this way all the tag related input/output would no change much.
>> For example all the decoration would be $tag instead of origin/tag.
>
> Agreed, tags.defaultRemote (or tags.preferredRemote if I'm allowed to
> bikeshed) may be a valuable addition. Another way to achieve this would
> be to explicitly copy tags from the preferred remote (e.g. origin)
> directly into refs/tags. I.e. in addition to the (new) default tag
> refspec
>
>        +refs/tags/*:refs/remotes/origin/tags/*
>
> you could add an _additional_ refspec
>
>        refs/tags/*:refs/tags/*
>
> that would also copy all of origin's tags directly into your local tag
> namespace.

Yes, you always can add this refspec but I don't want to pollute my
"strict" local tags. And moreover with the config tags.preferredRemote
you can change from one preferred remote to another just changing a
config.

> Thanks for the feedback! :)

Thanks for the proposal!

HTH,
Santi
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Remote tag namespace

Marc Branchaud
In reply to this post by Duy Nguyen
On 11-02-01 10:35 AM, Nguyen Thai Ngoc Duy wrote:

> On Tue, Feb 1, 2011 at 10:07 PM, Marc Branchaud<[hidden email]>  wrote:
>>> Config branch.*.globalTags (perhaps takes a pattern?) may be defined
>>> to create refs/tags/* in addition to refs/remote-tags/<remote>/* when
>>> fetching tags.
>>
>> I may be getting into the weeds prematurely here, but why put the config item
>> under branch.* ?  Or did you mean remote.*.globalTags?  Personally, I don't
>> see a need for this.  I'd rather have the rev-parse machinery search in
>> remote tag namespaces if it can't find anything local.
>
> Ahh.. yeah it's remote.*.globalTags. I don't know, some people might
> find current behavior useful. So instead of dropping it entirely, I'd
> limit it to certain remotes.

IMHO, it's best not to assume what people might want.  Better to wait
for someone to ask for something specific.

[ ...snip... ]

> When tags are put in remote namespace (wherever it actually is),
> git-tag must learn -r like git-branch. I think option name change for
> -a is too late though. When "git-ng" rewrite project comes (that is
> after libgit2 replaces git core), we may have everything consistent
> again.

I think we could start by making "git tag -A" a synonym for "git tag -a"
with a verbose warning when "-a" is used that it'll soon gain a
different meaning.

Also, during the transition "git tag -a" without any other options could
(without the big warning) list all local and remote tags (like "git
branch -a") and if someone wanted to make an annotated tag of the
current tip they could do "git tag -A" or "git tag -a HEAD".

                M.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Duy Nguyen
In reply to this post by Johan Herland
On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]> wrote:

> Migration plan:
> ...
> In v1.8.0, we should default to the new default refspecs when creating new
> remotes. However, existing remotes (created pre-v1.8.0) must continue to
> work as before, so we cannot simply remove the implicit refspecs (or tag
> auto-following). Instead we need to make sure that the implicit refspecs is
> NOT applied to the new-style remotes. Identifying new-style vs. old-style
> remotes can be done by looking at the refspec itself (old-style:
> "refs/remotes/$remote/*", new-style: "refs/remotes/$remote/heads/*"), or
> (worst case) by introducing a config variable specifying the desired
> behavior (defaulting to old-style).

How about convert old style remotes to new style? Should it be done
automatically when new git detects old style remotes, or done by
command, or manually?
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Johan Herland
On Thursday 03 February 2011, Nguyen Thai Ngoc Duy wrote:

> On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]> wrote:
> > Migration plan:
> > ...
> > In v1.8.0, we should default to the new default refspecs when creating
> > new remotes. However, existing remotes (created pre-v1.8.0) must
> > continue to work as before, so we cannot simply remove the implicit
> > refspecs (or tag auto-following). Instead we need to make sure that
> > the implicit refspecs is NOT applied to the new-style remotes.
> > Identifying new-style vs. old-style remotes can be done by looking at
> > the refspec itself (old-style: "refs/remotes/$remote/*", new-style:
> > "refs/remotes/$remote/heads/*"), or (worst case) by introducing a
> > config variable specifying the desired behavior (defaulting to
> > old-style).
>
> How about convert old style remotes to new style? Should it be done
> automatically when new git detects old style remotes, or done by
> command, or manually?

I don't think we want to mess with existing remote refs without the user's
consent, especially since the user might have all kinds of repo-specific
practices tied to the old layout of remote refs.

Providing a command to do it (git remote renew?) is a much better way to go
about it, IMHO. Still, it is vitally important that new git keeps working
with old-style remotes.

Another issue is whether we should automatically make the old-style implicit
refspecs into _explicit_ (but still old-style) refspecs. I.e. when
encountering an old-style remote, new git could automatically add the
following refspecs to the remote:

        +HEAD:refs/remotes/origin/HEAD
    ~refs/tags/*:refs/tags/*


...Johan

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Duy Nguyen
In reply to this post by Johan Herland
On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]> wrote:

> Migration plan:
> ...
> In v1.8.0, we should default to the new default refspecs when creating new
> remotes. However, existing remotes (created pre-v1.8.0) must continue to
> work as before, so we cannot simply remove the implicit refspecs (or tag
> auto-following). Instead we need to make sure that the implicit refspecs is
> NOT applied to the new-style remotes. Identifying new-style vs. old-style
> remotes can be done by looking at the refspec itself (old-style:
> "refs/remotes/$remote/*", new-style: "refs/remotes/$remote/heads/*"), or
> (worst case) by introducing a config variable specifying the desired
> behavior (defaulting to old-style).

I'd prefer config var (remote.*.implicitRules, maybe). We don't
reserve heads, tags... in remote namespace for ourselves. Some users
might have already have branches heads/ant, heads/bee... making new
style detection unreliable.

So I propose add remote.*.implicitRules = false since 1.8.0 for new
remotes as a way to detect new/old style. The default value would be
true.

But I don't want to keep adding remote.*.implicitRules on new remotes
forever. I suppose one year after 1.8.0, the new behavior is
widespread enough. We can then annoy users to add
remote.*.implicitRules for all old remotes. There should be no more
default value after 1-2 years. We then flip the default value and
won't automatically add remote.*.implicitRules = false on new remotes.
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Johan Herland
On Thursday 03 February 2011, Nguyen Thai Ngoc Duy wrote:
> On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]>
wrote:

> > Migration plan:
> > ...
> > In v1.8.0, we should default to the new default refspecs when
> > creating new remotes. However, existing remotes (created
> > pre-v1.8.0) must continue to work as before, so we cannot simply
> > remove the implicit refspecs (or tag auto-following). Instead we
> > need to make sure that the implicit refspecs is NOT applied to the
> > new-style remotes. Identifying new-style vs. old-style remotes can
> > be done by looking at the refspec itself (old-style:
> > "refs/remotes/$remote/*", new-style:
> > "refs/remotes/$remote/heads/*"), or (worst case) by introducing a
> > config variable specifying the desired behavior (defaulting to
> > old-style).
>
> I'd prefer config var (remote.*.implicitRules, maybe). We don't
> reserve heads, tags... in remote namespace for ourselves. Some users
> might have already have branches heads/ant, heads/bee... making new
> style detection unreliable.
>
> So I propose add remote.*.implicitRules = false since 1.8.0 for new
> remotes as a way to detect new/old style. The default value would be
> true.
>
> But I don't want to keep adding remote.*.implicitRules on new remotes
> forever. I suppose one year after 1.8.0, the new behavior is
> widespread enough. We can then annoy users to add
> remote.*.implicitRules for all old remotes. There should be no more
> default value after 1-2 years. We then flip the default value and
> won't automatically add remote.*.implicitRules = false on new
> remotes.

I don't have a problem with this, other than bikeshedding over the
variable name: I find remote.*.implicitFetchRefspecs more descriptive.


...Johan

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Santi Béjar-2
> On Thursday 03 February 2011, Nguyen Thai Ngoc Duy wrote:
>> On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]>
> wrote:
>> > Migration plan:
>> > ...
>> > In v1.8.0, we should default to the new default refspecs when
>> > creating new remotes. However, existing remotes (created
>> > pre-v1.8.0) must continue to work as before, so we cannot simply
>> > remove the implicit refspecs (or tag auto-following). Instead we
>> > need to make sure that the implicit refspecs is NOT applied to the
>> > new-style remotes. Identifying new-style vs. old-style remotes can
>> > be done by looking at the refspec itself (old-style:
>> > "refs/remotes/$remote/*", new-style:
>> > "refs/remotes/$remote/heads/*"), or (worst case) by introducing a
>> > config variable specifying the desired behavior (defaulting to
>> > old-style).
>>
>> I'd prefer config var (remote.*.implicitRules, maybe). We don't
>> reserve heads, tags... in remote namespace for ourselves. Some users
>> might have already have branches heads/ant, heads/bee... making new
>> style detection unreliable.

I don't quite follow the argument. For me the question is how likely
an old-time user has modified the refspec to read
"refs/remotes/$remote/heads/* (new-style). I think this is very, very
unlikely and thus the "heuristic" to detect old/new style works most
of the time and there is no need for a new config/compatibility key.

HTH,
Santi
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Duy Nguyen
On Thu, Feb 3, 2011 at 9:10 PM, Santi Béjar <[hidden email]> wrote:

>> On Thursday 03 February 2011, Nguyen Thai Ngoc Duy wrote:
>>> On Wed, Feb 2, 2011 at 9:21 AM, Johan Herland <[hidden email]>
>> wrote:
>>> > Migration plan:
>>> > ...
>>> > In v1.8.0, we should default to the new default refspecs when
>>> > creating new remotes. However, existing remotes (created
>>> > pre-v1.8.0) must continue to work as before, so we cannot simply
>>> > remove the implicit refspecs (or tag auto-following). Instead we
>>> > need to make sure that the implicit refspecs is NOT applied to the
>>> > new-style remotes. Identifying new-style vs. old-style remotes can
>>> > be done by looking at the refspec itself (old-style:
>>> > "refs/remotes/$remote/*", new-style:
>>> > "refs/remotes/$remote/heads/*"), or (worst case) by introducing a
>>> > config variable specifying the desired behavior (defaulting to
>>> > old-style).
>>>
>>> I'd prefer config var (remote.*.implicitRules, maybe). We don't
>>> reserve heads, tags... in remote namespace for ourselves. Some users
>>> might have already have branches heads/ant, heads/bee... making new
>>> style detection unreliable.
>
> I don't quite follow the argument. For me the question is how likely
> an old-time user has modified the refspec to read
> "refs/remotes/$remote/heads/* (new-style). I think this is very, very
> unlikely and thus the "heuristic" to detect old/new style works most
> of the time and there is no need for a new config/compatibility key.

Personally I don't have any repos that weird, so it's no problem to
me. Maybe I'm overengineering.
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Junio C Hamano
In reply to this post by Johan Herland
Johan Herland <[hidden email]> writes:

> - Remote tags are now stored separate from local tags. When looking up a
> shorthand tag name (e.g. v1.7.4), we should consult local tags
> (refs/tags/v1.7.4) before remote tags (refs/remotes/*/tags/v1.7.4 [1]). See
> [2] for more details.

> - Remote heads have moved into refs/remotes/$remote/heads/*, hence
> invalidating shorthand remote head names, like "origin/master". We should
> change the lookup code, so that a shorthand ref of the form "$remote/$head"
> where "$remote" happens to match a configured remote is eventually expanded
> into lookup for "refs/remotes/$remote/heads/$head" [3].

Keeping 'origin/next' usable is a _must_, _if_ we were to go this route.

> - We might want to generalize the handling of "$remote/$head" into allowing
> shorthands like "$remote/$tag", "$remote/$replace" and "$remote/$note" as
> well (provided, of course, that they match unambiguously).
>
> - All fetch refspecs should be given explicitly.

What do you mean by this?

> Sub-proposal: While we are changing the default refspecs, we should also
> consider whether we want to keep the auto-following behavior that Git
> currently does for tags (don't fetch tags that refer to objects not
> otherwise fetched by another refspec). If we simply make an explicit
> "+refs/tags/*:refs/remotes/$remote/tags/*" refspec, we will lose the auto-
> following behavior. If we do want to keep the auto-following behavior, we
> could for example add a "~" prefix to the refspec to trigger auto-following
> behavior (i.e. this refspec only applies to refs that happen to point at
> objects fetched by way of a different refspec). See
> http://thread.gmane.org/gmane.comp.version-control.git/160503/focus=160795 
> for more details.

You seem to envision "auto-follow" to slurp remote tags in remotes/origin/$tag
namespace.  What should "git fetch --tags $from_there" do?

For some reason, many people seem to be enthused about splitting the tag
namespace, but I am not sure if that is a good thing in general.  Branches
are moving pointers for people to flip around in their local repositories,
and it makes sense to say "My master is a bit ahead of the public one",
but what would we gain by making it _easier_ to add and exchange many tags
with the same name (e.g. refs/remotes/*/tags/v1.7.4 vs refs/tags/v1.7.4),
other than the extra confusion?

While you are talking about drastic reorganization (and rewriting the ref
code to support it), another possible Sub-proposal we may want to consider
is to allow "next" and "next/foo" at the same time.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|

Re: [1.8.0] Provide proper remote ref namespaces

Johan Herland
On Friday 04 February 2011, Junio C Hamano wrote:
> Johan Herland <[hidden email]> writes:
> > - Remote heads have moved into refs/remotes/$remote/heads/*, hence
> > invalidating shorthand remote head names, like "origin/master". We
> > should change the lookup code, so that a shorthand ref of the form
> > "$remote/$head" where "$remote" happens to match a configured remote
> > is eventually expanded into lookup for
> > "refs/remotes/$remote/heads/$head" [3].
>
> Keeping 'origin/next' usable is a _must_, _if_ we were to go this route.

Of course.

> > - All fetch refspecs should be given explicitly.
>
> What do you mean by this?

Today, when you fetch from a remote, the config typically says

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = ...

But this fetch refspec does not tell the full story. In addition to mapping
origin's refs/heads/* into refs/remotes/origin/*, it also fetches origin's  
HEAD into refs/remotes/origin/HEAD, and anything in origin's refs/tags/*
that happen to point to a fetched object is fetched into refs/tags/* (aka.
auto-following tags). These other fetches are not explicitly specified in
the config, but "magically" happen anyway. Instead of having such implicit
refspecs, I'd rather have all fetch refspecs listed explicitly in the
config, like this (for replicating current layout):

[remote "origin"]
        fetch = +HEAD:refs/remotes/origin/HEAD
        fetch = +refs/heads/*:refs/remotes/origin/*
        fetch = ~refs/tags/*:refs/tags/*
        url = ...

or this (in the proposed new layout):

[remote "origin"]
        fetch = +HEAD:refs/remotes/origin/HEAD
        fetch = +refs/heads/*:refs/remotes/origin/heads*
        fetch = +refs/tags/*:refs/remotes/origin/tags/*
        url = ...

> > Sub-proposal: While we are changing the default refspecs, we should
> > also consider whether we want to keep the auto-following behavior that
> > Git currently does for tags (don't fetch tags that refer to objects
> > not otherwise fetched by another refspec). If we simply make an
> > explicit "+refs/tags/*:refs/remotes/$remote/tags/*" refspec, we will
> > lose the auto- following behavior. If we do want to keep the
> > auto-following behavior, we could for example add a "~" prefix to the
> > refspec to trigger auto-following behavior (i.e. this refspec only
> > applies to refs that happen to point at objects fetched by way of a
> > different refspec). See
> > http://thread.gmane.org/gmane.comp.version-control.git/160503/focus=160
> > 795 for more details.
>
> You seem to envision "auto-follow" to slurp remote tags in
> remotes/origin/$tag namespace. What should "git fetch --tags $from_there"
> do?

I would propose that "git fetch --tags $from_there" follows these steps:

1. Enumerate the (implicit or explicit) fetch refspecs for the given remote.

2. Map "refs/tags/*" through the refspecs to find where the remote tags
should be stored in the local repo.

3. If the matching refspec starts with "~" (auto-following), disregard the
"~" (since --tags disables auto-following).

4. Slurp remote tags into the location found in step #2.

Since we map through the refspec, the remote tags end up where the user
expect to find them: in refs/tags/* for old-style remotes, or in
refs/remotes/$from_there/tags/* for new-style remotes.

> For some reason, many people seem to be enthused about splitting the tag
> namespace, but I am not sure if that is a good thing in general.
> Branches are moving pointers for people to flip around in their local
> repositories, and it makes sense to say "My master is a bit ahead of the
> public one", but what would we gain by making it _easier_ to add and
> exchange many tags with the same name (e.g. refs/remotes/*/tags/v1.7.4
> vs refs/tags/v1.7.4), other than the extra confusion?

First, I should state that making tags into moving pointers is not something
I support, nor is it part of this proposal. Tags should still very much
refuse to be moved (except when forced).

Having said that, there are real situations where users encounter collisions
in the shared tag namespace. A rare (but plausible) scenario arise when two
developers create (and publish) conflicting tags in their repos. A more
common scenario that I have encountered at $dayjob, is where two parallel
(semi-related) projects are developed in separate repos (with different
versioning because of separate release schedules), and I need to interface
with both repos from a single local repo. Each of the remote repos have
their own "v1.0" tag, but my repo can only hold one such tag. Which of those
tags end up "winning" in my local repo depends on my fetch order.

Git already has code to discover ambiguous ref names, and we have powerful
tools for inspecting the history and diffs between local and remote
branches. But because we conflate tags into a single namespace, we cannot
easily use these tools when circumstances conspire to produce conflicting
tags.

Putting remote tags into separate namespaces allows us to use the same tools
that we use on remote branches, to discover and inspect conflicting tags
when (if only rarely) they do happen.

Another advantage of splitting tags into separate namespaces is that the
"source" or "domain" of a tag becomes slightly less foggy: Consider a tag
"foo" that may exist as refs/remotes/origin/tags/foo (remote/public) and/or
as refs/tags/foo (local/private). If it exists only locally, it may be a
hint that this is a "private" tag (not intended for public consumption). If
it exists only remotely, it's obviously a public tag. If it exists both
locally and remotely (without conflict), it may indicate that this is a
public tag that was originally created in this repo.

> While you are talking about drastic reorganization (and rewriting the ref
> code to support it), another possible Sub-proposal we may want to
> consider is to allow "next" and "next/foo" at the same time.

Interesting. I haven't followed this discussion lately (if there has been
any), but I guess we need to find a new way to organize loose refs that
doesn't cause file vs. directory problems. Obviously, the packed-refs format
should have no inherent problem with these refs, but I guess we can't drop
loose ref support completely.

One sort-of-workaround could be to detect when "next" vs. "next/foo"
happens, and simply force one of them to be a packed ref.


Have fun! :)

...Johan

--
Johan Herland, <[hidden email]>
www.herland.net
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
1234 ... 6