{"thread":{"id":"25611","subject":"[PATCH] Remove restriction on notes ref base","startedAt":"2010-11-02T00:16:43Z","lastAt":"2010-11-05T15:11:34Z","messageCount":21,"participants":["Kenny Root","Jonathan Nieder","Johan Herland","Shawn Pearce","Jeff King","Junio C Hamano","Sverre Rabbelier","Marc Branchaud","Chris Forbes"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"154950","messageId":"1288657003-17802-1-git-send-email-kroot@google.com","threadId":"25611","inReplyTo":null,"subject":"[PATCH] Remove restriction on notes ref base","fromName":"Kenny Root","fromEmail":"kroot@google.com","sentAt":"2010-11-02T00:16:43Z","receivedAt":"2010-11-02T00:16:43Z","isPatch":true,"sender":{"key":"kroot@google.com","avatar":null},"body":"Git notes were restricted to refs/notes/* in the command line utilities,\nbut setting things like GIT_NOTES_REF to something outside of that\nstructure would work.\n\nThis removes the restrictions on the git notes command line interface.\n\nSigned-off-by: Kenny Root <kroot@google.com>\n---\n builtin/notes.c |   11 ++---------\n 1 files changed, 2 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 6d07aac..9acce7b 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -343,11 +343,7 @@ static int notes_rewrite_config(const char *k, const char *v, void *cb)\n \t} else if (!c->refs_from_env && !strcmp(k, \"notes.rewriteref\")) {\n \t\t/* note that a refs/ prefix is implied in the\n \t\t * underlying for_each_glob_ref */\n-\t\tif (!prefixcmp(v, \"refs/notes/\"))\n-\t\t\tstring_list_add_refs_by_glob(c->refs, v);\n-\t\telse\n-\t\t\twarning(\"Refusing to rewrite notes in %s\"\n-\t\t\t\t\" (outside of refs/notes/)\", v);\n+\t\tstring_list_add_refs_by_glob(c->refs, v);\n \t\treturn 0;\n \t}\n \n@@ -473,9 +469,6 @@ static struct notes_tree *init_notes_check(const char *subcommand)\n \tinit_notes(NULL, NULL, NULL, 0);\n \tt = &default_notes_tree;\n \n-\tif (prefixcmp(t->ref, \"refs/notes/\"))\n-\t\tdie(\"Refusing to %s notes in %s (outside of refs/notes/)\",\n-\t\t    subcommand, t->ref);\n \treturn t;\n }\n \n@@ -844,7 +837,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix)\n \n \tif (override_notes_ref) {\n \t\tstruct strbuf sb = STRBUF_INIT;\n-\t\tif (!prefixcmp(override_notes_ref, \"refs/notes/\"))\n+\t\tif (!prefixcmp(override_notes_ref, \"refs/\"))\n \t\t\t/* we're happy */;\n \t\telse if (!prefixcmp(override_notes_ref, \"notes/\"))\n \t\t\tstrbuf_addstr(&sb, \"refs/\");\n-- \n1.7.3.1\n"},{"id":"154952","messageId":"20101102065208.GA4280@burratino","threadId":"25611","inReplyTo":"1288657003-17802-1-git-send-email-kroot@google.com","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-02T06:52:08Z","receivedAt":"2010-11-02T06:52:08Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"(+cc: Johan, Thomas)\n\nKenny Root wrote:\n\n> Git notes were restricted to refs/notes/* in the command line utilities,\n> but setting things like GIT_NOTES_REF to something outside of that\n> structure would work.\n> \n> This removes the restrictions on the git notes command line interface.\n\nCould you explain what those restrictions are (perhaps through an\nexample in the form of a patch to the t/ subdirectory)?\n\nCc-ing some people more knowledgeable about notes than I am; maybe\nthey can give more information about what this notes.rewriteref\nprotection and other check are about.\n\nJonathan\n\n[patch follows for their convenience.]\n> Signed-off-by: Kenny Root <kroot@google.com>\n> ---\n>  builtin/notes.c |   11 ++---------\n>  1 files changed, 2 insertions(+), 9 deletions(-)\n> \n> diff --git a/builtin/notes.c b/builtin/notes.c\n> index 6d07aac..9acce7b 100644\n> --- a/builtin/notes.c\n> +++ b/builtin/notes.c\n> @@ -343,11 +343,7 @@ static int notes_rewrite_config(const char *k, const char *v, void *cb)\n>  \t} else if (!c->refs_from_env && !strcmp(k, \"notes.rewriteref\")) {\n>  \t\t/* note that a refs/ prefix is implied in the\n>  \t\t * underlying for_each_glob_ref */\n> -\t\tif (!prefixcmp(v, \"refs/notes/\"))\n> -\t\t\tstring_list_add_refs_by_glob(c->refs, v);\n> -\t\telse\n> -\t\t\twarning(\"Refusing to rewrite notes in %s\"\n> -\t\t\t\t\" (outside of refs/notes/)\", v);\n> +\t\tstring_list_add_refs_by_glob(c->refs, v);\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -473,9 +469,6 @@ static struct notes_tree *init_notes_check(const char *subcommand)\n>  \tinit_notes(NULL, NULL, NULL, 0);\n>  \tt = &default_notes_tree;\n>  \n> -\tif (prefixcmp(t->ref, \"refs/notes/\"))\n> -\t\tdie(\"Refusing to %s notes in %s (outside of refs/notes/)\",\n> -\t\t    subcommand, t->ref);\n>  \treturn t;\n>  }\n>  \n> @@ -844,7 +837,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix)\n>  \n>  \tif (override_notes_ref) {\n>  \t\tstruct strbuf sb = STRBUF_INIT;\n> -\t\tif (!prefixcmp(override_notes_ref, \"refs/notes/\"))\n> +\t\tif (!prefixcmp(override_notes_ref, \"refs/\"))\n>  \t\t\t/* we're happy */;\n>  \t\telse if (!prefixcmp(override_notes_ref, \"notes/\"))\n>  \t\t\tstrbuf_addstr(&sb, \"refs/\");\n> -- \n"},{"id":"154958","messageId":"201011020948.22677.johan@herland.net","threadId":"25611","inReplyTo":"20101102065208.GA4280@burratino","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-02T08:48:22Z","receivedAt":"2010-11-02T08:48:22Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Tuesday 02 November 2010, Jonathan Nieder wrote:\n> (+cc: Johan, Thomas)\n> \n> Kenny Root wrote:\n> > Git notes were restricted to refs/notes/* in the command line\n> > utilities, but setting things like GIT_NOTES_REF to something outside\n> > of that structure would work.\n> > \n> > This removes the restrictions on the git notes command line interface.\n\nWhy do you need to set GIT_NOTES_REF to something outside refs/notes/ at \nall?\n\n> Could you explain what those restrictions are (perhaps through an\n> example in the form of a patch to the t/ subdirectory)?\n\nYes, please do. As it stands, I'm pretty sure the patch below breaks at \nleast TCs t3301.4 and t3301.5.\n\n> Cc-ing some people more knowledgeable about notes than I am; maybe\n> they can give more information about what this notes.rewriteref\n> protection and other check are about.\n\nWell, I guess we originally decided to limit notes refs to within \nrefs/notes/ in order to clearly separate notes from non-notes, and to \nprevent notes code from accidentally messing up non-notes refs.\n\nLater, we have discovered that in order to work with remote notes refs, we \nprobably have to lift this restriction, and allow (at least) notes refs \nsomewhere within refs/remotes/, e.g. refs/remotes/*/notes/.\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/159469/focus=159703 \nand its sub-thread contains more discussion on sharing notes with remote \nrepos.\n\nSo, in conclusion, this patch is a move in the right direction, but in some \nrespects it might be going a bit _too_ far: Maybe we should restrict notes \nto refs/notes/ and refs/remotes/*/notes/? ...or maybe I'm too paranoid, and \nallowing notes \"everywhere\" is ok. Then again, in other respects this patch \nisn't going far enough, since it doesn't deal with setting up the refspecs \nneeded to make notes sharing easy and straighforward for end users.\n\n> [patch follows for their convenience.]\n> [...]\n> > @@ -844,7 +837,7 @@ int cmd_notes(int argc, const char **argv, const\n> > char *prefix)\n> > \n> >  \tif (override_notes_ref) {\n> >  \t\n> >  \t\tstruct strbuf sb = STRBUF_INIT;\n> > \n> > -\t\tif (!prefixcmp(override_notes_ref, \"refs/notes/\"))\n> > +\t\tif (!prefixcmp(override_notes_ref, \"refs/\"))\n> > \n> >  \t\t\t/* we're happy */;\n> >  \t\t\n> >  \t\telse if (!prefixcmp(override_notes_ref, \"notes/\"))\n> >  \t\t\n> >  \t\t\tstrbuf_addstr(&sb, \"refs/\");\n\nFTR, this hunk will surely conflict with the introduction of \nexpand_notes_ref() which is in patch 09/23 in the 'git notes merge' series \nin 'pu'.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"154967","messageId":"AANLkTinN1UXSmkxOg59pT_xVd2eWS0Ms2sgAweLv7hbg@mail.gmail.com","threadId":"25611","inReplyTo":"201011020948.22677.johan@herland.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-11-02T14:11:45Z","receivedAt":"2010-11-02T14:11:45Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"On Tue, Nov 2, 2010 at 1:48 AM, Johan Herland <johan@herland.net> wrote:\n> On Tuesday 02 November 2010, Jonathan Nieder wrote:\n>> (+cc: Johan, Thomas)\n>>\n>> Kenny Root wrote:\n>> > Git notes were restricted to refs/notes/* in the command line\n>> > utilities, but setting things like GIT_NOTES_REF to something outside\n>> > of that structure would work.\n>> >\n>> > This removes the restrictions on the git notes command line interface.\n>\n> Why do you need to set GIT_NOTES_REF to something outside refs/notes/ at\n> all?\n\nI wanted Kenny to create a notes branch called refs/meta/bad-commits,\nand put that inside of one of our Gerrit Code Review server\nrepositories.  We want to extend Gerrit Code Review to check to see if\nany commit in the incoming pack appears in the bad-commits with a\nnote.  If it does, it will reject the push.  This allows a repository\nowner to ban certain commits from re-entering a repository once they\nhave done a filter-branch or rebase to rewrite a particular item out\nof history.\n\nI didn't want to use refs/notes/bad-commits because its not really an\nannotation you would be looking at with git log.  But we do want to\nhave a log of who banned particular SHA-1s from entering the\nrepository, and being able to push that branch from a workstation to\nthe server is a convenient way to edit that list of banned SHA-1s.\nDuring prototyping Kenny discovered you can't use `git note --ref\nrefs/meta/bad-commits`.  Which means a server administrator wouldn't\nbe able to edit the list directly in the repository.  Hence this\npatch.\n\n>> Cc-ing some people more knowledgeable about notes than I am; maybe\n>> they can give more information about what this notes.rewriteref\n>> protection and other check are about.\n>\n> Well, I guess we originally decided to limit notes refs to within\n> refs/notes/ in order to clearly separate notes from non-notes, and to\n> prevent notes code from accidentally messing up non-notes refs.\n\nI guess I can see some logic in this.  But the documentation says\n--ref accepts a qualified ref name, and then proceeds to assume that a\nstring that starts with \"refs/\" (like \"refs/meta/bad-commits\") should\nactually be \"refs/notes/refs/meta/bad-commits\".  That's a bug in the\nUI and/or documentation.  If we are given a string starting with\n\"refs/\" and its documented as taking a qualified name, that's\nqualified and should either be rejected, or should be taken as-is.\n\nI think the docs are correct, and the code is buggy.  If the user\nasked us to edit refs/meta/bad-commits, we should.  If the user asked\nus to edit refs/heads/my-branch... well, they asked us to edit it.\n:-)\n\nA better safety measure might be to sniff the ref's contents and see\nwhat it is.  If the top level directory has a number of non-note like\nentries, we should abort editing the branch.  Its not common for users\nto name their directories \"02\" and \"fe\".\n\n-- \nShawn.\n"},{"id":"154969","messageId":"20101102142931.GA31394@sigill.intra.peff.net","threadId":"25611","inReplyTo":"AANLkTinN1UXSmkxOg59pT_xVd2eWS0Ms2sgAweLv7hbg@mail.gmail.com","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-02T14:29:31Z","receivedAt":"2010-11-02T14:29:31Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Nov 02, 2010 at 07:11:45AM -0700, Shawn O. Pearce wrote:\n\n> I didn't want to use refs/notes/bad-commits because its not really an\n> annotation you would be looking at with git log.  But we do want to\n> have a log of who banned particular SHA-1s from entering the\n> repository, and being able to push that branch from a workstation to\n> the server is a convenient way to edit that list of banned SHA-1s.\n\nFWIW, I use refs/notes/cache/textconv/* to store textconv caches, and\nthere is no problem. Unless somebody specifically configures\nGIT_NOTES_REF or notes.displayRef to see them, log should never look at\nthem.\n\nSo I think you are being overly cautious. That being said:\n\n> I think the docs are correct, and the code is buggy.  If the user\n> asked us to edit refs/meta/bad-commits, we should.  If the user asked\n> us to edit refs/heads/my-branch... well, they asked us to edit it.\n> :-)\n\nI agree. This part of git is unlike most other parts, which tend to DWYM\nwith a partial ref (by prepending refs/heads, refs/tags, etc), but still\naccept a full ref if the user really feels like organizing their refs\ndifferently.\n\n> A better safety measure might be to sniff the ref's contents and see\n> what it is.  If the top level directory has a number of non-note like\n> entries, we should abort editing the branch.  Its not common for users\n> to name their directories \"02\" and \"fe\".\n\nAgreed.\n\n-Peff\n"},{"id":"154973","messageId":"201011021624.10803.johan@herland.net","threadId":"25611","inReplyTo":"AANLkTinN1UXSmkxOg59pT_xVd2eWS0Ms2sgAweLv7hbg@mail.gmail.com","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-02T15:24:10Z","receivedAt":"2010-11-02T15:24:10Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Tuesday 02 November 2010, Shawn Pearce wrote:\n> On Tue, Nov 2, 2010 at 1:48 AM, Johan Herland wrote:\n> > On Tuesday 02 November 2010, Jonathan Nieder wrote:\n> >> (+cc: Johan, Thomas)\n> >>\n> >> Kenny Root wrote:\n> >> > Git notes were restricted to refs/notes/* in the command line\n> >> > utilities, but setting things like GIT_NOTES_REF to something\n> >> > outside of that structure would work.\n> >> >\n> >> > This removes the restrictions on the git notes command line\n> >> > interface.\n> >\n> > Why do you need to set GIT_NOTES_REF to something outside\n> > refs/notes/ at all?\n>\n> I wanted Kenny to create a notes branch called refs/meta/bad-commits,\n> and put that inside of one of our Gerrit Code Review server\n> repositories.  We want to extend Gerrit Code Review to check to see\n> if any commit in the incoming pack appears in the bad-commits with a\n> note.  If it does, it will reject the push.  This allows a repository\n> owner to ban certain commits from re-entering a repository once they\n> have done a filter-branch or rebase to rewrite a particular item out\n> of history.\n\nAh. Nice feature. Yet another use case for 'git notes' to add to my \nlist... :)\n\n> I didn't want to use refs/notes/bad-commits because its not really an\n> annotation you would be looking at with git log. But we do want to\n> have a log of who banned particular SHA-1s from entering the\n> repository, and being able to push that branch from a workstation to\n> the server is a convenient way to edit that list of banned SHA-1s.\n> During prototyping Kenny discovered you can't use `git note --ref\n> refs/meta/bad-commits`.  Which means a server administrator wouldn't\n> be able to edit the list directly in the repository.  Hence this\n> patch.\n\nOk, so you're using notes to annotate commits that should NOT exist in \nyour repo. In other words (from the code's POV) you are annotating SHA1 \nsums that (hopefully) don't exist as objects in your repo.\n\nThe notes code will happily do this (and I don't plan on changing this \nbehaviour), but you should still know that this is more a side-effect \nof the current implementation than part of the design specification. \nOther notes implementations (jgit?) will need to keep this extra \nrequirement in mind.\n\nAlso, if you run 'git notes prune' on your notes ref, it will (as \nspecified) happily purge all notes to non-existing objects.\n\n> >> Cc-ing some people more knowledgeable about notes than I am; maybe\n> >> they can give more information about what this notes.rewriteref\n> >> protection and other check are about.\n> >\n> > Well, I guess we originally decided to limit notes refs to within\n> > refs/notes/ in order to clearly separate notes from non-notes, and\n> > to prevent notes code from accidentally messing up non-notes refs.\n>\n> I guess I can see some logic in this.  But the documentation says\n> --ref accepts a qualified ref name, and then proceeds to assume that\n> a string that starts with \"refs/\" (like \"refs/meta/bad-commits\")\n> should actually be \"refs/notes/refs/meta/bad-commits\".  That's a bug\n> in the UI and/or documentation.  If we are given a string starting\n> with \"refs/\" and its documented as taking a qualified name, that's\n> qualified and should either be rejected, or should be taken as-is.\n>\n> I think the docs are correct, and the code is buggy.  If the user\n> asked us to edit refs/meta/bad-commits, we should.  If the user asked\n> us to edit refs/heads/my-branch... well, they asked us to edit it.\n>\n> :-)\n\nOk, we've probably been too conservative by trying to restrict where \nusers put notes. As I said in the earlier email, we need to loosen this \nup in any case, in order to share notes with remote repos.\n\n> A better safety measure might be to sniff the ref's contents and see\n> what it is.  If the top level directory has a number of non-note like\n> entries, we should abort editing the branch.  Its not common for\n> users to name their directories \"02\" and \"fe\".\n\nGood idea. We should probably add something like this to the bottom of \nnotes.c:init_notes() (UNTESTED - not even compiled):\n\n  unsigned int i, empty_tree = 1;\n\n  for (i = 0; i < 16; i++) {\n  \tif (t->root[i]) {\n  \t\tempty_tree = 0;\n  \t\tbreak;\n  \t}\n  }\n\n  /* If no notes and >0 non-notes, this is probably not a notes tree */\n  if (empty_tree && t->first_non_note)\n  \tdie(\"'%s' doesn't look like a valid notes tree\", t->ref);\n\n\nHave fun! :)\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"154990","messageId":"7vsjzj1v49.fsf@alter.siamese.dyndns.org","threadId":"25611","inReplyTo":"AANLkTinN1UXSmkxOg59pT_xVd2eWS0Ms2sgAweLv7hbg@mail.gmail.com","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-11-02T17:41:10Z","receivedAt":"2010-11-02T17:41:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Pearce <spearce@spearce.org> writes:\n\n> I didn't want to use refs/notes/bad-commits because its not really an\n> annotation you would be looking at with git log.\n\nWhy not?  Within a repository with bad commits, you would want an option\nto have them applied to bad commits you still have, no?\n\nI am still torn with this patch, and I say \"still\" for a reason.  Even\nthough notes are implemented as commits, they are not commits on a part of\nnormal histories, and restriction of them within refs/notes hierarchy at\nleast is a safety measure (it is easy to loosen a restriction later, but\nit is hard to let people loose first and then later restrict).  While a\npurist in me says that GIT_NOTES_REF and command line option _should_\nenforce the same restriction, keeping the more obscure GIT_NOTES_REF\ninterface a bit looser gives us an escape hatch.\n\nAs to remote interface, refs/remotes/$remotes/ hierarchy corresponds to\nthe local refs/heads/ interface, so I do not think we will change the\ndefault mapping we document (and have \"clone\" prepare) to place notes\nobtained from elsewhere in refs/remotes/ hierarchy (we do not do that for\ntags neither), so I think Johan's point is an independent issue.\n"},{"id":"155008","messageId":"201011022358.11340.johan@herland.net","threadId":"25611","inReplyTo":"7vsjzj1v49.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-02T22:58:11Z","receivedAt":"2010-11-02T22:58:11Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Tuesday 02 November 2010, Junio C Hamano wrote:\n> As to remote interface, refs/remotes/$remotes/ hierarchy corresponds to\n> the local refs/heads/ interface, so I do not think we will change the\n> default mapping we document (and have \"clone\" prepare) to place notes\n> obtained from elsewhere in refs/remotes/ hierarchy (we do not do that for\n> tags neither), so I think Johan's point is an independent issue.\n\nI assume that means you'd rather have remote-tracking notes refs live under \nrefs/notes. So, to avoid collisions with local notes refs (and remote-\ntracking notes refs from _other_ remote), we probably want to store them \nunder refs/notes/remotes/$remote/. I have no problem with that.\n\nAlthough I'm starting to wonder whether our remote -> local refspec mappings \nare getting too varied (i.e. confusing). Currently we have:\n\n  Remote repo    ->   Local repo\n  ------------------------------------------------\n  refs/heads/*        refs/remotes/$remote/*\n  refs/tags/*         refs/tags/*\n\n...and soon we may also have:\n  refs/notes/*        refs/notes/remotes/$remote/*\n\nOf these, the first is specified in the config, the second is \nimplicit/magic, and the third would be specified in the config.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"155198","messageId":"62BAFF6485708A40A8955546574E52655362DE@server01.FarmWorks.local","threadId":"25611","inReplyTo":"201011022358.11340.johan@herland.net","subject":"RE: [PATCH] Remove restriction on notes ref base","fromName":"Chris Forbes","fromEmail":"chrisf@farmworkspfs.co.nz","sentAt":"2010-11-02T23:28:32Z","receivedAt":"2010-11-02T23:28:32Z","isPatch":true,"sender":{"key":"chrisf@farmworkspfs.co.nz","avatar":null},"body":"Hi\n\n> Although I'm starting to wonder whether our remote -> local refspec\nmappings \n> are getting too varied (i.e. confusing). Currently we have:\n\n>  Remote repo    ->   Local repo\n>  ------------------------------------------------\n>  refs/heads/*        refs/remotes/$remote/*\n>  refs/tags/*         refs/tags/*\n\nWhat's the rationale for the implicit/magic behaviour for tags? It\ncauses plenty of confusion for new users, etc.\n\n-- Chris Forbes\n"},{"id":"155036","messageId":"20101103064137.GC7606@burratino","threadId":"25611","inReplyTo":"201011022358.11340.johan@herland.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-03T06:41:37Z","receivedAt":"2010-11-03T06:41:37Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Johan Herland wrote:\n\n> Although I'm starting to wonder whether our remote -> local refspec mappings \n> are getting too varied (i.e. confusing). Currently we have:\n> \n>   Remote repo    ->   Local repo\n>   ------------------------------------------------\n>   refs/heads/*        refs/remotes/$remote/*\n>   refs/tags/*         refs/tags/*\n> \n> ...and soon we may also have:\n>   refs/notes/*        refs/notes/remotes/$remote/*\n\nHow about\n\n    refs/notes/*        refs/notes/$remote/*\n\n?\n\nPlus side: shorter magic prefix to remember,\n           --notes-ref=charon/full would work with the\n           current --notes-ref dwimery.\nDownside: potential for name conflicts?\n"},{"id":"155053","messageId":"7vsjzixty5.fsf@alter.siamese.dyndns.org","threadId":"25611","inReplyTo":"20101103064137.GC7606@burratino","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-11-03T16:17:38Z","receivedAt":"2010-11-03T16:17:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> How about\n>\n>     refs/notes/*        refs/notes/$remote/*\n>\n> ?\n\nI was actually thinking more along the lines of \"not keeping track of\nremote state at all\".  We don't do that for tags either.\n"},{"id":"155054","messageId":"AANLkTin_NuzQocOab+w=B3Ka+n22j2-OXQu8=J6uzByS@mail.gmail.com","threadId":"25611","inReplyTo":"7vsjzixty5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-11-03T16:30:00Z","receivedAt":"2010-11-03T16:30:00Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Wed, Nov 3, 2010 at 17:17, Junio C Hamano <gitster@pobox.com> wrote:\n> I was actually thinking more along the lines of \"not keeping track of\n> remote state at all\".  We don't do that for tags either.\n\nI would rather see us go the other way (and make the tags refspec put\ntags under refs/tags/remotes/.../). I can understand not scoping tags\n(since they're supposed to be immutable, and are usually global), but\nI don't think the same holds for notes. Notes _are_ versioned, and\nit's expected that users will collaborate.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"155072","messageId":"20101103163524.GB12934@burratino","threadId":"25611","inReplyTo":"7vsjzixty5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-03T16:35:24Z","receivedAt":"2010-11-03T16:35:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n\n>> How about\n>>\n>>     refs/notes/*        refs/notes/$remote/*\n>>\n>> ?\n>\n> I was actually thinking more along the lines of \"not keeping track of\n> remote state at all\".  We don't do that for tags either.\n\nWhat would be the behavior when a remote and local notes ref have the\nsame name?\n\nTags are supposed to be universal and never change, so that doesn't\ncome up.  With branches and notes trees, one can impose a requirement\nthat the remote and local refs never have the same name (the \"no\nseparate remotes\" layout) but I think that runs into problems from\nboth ends:\n\nWhen the remote and local notes are written by the same person, it\nseems like busy work to ask that person to give different names for\nthe same branch at different installations.\n\nIn a distributed world where many developers might not even know\nabout each other's repositories, name conflicts on development\nbranches would seem to be inevitable.\n\n home> ... hack hack hack ...\n home> git notes add some-commit;\t# hmm, noticed something\n home> ... hack hack hack ...\n\n Time to go to work...\n\n work> ... hack hack hack ...\n work> git notes add another-commit\n work> ... hack hack hack ...\n work> git fetch home;\t\t\t# grabbing notes from home.\n work> git notes merge home/commits\n work> git push;\t\t\t# publish.\n\nStill, as long as the default can be overridden (even if only on a\nper-remote basis), I wouldn't mind.  Maybe this way of using notes\nwould be unusual and the no-separate-remotes layout supports some\nother use case better.\n"},{"id":"155101","messageId":"201011040149.47968.johan@herland.net","threadId":"25611","inReplyTo":"AANLkTin_NuzQocOab+w=B3Ka+n22j2-OXQu8=J6uzByS@mail.gmail.com","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-04T00:49:47Z","receivedAt":"2010-11-04T00:49:47Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wednesday 03 November 2010, Sverre Rabbelier wrote:\n> On Wed, Nov 3, 2010 at 17:17, Junio C Hamano <gitster@pobox.com> wrote:\n> > I was actually thinking more along the lines of \"not keeping track of\n> > remote state at all\".  We don't do that for tags either.\n> \n> I would rather see us go the other way (and make the tags refspec put\n> tags under refs/tags/remotes/.../). I can understand not scoping tags\n> (since they're supposed to be immutable, and are usually global), but\n> I don't think the same holds for notes. Notes _are_ versioned, and\n> it's expected that users will collaborate.\n\nAgreed. I don't see how you can easily share and manipulate notes between \nrepos _without_ keeping the remote state separate from the local state.\n\n\nI'm probably gonna be flamed for this, but I'd like to go even further, and \n- for a future major version of Git - reconsider Git's default refspecs. \nCurrently we have:\n\n  Remote repo    ->   Local repo\n  ------------------------------------------------\n  refs/heads/*        refs/remotes/$remote/*\n  refs/tags/*         refs/tags/*\n  refs/notes/*        ???\n\nOf these, the first is specified in the config, the second is \nimplicit/magic, and the third would be specified in the config.\n\nI'd probably suggest a more straightforward (and hopefully less confusing) \nsetup like this:\n\n  Remote repo    ->   Local repo\n  ------------------------------------------------\n  refs/heads/*        refs/remotes/$remote/heads/*\n  refs/tags/*         refs/remotes/$remote/tags/*\n  refs/notes/*        refs/remotes/$remote/notes/*\n\n...and these would all be set in the config, i.e. no implicit/magic \nrefspecs.\n\nNow, there would obviously need to be some accompanying changes:\n\nWe would, for example, extend the ref disambiguation of <name> (as \ndocumented in the \"SPECIFYING REVISIONS\" section of git-rev-parse(1)), so \nthat in the cases where <name> is of the form \"<foo>/<bar>\" AND <foo> is an \nexisting remote, we also check for the following refs (after none of the \nexisting checks have returned a match):\n\n  7. refs/remotes/<foo>/tags/<bar>\n  8. refs/remotes/<foo>/heads/<bar>\n\nWe would also need similar disambiguation rules for notes refs, e.g.:\n\n  1. $GIT_DIR/<name>\n  2. refs/notes/<name>\n  3. refs/remotes/<foo>/notes/<bar> (when <name> is of the form <foo>/<bar>)\n\nWith these rules, we could use \"origin/master\", \"origin/v1.2.3\" and \n\"origin/bugnotes\" to refer to \"refs/remotes/origin/heads/master\", \n\"refs/remotes/origin/tags/v1.2.3\" and \"refs/remotes/origin/notes/bugnotes\" \nrespectively.\n\nAs a bonus, we'd get better handling of conflicting tag names: If e.g. \nremotes \"alice\" and \"bob\" each have a tag \"xyzzy\" pointing to different \nobjects, you could reference and compare both tags (using \"alice/xyzzy\" and \n\"bob/xyzzy\", respectively), and optionally set your own local tag \n(\"refs/tags/xyzzy\") to match either of them.\n\n\n...Johan (scrambles for a flame retardant suit)\n\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"155105","messageId":"AANLkTimDyAatzEXGi_q+1+3x5p5SXGaap2Aqwr+d3Nhk@mail.gmail.com","threadId":"25611","inReplyTo":"201011040149.47968.johan@herland.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-11-04T01:00:12Z","receivedAt":"2010-11-04T01:00:12Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Nov 4, 2010 at 01:49, Johan Herland <johan@herland.net> wrote:\n> ...Johan (scrambles for a flame retardant suit)\n\nI for one, have thought about this design, and it's probably how I\nwill represent refs for hg remotes (for git-remote-hg). E.g.:\n\n* refs/remotes/<some-hg-remote>/heads\n* refs/remotes/<some-hg-remote>/tags\n* refs/remotes/<some-hg-remote>/branches\n\nSo, no retardant suit needed as far as I'm concerned :)\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"155169","messageId":"4CD2C49A.8010309@xiplink.com","threadId":"25611","inReplyTo":"201011040149.47968.johan@herland.net","subject":"Tag refspecs (was Re: [PATCH] Remove restriction on notes ref base)","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2010-11-04T14:35:06Z","receivedAt":"2010-11-04T14:35:06Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 10-11-03 08:49 PM, Johan Herland wrote:\n> On Wednesday 03 November 2010, Sverre Rabbelier wrote:\n>> On Wed, Nov 3, 2010 at 17:17, Junio C Hamano <gitster@pobox.com> wrote:\n>>> I was actually thinking more along the lines of \"not keeping track of\n>>> remote state at all\".  We don't do that for tags either.\n>>\n>> I would rather see us go the other way (and make the tags refspec put\n>> tags under refs/tags/remotes/.../). I can understand not scoping tags\n>> (since they're supposed to be immutable, and are usually global), but\n>> I don't think the same holds for notes. Notes _are_ versioned, and\n>> it's expected that users will collaborate.\n> \n> Agreed. I don't see how you can easily share and manipulate notes between \n> repos _without_ keeping the remote state separate from the local state.\n> \n> \n> I'm probably gonna be flamed for this, but I'd like to go even further, and \n> - for a future major version of Git - reconsider Git's default refspecs. \n> Currently we have:\n> \n>   Remote repo    ->   Local repo\n>   ------------------------------------------------\n>   refs/heads/*        refs/remotes/$remote/*\n>   refs/tags/*         refs/tags/*\n>   refs/notes/*        ???\n> \n> Of these, the first is specified in the config, the second is \n> implicit/magic, and the third would be specified in the config.\n> \n> I'd probably suggest a more straightforward (and hopefully less confusing) \n> setup like this:\n> \n>   Remote repo    ->   Local repo\n>   ------------------------------------------------\n>   refs/heads/*        refs/remotes/$remote/heads/*\n>   refs/tags/*         refs/remotes/$remote/tags/*\n>   refs/notes/*        refs/remotes/$remote/notes/*\n> \n> ...and these would all be set in the config, i.e. no implicit/magic \n> refspecs.\n\nI'll second this proposal, at least as far as tags go.  I can offer two\nreasons to support this.\n\n\nFirst, I think the assumption that tags are immutable is too strong.  In our\nrepo, we try to keep our topic branches mergeable into both the \"master\" and\n\"maintenance-of-the-latest-release\" branches.\n\nThis means the topic branches need to be based at the point where the\nmaintenance and master branches diverged.  Making this rule easy to follow is\nbest accomplished with a tag, e.g. \"topic-base\", but that tag will move when\nwe create a new maintenance branch for a new release.  With the current tag\nsemantics, when that happens everyone has to delete their local topic-base\ntags and get the new one from the common/shared repo.  People who forget to\ndo this end up basing their topics on outdated code, with predictable results.\n\nIt would be much easier to be able to just use an \"origin/topic-base\" tag\ninstead, one that that tracks the topic-base tag in the origin repo.\n\n\nSecond, I agree with Johan that the current semantics are confusing.  I'm\nbasically the git guru here at work, so it falls to me to teach people how\ngit works and how to use it.  I find that once people wrap their minds around\nthe concept of remote and local branches, they get tripped up by the way tags\nwork.\n\nIMHO it would be more intuitive if tags used the same local/remote semantics\nas branches.\n\n\t\tM.\n"},{"id":"155171","messageId":"20101104145817.GA27580@sigill.intra.peff.net","threadId":"25611","inReplyTo":"201011040149.47968.johan@herland.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-04T14:58:17Z","receivedAt":"2010-11-04T14:58:17Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 04, 2010 at 01:49:47AM +0100, Johan Herland wrote:\n\n> I'd probably suggest a more straightforward (and hopefully less confusing) \n> setup like this:\n> \n>   Remote repo    ->   Local repo\n>   ------------------------------------------------\n>   refs/heads/*        refs/remotes/$remote/heads/*\n>   refs/tags/*         refs/remotes/$remote/tags/*\n>   refs/notes/*        refs/remotes/$remote/notes/*\n> \n> ...and these would all be set in the config, i.e. no implicit/magic \n> refspecs.\n\nI have often considered that something like that would be simpler, too.\nBut just specifying\n\n  fetch = refs/tags/*:refs/remotes/$remote/tags/*\n\nwould pull down _all_ tags from the remote. Right now we only pull down\ntags for things that we are actually fetching (i.e., auto-follow).\n\nNow you could argue that auto-follow is not worth the effort. It is\nsomewhat confusing, and I can't think of a time when it ever actually\nreduced the set of objects I was fetching (as opposed to just fetching\nall tags). But maybe others have use cases where it matters.\n\n> We would, for example, extend the ref disambiguation of <name> (as \n> documented in the \"SPECIFYING REVISIONS\" section of git-rev-parse(1)), so \n> that in the cases where <name> is of the form \"<foo>/<bar>\" AND <foo> is an \n> existing remote, we also check for the following refs (after none of the \n> existing checks have returned a match):\n> \n>   7. refs/remotes/<foo>/tags/<bar>\n>   8. refs/remotes/<foo>/heads/<bar>\n\nThis codifies that refs for remote $foo are in refs/remotes/$foo, which\nis something we have avoided so far. For example, when finding the\n\"upstream\" branch, we have the name of the remote and the merge branch,\nlook up the fetch refspecs in the config, and then figure out where that\nbranch would be fetched to. Which of course turns out as you say (as\nremotes/$remote_name/$branch) in the default config, but we don't\nrestrict people to that.\n\n-Peff\n"},{"id":"155239","messageId":"201011050202.16931.johan@herland.net","threadId":"25611","inReplyTo":"4CD2C49A.8010309@xiplink.com","subject":"Re: Tag refspecs (was Re: [PATCH] Remove restriction on notes ref base)","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-05T01:02:16Z","receivedAt":"2010-11-05T01:02:16Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Thursday 04 November 2010, Marc Branchaud wrote:\n> On 10-11-03 08:49 PM, Johan Herland wrote:\n> > I'd probably suggest a more straightforward (and hopefully less\n> > confusing)\n> > \n> > setup like this:\n> >   Remote repo    ->   Local repo\n> >   ------------------------------------------------\n> >   refs/heads/*        refs/remotes/$remote/heads/*\n> >   refs/tags/*         refs/remotes/$remote/tags/*\n> >   refs/notes/*        refs/remotes/$remote/notes/*\n> > \n> > ...and these would all be set in the config, i.e. no implicit/magic\n> > refspecs.\n> \n> I'll second this proposal, at least as far as tags go.  I can offer two\n> reasons to support this.\n> \n> \n> First, I think the assumption that tags are immutable is too strong.  In\n> our repo, we try to keep our topic branches mergeable into both the\n> \"master\" and \"maintenance-of-the-latest-release\" branches.\n> \n> This means the topic branches need to be based at the point where the\n> maintenance and master branches diverged.  Making this rule easy to\n> follow is best accomplished with a tag, e.g. \"topic-base\", but that tag\n> will move when we create a new maintenance branch for a new release. \n> With the current tag semantics, when that happens everyone has to delete\n> their local topic-base tags and get the new one from the common/shared\n> repo.  People who forget to do this end up basing their topics on\n> outdated code, with predictable results.\n> \n> It would be much easier to be able to just use an \"origin/topic-base\" tag\n> instead, one that that tracks the topic-base tag in the origin repo.\n\nActually, this is not a valid reason. To me, it sounds like your \"topic-\nbase\" tag _really_ should be a \"topic_base\" _branch_. The branch is \ninitialized to the merge-base between \"master\" and \"maintenance-of-the-\nlatest-release\" branches, and when you create a new maintenance branch, the \n\"topic-base\" branch is fast-forwarded along the master branch until it \nreaches the merge-base with the new maintenance branch. (Remember that \nbranches really are nothing but named pointers into the commit graph, and as \nlong as the \"topic-base\" branch stays within the history of the \"master\" \nbranch, it does not constitute a proper \"branch\", i.e. a fork in the commit \nhistory.)\n\nIMHO, tags should still be very much immutable.\n\nHowever, when working with remotes, you may get into a situation where the \nsame tag name is independently set in different repos pointing at different \ncommits. When these repos fetch from eachother, the tag name collision will \nbe ignored, and each repo will keep their local version of the tag. Git \nwill, AFAIK, not alert you to the tag name collision, and even after you \nidentify the collision, it is not always easy to resolve it [1]. However, if \nwe namespace remote tags (like we already do with remote branches), it is \nmuch easier to review which commits each remote has associated with a given \ntag name, and it's also much simpler to resolve which remote's tag you want \nto use in your own repo. (e.g. \"git tag xyzzy refs/remotes/foo/tags/xyzzy\").\n\n> Second, I agree with Johan that the current semantics are confusing.  I'm\n> basically the git guru here at work, so it falls to me to teach people\n> how git works and how to use it.  I find that once people wrap their\n> minds around the concept of remote and local branches, they get tripped\n> up by the way tags work.\n> \n> IMHO it would be more intuitive if tags used the same local/remote\n> semantics as branches.\n\nI am in much the same situation at my $dayjob, and I can only agree.\n\n\n...Johan\n\n\n[1]: Resolving tag collisions currently involves removing the tag from one \nrepo and re-fetching from the other, or writing a custom refspec to rename \nthe tag when fetching.\n\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"155240","messageId":"201011050229.15941.johan@herland.net","threadId":"25611","inReplyTo":"20101104145817.GA27580@sigill.intra.peff.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-11-05T01:29:15Z","receivedAt":"2010-11-05T01:29:15Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Thursday 04 November 2010, Jeff King wrote:\n> On Thu, Nov 04, 2010 at 01:49:47AM +0100, Johan Herland wrote:\n> > I'd probably suggest a more straightforward (and hopefully less\n> > confusing)\n> > \n> > setup like this:\n> >   Remote repo    ->   Local repo\n> >   ------------------------------------------------\n> >   refs/heads/*        refs/remotes/$remote/heads/*\n> >   refs/tags/*         refs/remotes/$remote/tags/*\n> >   refs/notes/*        refs/remotes/$remote/notes/*\n> > \n> > ...and these would all be set in the config, i.e. no implicit/magic\n> > refspecs.\n> \n> I have often considered that something like that would be simpler, too.\n> But just specifying\n> \n>   fetch = refs/tags/*:refs/remotes/$remote/tags/*\n> \n> would pull down _all_ tags from the remote. Right now we only pull down\n> tags for things that we are actually fetching (i.e., auto-follow).\n> \n> Now you could argue that auto-follow is not worth the effort. It is\n> somewhat confusing, and I can't think of a time when it ever actually\n> reduced the set of objects I was fetching (as opposed to just fetching\n> all tags). But maybe others have use cases where it matters.\n\nActually, I don't have anything against auto-follow per se, and we could \neasily enough extend the refspec to specify auto-follow behaviour: There is \ncurrently the \"+\" prefix for specifying a forced (non-fast-forward) update. \nWe could for example add a \"~\" prefix for specifying that the refs matched \nby this refspec should only be fetched if they are part of the history \nfetched by other refspecs. We could then reproduce the current auto-follow \nbehaviour with the following pair of refspecs:\n\n  +refs/heads/*:refs/remotes/origin/*\n  ~+refs/tags/*:refs/tags/*\n\nor in my above proposal:\n\n  +refs/heads/*:refs/remotes/$remote/heads/*\n  ~+refs/tags/*:refs/remotes/$remote/tags/*\n  +refs/notes/*:refs/remotes/$remote/notes/*\n\n> > We would, for example, extend the ref disambiguation of <name> (as\n> > documented in the \"SPECIFYING REVISIONS\" section of git-rev-parse(1)),\n> > so that in the cases where <name> is of the form \"<foo>/<bar>\" AND\n> > <foo> is an existing remote, we also check for the following refs\n> > (after none of the\n> > \n> > existing checks have returned a match):\n> >   7. refs/remotes/<foo>/tags/<bar>\n> >   8. refs/remotes/<foo>/heads/<bar>\n> \n> This codifies that refs for remote $foo are in refs/remotes/$foo, which\n> is something we have avoided so far. For example, when finding the\n> \"upstream\" branch, we have the name of the remote and the merge branch,\n> look up the fetch refspecs in the config, and then figure out where that\n> branch would be fetched to. Which of course turns out as you say (as\n> remotes/$remote_name/$branch) in the default config, but we don't\n> restrict people to that.\n\nWe can do the same for \"foo/bar\" as well, although things become slightly \nmore fiddly:\n\nWhen \"foo\" exists as a remote, look up its fetch refspec(s), and determine \npossible mappings for name \"bar\". I.e. given the following (non-default) \nrefspecs for remote \"foo\":\n\n  +refs/heads/*:refs/remotes/spam/heads/*\n  +refs/tags/*:refs/remotes/eggs/tags/*\n  +refs/notes/*:refs/remotes/bacon/notes/*\n\nwe know that the intersection between the left side of these refspec and the \nref disambiguation rules consists of \"refs/tags/bar\" and \"refs/heads/bar\" \n(in that order). We can then map these to the right side of the refspec to \nget \"refs/remotes/eggs/tags/bar\" and \"refs/remotes/spam/heads/bar\" (in that \norder). We would then use the first match from these alternatives.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"155260","messageId":"20101105145510.GA19087@sigill.intra.peff.net","threadId":"25611","inReplyTo":"201011050229.15941.johan@herland.net","subject":"Re: [PATCH] Remove restriction on notes ref base","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-05T14:55:10Z","receivedAt":"2010-11-05T14:55:10Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 05, 2010 at 02:29:15AM +0100, Johan Herland wrote:\n\n> Actually, I don't have anything against auto-follow per se, and we could \n> easily enough extend the refspec to specify auto-follow behaviour: There is \n\nYup, agreed. That would be sufficient to capture the current behavior\n(and IMHO makes it much more transparent to the user).\n\n> > This codifies that refs for remote $foo are in refs/remotes/$foo, which\n> > is something we have avoided so far. For example, when finding the\n> > \"upstream\" branch, we have the name of the remote and the merge branch,\n> > look up the fetch refspecs in the config, and then figure out where that\n> > branch would be fetched to. Which of course turns out as you say (as\n> > remotes/$remote_name/$branch) in the default config, but we don't\n> > restrict people to that.\n> \n> We can do the same for \"foo/bar\" as well, although things become slightly \n> more fiddly:\n\nYeah, I don't think the problem is unsurmountable. But I do think it is\nworth doing the more complex behavior, as it keeps things \"right\" with\nrespect to arbitrary config.\n\n> When \"foo\" exists as a remote, look up its fetch refspec(s), and determine \n> possible mappings for name \"bar\". I.e. given the following (non-default) \n> refspecs for remote \"foo\":\n> \n>   +refs/heads/*:refs/remotes/spam/heads/*\n>   +refs/tags/*:refs/remotes/eggs/tags/*\n>   +refs/notes/*:refs/remotes/bacon/notes/*\n> \n> we know that the intersection between the left side of these refspec and the \n> ref disambiguation rules consists of \"refs/tags/bar\" and \"refs/heads/bar\" \n> (in that order). We can then map these to the right side of the refspec to \n> get \"refs/remotes/eggs/tags/bar\" and \"refs/remotes/spam/heads/bar\" (in that \n> order). We would then use the first match from these alternatives.\n\nYeah, that makes sense. If the remote side is storing tags somewhere\nbesides \"refs/tags\" you wouldn't find them, but that is probably a good\nthing.\n\n-Peff\n"},{"id":"155261","messageId":"4CD41EA6.1090003@xiplink.com","threadId":"25611","inReplyTo":"201011050202.16931.johan@herland.net","subject":"Re: Tag refspecs (was Re: [PATCH] Remove restriction on notes ref base)","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2010-11-05T15:11:34Z","receivedAt":"2010-11-05T15:11:34Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 10-11-04 09:02 PM, Johan Herland wrote:\n> On Thursday 04 November 2010, Marc Branchaud wrote:\n>> On 10-11-03 08:49 PM, Johan Herland wrote:\n>>> I'd probably suggest a more straightforward (and hopefully less\n>>> confusing)\n>>>\n>>> setup like this:\n>>>   Remote repo    ->   Local repo\n>>>   ------------------------------------------------\n>>>   refs/heads/*        refs/remotes/$remote/heads/*\n>>>   refs/tags/*         refs/remotes/$remote/tags/*\n>>>   refs/notes/*        refs/remotes/$remote/notes/*\n>>>\n>>> ...and these would all be set in the config, i.e. no implicit/magic\n>>> refspecs.\n>>\n>> I'll second this proposal, at least as far as tags go.  I can offer two\n>> reasons to support this.\n>>\n>>\n>> First, I think the assumption that tags are immutable is too strong.  In\n>> our repo, we try to keep our topic branches mergeable into both the\n>> \"master\" and \"maintenance-of-the-latest-release\" branches.\n>>\n>> This means the topic branches need to be based at the point where the\n>> maintenance and master branches diverged.  Making this rule easy to\n>> follow is best accomplished with a tag, e.g. \"topic-base\", but that tag\n>> will move when we create a new maintenance branch for a new release. \n>> With the current tag semantics, when that happens everyone has to delete\n>> their local topic-base tags and get the new one from the common/shared\n>> repo.  People who forget to do this end up basing their topics on\n>> outdated code, with predictable results.\n>>\n>> It would be much easier to be able to just use an \"origin/topic-base\" tag\n>> instead, one that that tracks the topic-base tag in the origin repo.\n> \n> Actually, this is not a valid reason. To me, it sounds like your \"topic-\n> base\" tag _really_ should be a \"topic_base\" _branch_. The branch is \n> initialized to the merge-base between \"master\" and \"maintenance-of-the-\n> latest-release\" branches, and when you create a new maintenance branch, the \n> \"topic-base\" branch is fast-forwarded along the master branch until it \n> reaches the merge-base with the new maintenance branch. (Remember that \n> branches really are nothing but named pointers into the commit graph, and as \n> long as the \"topic-base\" branch stays within the history of the \"master\" \n> branch, it does not constitute a proper \"branch\", i.e. a fork in the commit \n> history.)\n\nI understand how a branch can, with careful management, mechanically achieve\nthe behaviour I want.\n\nBut the problem with that approach is that it breaks as soon as someone\ncommits to the topic-base branch (an easy mistake to make, especially for\nrookie users).  Then that person would base later topics on the wrong commit,\nand worse, if they pushed their \"topic-base\" branch to our shared repo then\neveryone would be affected.\n\nA hook in the shared repo could prevent the pushing of the topic-base branch,\nbut that that's just a complicated, half-baked way of making a branch behave\nlike a tag.  A tag doesn't need the careful management that a branch would.\n\n\nAnyway, regardless of whether or not the scenario I described is valid, I\nstill wonder if tag immutability makes sense when remote tags live in the\nrepo's namespace.  If a repo first sets tag \"foo\" to point to commit 'A' then\nlater changes \"foo\" to point to 'B', shouldn't my clone's \"repo/foo\" tag\nupdate automatically to reflect that?  I see little point in keeping my\n\"repo/foo\" tag pointing at commit 'A'.\n\n\t\tM.\n"}]}