{"thread":{"id":"57397","subject":"[PATCH] glossary: describe \"worktree\"","startedAt":"2022-02-10T02:19:18Z","lastAt":"2022-02-18T20:50:38Z","messageCount":14,"participants":["Junio C Hamano","Derrick Stolee","Elijah Newren","Han-Wen Nienhuys","Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"448083","messageId":"xmqqczjvxy3o.fsf@gitster.g","threadId":"57397","inReplyTo":null,"subject":"[PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-10T02:19:07Z","receivedAt":"2022-02-10T02:19:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We have description on \"per worktree ref\", but \"worktree\" is not\ndescribed in the glossary.  We do have \"working tree\", though.\n\nCasually put, a \"working tree\" is what your editor and compiler\ninteracts with.  \"worktree\" is a mechanism to allow one or more\n\"working tree\"s to be attached to a repository and used to check out\ndifferent commits and branches independently, which includes not\njust a \"working tree\" but also repository metadata like HEAD, the\nindex to support simultaneous use of them.  Historically, we used\nthese terms interchangeably but we have been trying to use \"working\ntree\" when we mean it, instead of \"worktree\".\n\nMost of the existing references to \"working tree\" in the glossary do\nrefer primarily to the working tree portion, except for one that\nsaid refs like HEAD and refs/bisect/* are per \"working tree\", but it\nis more precise to say they are per \"worktree\".\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * Mostly unchanged from the version in the original discussion\n   https://lore.kernel.org/git/xmqqo83hatm1.fsf@gitster.g/ except\n   that we now mention that pseudorefs are also per worktree.\n\n   One thing that makes me worried somewhat is what I did not touch,\n   namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n   special and it may be impossible to coax it into refs API for\n   writing, so the text there makes sense for it, but there are\n   other all-caps-and-directly-under-dot-git-directory files like\n   ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n   API, so the description would have to be updated there.\n\n Documentation/glossary-content.txt | 13 +++++++++++--\n 1 file changed, 11 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt\nindex c077971335..9eb8920552 100644\n--- a/Documentation/glossary-content.txt\n+++ b/Documentation/glossary-content.txt\n@@ -312,7 +312,7 @@ Pathspecs are used on the command line of \"git ls-files\", \"git\n ls-tree\", \"git add\", \"git grep\", \"git diff\", \"git checkout\",\n and many other commands to\n limit the scope of operations to some subset of the tree or\n-worktree.  See the documentation of each command for whether\n+working tree.  See the documentation of each command for whether\n paths are relative to the current directory or toplevel.  The\n pathspec syntax is as follows:\n +\n@@ -446,7 +446,7 @@ exclude;;\n \tinterface than the <<def_plumbing,plumbing>>.\n \n [[def_per_worktree_ref]]per-worktree ref::\n-\tRefs that are per-<<def_working_tree,worktree>>, rather than\n+\tRefs that are per-<<def_worktree,worktree>>, rather than\n \tglobal.  This is presently only <<def_HEAD,HEAD>> and any refs\n \tthat start with `refs/bisect/`, but might later include other\n \tunusual refs.\n@@ -669,3 +669,12 @@ The most notable example is `HEAD`.\n \tThe tree of actual checked out files.  The working tree normally\n \tcontains the contents of the <<def_HEAD,HEAD>> commit's tree,\n \tplus any local changes that you have made but not yet committed.\n+\n+[[def_work_tree]]worktree::\n+\tA repository can have zero (i.e. bare repository) or one or\n+\tmore worktrees attached to it. One \"worktree\" consists of a\n+\t\"working tree\" and repository metadata, most of which are\n+\tshared among other worktrees of a single repository, and\n+\tsome of which are maintained separately per worktree\n+\t(e.g. the index, HEAD and pseudorefs like MERGE_HEAD,\n+\tper-worktree refs and per-worktree configuration file).\n-- \n2.35.1-102-g2b9c120970\n\n"},{"id":"448136","messageId":"3228c238-815e-3dd6-bfe4-e00c4cc43c34@gmail.com","threadId":"57397","inReplyTo":"xmqqczjvxy3o.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2022-02-10T14:40:01Z","receivedAt":"2022-02-10T14:40:07Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 2/9/2022 9:19 PM, Junio C Hamano wrote:\n> We have description on \"per worktree ref\", but \"worktree\" is not\n> described in the glossary.  We do have \"working tree\", though.\n\n>  * Mostly unchanged from the version in the original discussion\n>    https://lore.kernel.org/git/xmqqo83hatm1.fsf@gitster.g/ except\n>    that we now mention that pseudorefs are also per worktree.\n\nThis version looks good to me! Thanks.\n\n>    One thing that makes me worried somewhat is what I did not touch,\n>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n>    special and it may be impossible to coax it into refs API for\n>    writing, so the text there makes sense for it, but there are\n>    other all-caps-and-directly-under-dot-git-directory files like\n>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n>    API, so the description would have to be updated there.\n\nI agree that such changes would be nice. Shouldn't hold up\nthis change, though.\n\nThanks,\n-Stolee\n"},{"id":"448139","messageId":"CABPp-BHrFb_AA2OAiR7Bmq7vQuyG2Wme_PdjPdY8j-tp3VJfJg@mail.gmail.com","threadId":"57397","inReplyTo":"xmqqczjvxy3o.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-10T15:50:37Z","receivedAt":"2022-02-10T15:50:54Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Feb 9, 2022 at 6:19 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> We have description on \"per worktree ref\", but \"worktree\" is not\n> described in the glossary.  We do have \"working tree\", though.\n>\n> Casually put, a \"working tree\" is what your editor and compiler\n> interacts with.  \"worktree\" is a mechanism to allow one or more\n> \"working tree\"s to be attached to a repository and used to check out\n> different commits and branches independently, which includes not\n> just a \"working tree\" but also repository metadata like HEAD, the\n> index to support simultaneous use of them.  Historically, we used\n> these terms interchangeably but we have been trying to use \"working\n> tree\" when we mean it, instead of \"worktree\".\n>\n> Most of the existing references to \"working tree\" in the glossary do\n> refer primarily to the working tree portion, except for one that\n> said refs like HEAD and refs/bisect/* are per \"working tree\", but it\n> is more precise to say they are per \"worktree\".\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>\n>  * Mostly unchanged from the version in the original discussion\n>    https://lore.kernel.org/git/xmqqo83hatm1.fsf@gitster.g/ except\n>    that we now mention that pseudorefs are also per worktree.\n>\n>    One thing that makes me worried somewhat is what I did not touch,\n>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n>    special and it may be impossible to coax it into refs API for\n>    writing, so the text there makes sense for it, but there are\n>    other all-caps-and-directly-under-dot-git-directory files like\n>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n>    API, so the description would have to be updated there.\n\nI'm not quite following; why would the description need to be updated?\n Sure MERGE_HEAD is written without using the refs API, but we didn't\nmention how the pseduorefs were written in the description, and all of\nMERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\nper-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\nas the reader is concerned?\n\n>  Documentation/glossary-content.txt | 13 +++++++++++--\n>  1 file changed, 11 insertions(+), 2 deletions(-)\n>\n> diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt\n> index c077971335..9eb8920552 100644\n> --- a/Documentation/glossary-content.txt\n> +++ b/Documentation/glossary-content.txt\n> @@ -312,7 +312,7 @@ Pathspecs are used on the command line of \"git ls-files\", \"git\n>  ls-tree\", \"git add\", \"git grep\", \"git diff\", \"git checkout\",\n>  and many other commands to\n>  limit the scope of operations to some subset of the tree or\n> -worktree.  See the documentation of each command for whether\n> +working tree.  See the documentation of each command for whether\n>  paths are relative to the current directory or toplevel.  The\n>  pathspec syntax is as follows:\n>  +\n> @@ -446,7 +446,7 @@ exclude;;\n>         interface than the <<def_plumbing,plumbing>>.\n>\n>  [[def_per_worktree_ref]]per-worktree ref::\n> -       Refs that are per-<<def_working_tree,worktree>>, rather than\n> +       Refs that are per-<<def_worktree,worktree>>, rather than\n>         global.  This is presently only <<def_HEAD,HEAD>> and any refs\n>         that start with `refs/bisect/`, but might later include other\n>         unusual refs.\n> @@ -669,3 +669,12 @@ The most notable example is `HEAD`.\n>         The tree of actual checked out files.  The working tree normally\n>         contains the contents of the <<def_HEAD,HEAD>> commit's tree,\n>         plus any local changes that you have made but not yet committed.\n> +\n> +[[def_work_tree]]worktree::\n> +       A repository can have zero (i.e. bare repository) or one or\n> +       more worktrees attached to it. One \"worktree\" consists of a\n> +       \"working tree\" and repository metadata, most of which are\n> +       shared among other worktrees of a single repository, and\n> +       some of which are maintained separately per worktree\n> +       (e.g. the index, HEAD and pseudorefs like MERGE_HEAD,\n> +       per-worktree refs and per-worktree configuration file).\n> --\n> 2.35.1-102-g2b9c120970\n\nThe text looks good to me.\n"},{"id":"448140","messageId":"xmqqiltmwufw.fsf@gitster.g","threadId":"57397","inReplyTo":"CABPp-BHrFb_AA2OAiR7Bmq7vQuyG2Wme_PdjPdY8j-tp3VJfJg@mail.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-10T16:35:47Z","receivedAt":"2022-02-10T16:35:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>>    One thing that makes me worried somewhat is what I did not touch,\n>>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n>>    special and it may be impossible to coax it into refs API for\n>>    writing, so the text there makes sense for it, but there are\n>>    other all-caps-and-directly-under-dot-git-directory files like\n>>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n>>    API, so the description would have to be updated there.\n>\n> I'm not quite following; why would the description need to be updated?\n>  Sure MERGE_HEAD is written without using the refs API, but we didn't\n> mention how the pseduorefs were written in the description, and all of\n> MERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\n> per-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\n> as the reader is concerned?\n\nHere is how pseudo refs are defined.\n\n[[def_pseudoref]]pseudoref::\n\tPseudorefs are a class of files under `$GIT_DIR` which behave\n\tlike refs for the purposes of rev-parse, but which are treated\n\tspecially by git.  Pseudorefs both have names that are all-caps,\n\tand always start with a line consisting of a\n\t<<def_SHA1,SHA-1>> followed by whitespace.  So, HEAD is not a\n\tpseudoref, because it is sometimes a symbolic ref.  They might\n\toptionally contain some additional data.  `MERGE_HEAD` and\n\t`CHERRY_PICK_HEAD` are examples.  Unlike\n\t<<def_per_worktree_ref,per-worktree refs>>, these files cannot\n\tbe symbolic refs, and never have reflogs.  They also cannot be\n\tupdated through the normal ref update machinery.  Instead,\n\tthey are updated by directly writing to the files.  However,\n\tthey can be read as if they were refs, so `git rev-parse\n\tMERGE_HEAD` will work.\n\nPoints that may need to be looked at in the world where files\nbackend is not the only ref backend are:\n\n - \"are ... files under `$GIT_DIR`\" may no longer be true, once some\n   of them are stored in reftable, for example.\n\n - \"followed by whitespace\" may be an irrelevant detail for the\n   purpose of this paragraph.\n\n - CHERRY_PICK_HEAD, as written in sequencer.c::do_pick_commit(),\n   use update_ref() to write a named file out, so \"followed by\n   whitesspace\" (and other cruft, like MERGE_HEAD does) certainly\n   does not apply.\n\n - Also \"cannot be updated through the normal ref update machinery\"\n   is no longer true.  sequencer.c::do_pick_commit() even calls\n   update_ref() with REF_NO_DEREF to ensure \"cannot be symbolic\n   refs\".\n\n - \"never have reflogs\" would make sense for the current set of\n   pseudorefs (does reflog on CHERRY_PICK_HEAD, for example, have\n   real use case?), but I do not know if it stays that way.  I do\n   not care too deeply either way, but I want to avoid over\n   specifying things.\n\nWhat worries me the most is that we cannot simply say \"all-caps\nnames that end with '_HEAD' all behave like refs except that they\nwill not be symrefs without reflog.\" MERGE_HEAD is the only known\nexception if I am not mistaken, and I am OK to single it out as an\noddball.  The current description however gives that there are a lot\nmore differences _among_ pseudorefs.\n\n\n"},{"id":"448171","messageId":"CABPp-BEtjtpUK7gsb2QYW6JiicA3=ewkK7oKr6i8jh-1ndMnYw@mail.gmail.com","threadId":"57397","inReplyTo":"xmqqiltmwufw.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-02-10T17:03:27Z","receivedAt":"2022-02-10T17:03:43Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Feb 10, 2022 at 8:35 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> >>    One thing that makes me worried somewhat is what I did not touch,\n> >>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n> >>    special and it may be impossible to coax it into refs API for\n> >>    writing, so the text there makes sense for it, but there are\n> >>    other all-caps-and-directly-under-dot-git-directory files like\n> >>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n> >>    API, so the description would have to be updated there.\n> >\n> > I'm not quite following; why would the description need to be updated?\n> >  Sure MERGE_HEAD is written without using the refs API, but we didn't\n> > mention how the pseduorefs were written in the description, and all of\n> > MERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\n> > per-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\n> > as the reader is concerned?\n>\n> Here is how pseudo refs are defined.\n>\n> [[def_pseudoref]]pseudoref::\n>         Pseudorefs are a class of files under `$GIT_DIR` which behave\n>         like refs for the purposes of rev-parse, but which are treated\n>         specially by git.  Pseudorefs both have names that are all-caps,\n>         and always start with a line consisting of a\n>         <<def_SHA1,SHA-1>> followed by whitespace.  So, HEAD is not a\n>         pseudoref, because it is sometimes a symbolic ref.  They might\n>         optionally contain some additional data.  `MERGE_HEAD` and\n>         `CHERRY_PICK_HEAD` are examples.  Unlike\n>         <<def_per_worktree_ref,per-worktree refs>>, these files cannot\n>         be symbolic refs, and never have reflogs.  They also cannot be\n>         updated through the normal ref update machinery.  Instead,\n>         they are updated by directly writing to the files.  However,\n>         they can be read as if they were refs, so `git rev-parse\n>         MERGE_HEAD` will work.\n>\n> Points that may need to be looked at in the world where files\n> backend is not the only ref backend are:\n\nAh, sorry, I assumed in \"the description would have to be updated\nthere\" you used \"there\" to refer to some part of your new patch text.\nRe-reading, I can see you did specify the pseudoref section, but I\njust somehow missed it.  Sorry about that.\n\n>  - \"are ... files under `$GIT_DIR`\" may no longer be true, once some\n>    of them are stored in reftable, for example.\n>\n>  - \"followed by whitespace\" may be an irrelevant detail for the\n>    purpose of this paragraph.\n>\n>  - CHERRY_PICK_HEAD, as written in sequencer.c::do_pick_commit(),\n>    use update_ref() to write a named file out, so \"followed by\n>    whitesspace\" (and other cruft, like MERGE_HEAD does) certainly\n>    does not apply.\n>\n>  - Also \"cannot be updated through the normal ref update machinery\"\n>    is no longer true.  sequencer.c::do_pick_commit() even calls\n>    update_ref() with REF_NO_DEREF to ensure \"cannot be symbolic\n>    refs\".\n>\n>  - \"never have reflogs\" would make sense for the current set of\n>    pseudorefs (does reflog on CHERRY_PICK_HEAD, for example, have\n>    real use case?), but I do not know if it stays that way.  I do\n>    not care too deeply either way, but I want to avoid over\n>    specifying things.\n>\n> What worries me the most is that we cannot simply say \"all-caps\n> names that end with '_HEAD' all behave like refs except that they\n> will not be symrefs without reflog.\" MERGE_HEAD is the only known\n> exception if I am not mistaken, and I am OK to single it out as an\n> oddball.  The current description however gives that there are a lot\n> more differences _among_ pseudorefs.\n\nMakes sense; thanks for clarifying for me.\n"},{"id":"448177","messageId":"CAFQ2z_OgVcaty1wMX0O0mj-PYSAphKAkXgTCW+uJKDAuCwLn4w@mail.gmail.com","threadId":"57397","inReplyTo":"xmqqiltmwufw.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@google.com","sentAt":"2022-02-10T18:07:22Z","receivedAt":"2022-02-10T18:07:37Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"On Thu, Feb 10, 2022 at 5:36 PM Junio C Hamano <gitster@pobox.com> wrote:\n> >>    One thing that makes me worried somewhat is what I did not touch,\n> >>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n> >>    special and it may be impossible to coax it into refs API for\n> >>    writing, so the text there makes sense for it, but there are\n> >>    other all-caps-and-directly-under-dot-git-directory files like\n> >>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n> >>    API, so the description would have to be updated there.\n> >\n> > I'm not quite following; why would the description need to be updated?\n> >  Sure MERGE_HEAD is written without using the refs API, but we didn't\n> > mention how the pseduorefs were written in the description, and all of\n> > MERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\n> > per-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\n> > as the reader is concerned?\n>\n> Here is how pseudo refs are defined.\n>\n> [[def_pseudoref]]pseudoref::\n>         Pseudorefs are a class of files under `$GIT_DIR` which behave\n>         like refs for the purposes of rev-parse, but which are treated\n>         specially by git.  Pseudorefs both have names that are all-caps,\n>         and always start with a line consisting of a\n>         <<def_SHA1,SHA-1>> followed by whitespace.  So, HEAD is not a\n>         pseudoref, because it is sometimes a symbolic ref.  They might\n\nrefs.c says\n\n        if (is_pseudoref_syntax(refname))\n                return REF_TYPE_PSEUDOREF;\n\nIe. ref_type(\"HEAD\") == REF_TYPE_PSEUDOREF\n\nThis may be partly my fault (commit 55dd8b910 \"Make HEAD a PSEUDOREF\nrather than PER_WORKTREE.\").\n\nFrom the source code I had only understood that pseudorefs are ALLCAPS\nnames and are in the toplevel namespace.\n(HEAD, FETCH_HEAD and MERGE_HEAD have special-cased support in various places).\n\nIs this glossary the official definition of what things are? If so,\nthe source code should refer to there. If not -except for confusion-\nhow bad is it if the info in the glossary is inaccurate?\n\n> What worries me the most is that we cannot simply say \"all-caps\n> names that end with '_HEAD' all behave like refs except that they\n> will not be symrefs without reflog.\" MERGE_HEAD is the only known\n> exception if I am not mistaken, and I am OK to single it out as an\n> oddball.  The current description however gives that there are a lot\n> more differences _among_ pseudorefs.\n\nIt might be possible to add this extra info the reftable format as a\nfurther subtype of the ref record.  We'd have to update the JGit\nimplementation, though.\n\n-- \nHan-Wen Nienhuys - Google Munich\nI work 80%. Don't expect answers from me on Fridays.\n--\nGoogle Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich\nRegistergericht und -nummer: Hamburg, HRB 86891\nSitz der Gesellschaft: Hamburg\nGeschäftsführer: Paul Manicle, Halimah DeLaine Prado\n"},{"id":"448178","messageId":"xmqqh796tw34.fsf@gitster.g","threadId":"57397","inReplyTo":"CAFQ2z_OgVcaty1wMX0O0mj-PYSAphKAkXgTCW+uJKDAuCwLn4w@mail.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-10T18:28:31Z","receivedAt":"2022-02-10T18:28:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Han-Wen Nienhuys <hanwen@google.com> writes:\n\n> On Thu, Feb 10, 2022 at 5:36 PM Junio C Hamano <gitster@pobox.com> wrote:\n>> >>    One thing that makes me worried somewhat is what I did not touch,\n>> >>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n>> >>    special and it may be impossible to coax it into refs API for\n>> >>    writing, so the text there makes sense for it, but there are\n>> >>    other all-caps-and-directly-under-dot-git-directory files like\n>> >>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n>> >>    API, so the description would have to be updated there.\n>> >\n>> > I'm not quite following; why would the description need to be updated?\n>> >  Sure MERGE_HEAD is written without using the refs API, but we didn't\n>> > mention how the pseduorefs were written in the description, and all of\n>> > MERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\n>> > per-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\n>> > as the reader is concerned?\n>>\n>> Here is how pseudo refs are defined.\n>>\n>> [[def_pseudoref]]pseudoref::\n>>         Pseudorefs are a class of files under `$GIT_DIR` which behave\n>>         like refs for the purposes of rev-parse, but which are treated\n>>         specially by git.  Pseudorefs both have names that are all-caps,\n>>         and always start with a line consisting of a\n>>         <<def_SHA1,SHA-1>> followed by whitespace.  So, HEAD is not a\n>>         pseudoref, because it is sometimes a symbolic ref.  They might\n>\n> refs.c says\n>\n>         if (is_pseudoref_syntax(refname))\n>                 return REF_TYPE_PSEUDOREF;\n>\n> Ie. ref_type(\"HEAD\") == REF_TYPE_PSEUDOREF\n>\n> This may be partly my fault (commit 55dd8b910 \"Make HEAD a PSEUDOREF\n> rather than PER_WORKTREE.\").\n>\n> From the source code I had only understood that pseudorefs are ALLCAPS\n> names and are in the toplevel namespace.\n> (HEAD, FETCH_HEAD and MERGE_HEAD have special-cased support in various places).\n>\n> Is this glossary the official definition of what things are? If so,\n> the source code should refer to there. If not -except for confusion-\n> how bad is it if the info in the glossary is inaccurate?\n\nDeveloper and end-user confusion ensues.\n\n>> What worries me the most is that we cannot simply say \"all-caps\n>> names that end with '_HEAD' all behave like refs except that they\n>> will not be symrefs without reflog.\" MERGE_HEAD is the only known\n>> exception if I am not mistaken, and I am OK to single it out as an\n>> oddball.  The current description however gives that there are a lot\n>> more differences _among_ pseudorefs.\n>\n> It might be possible to add this extra info the reftable format as a\n> further subtype of the ref record.  We'd have to update the JGit\n> implementation, though.\n\nAs you said earlier, the true oddball is FETCH_HEAD X-<.  I actually\nthink in all the discussion in this thread around pseudoref, I meant\nthat one when I mentioned MERGE_HEAD, and I suspect the glossary\nentry also made the same mistake of not mentioning it.  MERGE_HEAD\nis also different in that it can list more than one commit, but\nFETCH_HEAD has a lot more information per commit.\n\nThe format was invented solely for the purpose of passing\ninformation from \"git fetch\" to \"git merge\" as an implementation\ndetail of \"git pull\" to describe each commit/tag that are being\nmerged, so that it can in turn pass the extra info to drive \"git\nfmt-merge-msg\" internally to prepare merge template.\n\n\"git pull\" did have to use such a special format temporary file\n(which is what FETCH_HEAD really is, rather than a ref that records\nmore than one commits), but we didn't have to treat such an oddball\ntemporary file as if it were a ref.  But we allowed \"git rev-parse\"\nto read only the first object name in the file and ignore the rest\nas if nothing strange happened, which probably was a mistake made\nout of my sloppyness when we did \"pull is fetch followed by merge\"\ncallchain.\n\nFor backward compatibility, \"git merge FETCH_HEAD\" still may have to\nwork the way it does (i.e. if FETCH_HEAD has multiple lines, the\nresulting merge would become an octopus merge, and merge message\nwill say not just the commit but mention where they came from).  But\nI am not sure if it is essential for us to keep treating these\noddball temporary files as if they are (sort of) refs.\n"},{"id":"448179","messageId":"CAFQ2z_Pvje9LM0iyiP87S-L754zepEE_9k=_4Oa0w1Lo_pb=TQ@mail.gmail.com","threadId":"57397","inReplyTo":"xmqqh796tw34.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@google.com","sentAt":"2022-02-10T18:36:49Z","receivedAt":"2022-02-10T18:37:04Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"On Thu, Feb 10, 2022 at 7:28 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Han-Wen Nienhuys <hanwen@google.com> writes:\n>\n> > On Thu, Feb 10, 2022 at 5:36 PM Junio C Hamano <gitster@pobox.com> wrote:\n> >> >>    One thing that makes me worried somewhat is what I did not touch,\n> >> >>    namely, how pseudo refs are defined.  I know MERGE_HEAD is very\n> >> >>    special and it may be impossible to coax it into refs API for\n> >> >>    writing, so the text there makes sense for it, but there are\n> >> >>    other all-caps-and-directly-under-dot-git-directory files like\n> >> >>    ORIG_HEAD and CHERRY_PICK_HEAD that are written using the refs\n> >> >>    API, so the description would have to be updated there.\n> >> >\n> >> > I'm not quite following; why would the description need to be updated?\n> >> >  Sure MERGE_HEAD is written without using the refs API, but we didn't\n> >> > mention how the pseduorefs were written in the description, and all of\n> >> > MERGE_HEAD, CHERRY_PICK_HEAD, ORIG_HEAD, REVERT_HEAD get written\n> >> > per-worktree so doesn't \"pseudorefs like MERGE_HEAD\" cover it as far\n> >> > as the reader is concerned?\n> >>\n> >> Here is how pseudo refs are defined.\n> >>\n> >> [[def_pseudoref]]pseudoref::\n> >>         Pseudorefs are a class of files under `$GIT_DIR` which behave\n> >>         like refs for the purposes of rev-parse, but which are treated\n> >>         specially by git.  Pseudorefs both have names that are all-caps,\n> >>         and always start with a line consisting of a\n> >>         <<def_SHA1,SHA-1>> followed by whitespace.  So, HEAD is not a\n> >>         pseudoref, because it is sometimes a symbolic ref.  They might\n> >\n> > refs.c says\n> >\n> >         if (is_pseudoref_syntax(refname))\n> >                 return REF_TYPE_PSEUDOREF;\n> >\n> > Ie. ref_type(\"HEAD\") == REF_TYPE_PSEUDOREF\n> >\n> > This may be partly my fault (commit 55dd8b910 \"Make HEAD a PSEUDOREF\n> > rather than PER_WORKTREE.\").\n> >\n> > From the source code I had only understood that pseudorefs are ALLCAPS\n> > names and are in the toplevel namespace.\n> > (HEAD, FETCH_HEAD and MERGE_HEAD have special-cased support in various places).\n> >\n> > Is this glossary the official definition of what things are? If so,\n> > the source code should refer to there. If not -except for confusion-\n> > how bad is it if the info in the glossary is inaccurate?\n>\n> Developer and end-user confusion ensues.\n\nthat's why I said: \"except for confusion\" :-)\n\nI'm asking to understand if there is anything stopping us from\nchanging the glossary to match the current code.\n\n> For backward compatibility, \"git merge FETCH_HEAD\" still may have to\n> work the way it does (i.e. if FETCH_HEAD has multiple lines, the\n> resulting merge would become an octopus merge, and merge message\n> will say not just the commit but mention where they came from).  But\n> I am not sure if it is essential for us to keep treating these\n> oddball temporary files as if they are (sort of) refs.\n\non a tangent: I posted a patch to write MERGE_AUTOSTASH,\nrebase-merge/autostash, etc. as refs.\nIs that the right direction? They are read like refs, but they are\ntogether in a directory with other bits of stateful data (similar to\nwhat is appended to FETCH_HEAD). Perhaps I should rather change the\nread path, so they're always read as files rather than refs?\n\n-- \nHan-Wen Nienhuys - Google Munich\nI work 80%. Don't expect answers from me on Fridays.\n--\n\nGoogle Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich\n\nRegistergericht und -nummer: Hamburg, HRB 86891\n\nSitz der Gesellschaft: Hamburg\n\nGeschäftsführer: Paul Manicle, Halimah DeLaine Prado\n"},{"id":"448183","messageId":"xmqqczjuttyw.fsf@gitster.g","threadId":"57397","inReplyTo":"CAFQ2z_Pvje9LM0iyiP87S-L754zepEE_9k=_4Oa0w1Lo_pb=TQ@mail.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-10T19:14:15Z","receivedAt":"2022-02-10T19:14:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Han-Wen Nienhuys <hanwen@google.com> writes:\n\n> on a tangent: I posted a patch to write MERGE_AUTOSTASH,\n> rebase-merge/autostash, etc. as refs.\n> Is that the right direction? They are read like refs, but they are\n> together in a directory with other bits of stateful data (similar to\n> what is appended to FETCH_HEAD). Perhaps I should rather change the\n> read path, so they're always read as files rather than refs?\n\nI think that would be a lot more preferrable.  If a file is written\nto record pieces of info, among which an object name happens to be\nincluded, it does not have to be recorded as a ref.  Especially if\nit is an ephemeral file like MERGE_AUTOSTASH and FETCH_HEAD.\n"},{"id":"448186","messageId":"xmqq7da2ttt7.fsf@gitster.g","threadId":"57397","inReplyTo":"CAFQ2z_Pvje9LM0iyiP87S-L754zepEE_9k=_4Oa0w1Lo_pb=TQ@mail.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-10T19:17:40Z","receivedAt":"2022-02-10T19:17:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Han-Wen Nienhuys <hanwen@google.com> writes:\n\n>> > Is this glossary the official definition of what things are? If so,\n>> > the source code should refer to there. If not -except for confusion-\n>> > how bad is it if the info in the glossary is inaccurate?\n>>\n>> Developer and end-user confusion ensues.\n>\n> that's why I said: \"except for confusion\" :-)\n>\n> I'm asking to understand if there is anything stopping us from\n> changing the glossary to match the current code.\n\nI do not think so.  It will give us a chance to rethink what we have\nin the code, too.  It is possible that we may end up concluding that\nit is better to leave a \"pseudoref\" always as a file inside $GIT_DIR\nregardless of what ref backend is in use, for example.\n\n"},{"id":"448676","messageId":"CAFQ2z_O=WguSAJDD4DRpwtX54A5dWQZQPCuQDR81idknQgchaA@mail.gmail.com","threadId":"57397","inReplyTo":"xmqqczjuttyw.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@google.com","sentAt":"2022-02-17T10:00:12Z","receivedAt":"2022-02-17T10:07:07Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"On Thu, Feb 10, 2022 at 8:14 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Han-Wen Nienhuys <hanwen@google.com> writes:\n>\n> > on a tangent: I posted a patch to write MERGE_AUTOSTASH,\n> > rebase-merge/autostash, etc. as refs.\n> > Is that the right direction? They are read like refs, but they are\n> > together in a directory with other bits of stateful data (similar to\n> > what is appended to FETCH_HEAD). Perhaps I should rather change the\n> > read path, so they're always read as files rather than refs?\n>\n> I think that would be a lot more preferrable.  If a file is written\n> to record pieces of info, among which an object name happens to be\n> included, it does not have to be recorded as a ref.  Especially if\n> it is an ephemeral file like MERGE_AUTOSTASH and FETCH_HEAD.\n\nFor FETCH_HEAD, doing\n\n  git fetch host refs/changes/23/123/1 && git checkout FETCH_HEAD\n\nis the standard idiom for downloading a change from Gerrit. I suspect\nthere might be other similar idioms. This means we have to read them\nthrough the refs machinery.\n\nI think the most sensible approach is to pass the read/write through\nrefs_* functions, but special-case the storage, so it doesn't go\nthrough reftable. We already do this for FETCH_HEAD and MERGE_HEAD in\nrefs_read_raw_refs.\n\nThis means we need a formal definition of which refs should be treated\nas files. Maybe we could do as follows:\n\nPseudorefs are\n  1) all uppercase toplevel names except for HEAD\n  2) all refs that are not under refs/* (for example:\nrebase-{merge,apply}/autostash)\n\nPseudorefs are always stored as files containing a hex object_id.\n\nPseudorefs can be read or written through refs_* functions, but given\nthe storage guarantees, it's also valid to read/write them outside\nrefs_* functions\n\nIt is forbidden to make cross-ref transactions that involve pseudorefs.\n\n-- \nHan-Wen Nienhuys - Google Munich\nI work 80%. Don't expect answers from me on Fridays.\n--\nGoogle Germany GmbH, Erika-Mann-Strasse 33, 80636 Munich\nRegistergericht und -nummer: Hamburg, HRB 86891\nSitz der Gesellschaft: Hamburg\nGeschäftsführer: Paul Manicle, Liana Sebastian\n"},{"id":"448727","messageId":"xmqqtucx8g34.fsf@gitster.g","threadId":"57397","inReplyTo":"CAFQ2z_O=WguSAJDD4DRpwtX54A5dWQZQPCuQDR81idknQgchaA@mail.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-17T19:10:07Z","receivedAt":"2022-02-17T19:10:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Han-Wen Nienhuys <hanwen@google.com> writes:\n\n> For FETCH_HEAD, doing\n>\n>   git fetch host refs/changes/23/123/1 && git checkout FETCH_HEAD\n>\n> is the standard idiom for downloading a change from Gerrit. I suspect\n> there might be other similar idioms. This means we have to read them\n> through the refs machinery.\n\nThis merely means we have to read them through the object-name\nmachinery around get_oid().  Historically that was done by calling\nrepo_dwin_ref() from get_oid_basic(), which is where refs machinery\nenters the picture, and because we had only files backend, it was OK\nand convenient to treat .git/FETCH_HEAD and .git/refs/heads/master\nin the same codepath.  But there is no reason for the arrangement to\nstay that way.  .git/FOOBAR_HEAD files can be read as a file (we can\nsay we let files-backend to handle it, but we can also extract a helper\nfunction out of it and make it clear that it truly has no dependence\non the refs machinery) while .git/refs/* can be read from the refs\nmachinery that may be backed by reftable backend.\n\n> I think the most sensible approach is to pass the read/write through\n> refs_* functions, but special-case the storage, so it doesn't go\n> through reftable. We already do this for FETCH_HEAD and MERGE_HEAD in\n> refs_read_raw_refs.\n\nI think we are more or less on the same page.  I do not think these\nfiles behave like refs (they have no reflog, and they do not serve\nas anchoring points for the purpose of gc/fsck) and we need a\nspecial code path, which might be identical to the current ref-files\nbackend code, to handle them no matter what backend is used for true\nrefs.\n\n> This means we need a formal definition of which refs should be treated\n> as files. Maybe we could do as follows:\n>\n> Pseudorefs are\n>   1) all uppercase toplevel names except for HEAD\n>   2) all refs that are not under refs/* (for example:\n> rebase-{merge,apply}/autostash)\n>\n> Pseudorefs are always stored as files containing a hex object_id.\n>\n> Pseudorefs can be read or written through refs_* functions, but given\n> the storage guarantees, it's also valid to read/write them outside\n> refs_* functions\n>\n> It is forbidden to make cross-ref transactions that involve pseudorefs.\n"},{"id":"448802","messageId":"220218.867d9rhqab.gmgdl@evledraar.gmail.com","threadId":"57397","inReplyTo":"xmqqtucx8g34.fsf@gitster.g","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-02-18T20:25:15Z","receivedAt":"2022-02-18T20:29:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Feb 17 2022, Junio C Hamano wrote:\n\n> Han-Wen Nienhuys <hanwen@google.com> writes:\n>\n>> For FETCH_HEAD, doing\n>>\n>>   git fetch host refs/changes/23/123/1 && git checkout FETCH_HEAD\n>>\n>> is the standard idiom for downloading a change from Gerrit. I suspect\n>> there might be other similar idioms. This means we have to read them\n>> through the refs machinery.\n>\n> This merely means we have to read them through the object-name\n> machinery around get_oid().  Historically that was done by calling\n> repo_dwin_ref() from get_oid_basic(), which is where refs machinery\n> enters the picture, and because we had only files backend, it was OK\n> and convenient to treat .git/FETCH_HEAD and .git/refs/heads/master\n> in the same codepath.  But there is no reason for the arrangement to\n> stay that way.  .git/FOOBAR_HEAD files can be read as a file (we can\n> say we let files-backend to handle it, but we can also extract a helper\n> function out of it and make it clear that it truly has no dependence\n> on the refs machinery) while .git/refs/* can be read from the refs\n> machinery that may be backed by reftable backend.\n>\n>> I think the most sensible approach is to pass the read/write through\n>> refs_* functions, but special-case the storage, so it doesn't go\n>> through reftable. We already do this for FETCH_HEAD and MERGE_HEAD in\n>> refs_read_raw_refs.\n>\n> I think we are more or less on the same page.  I do not think these\n> files behave like refs (they have no reflog, and they do not serve\n> as anchoring points for the purpose of gc/fsck) and we need a\n> special code path, which might be identical to the current ref-files\n> backend code, to handle them no matter what backend is used for true\n> refs.\n\nI'm not sure I get all the concerns in this thread, are we talking about\nhaving FETCH_HEAD be not-in-reftable mainly because it's multi-value?\n\nMaybe we will need these special refs on-disk forever, but it seems\npreferrable to pursue a plan where we use the preferred ref backend for\nthem.\n\nThat means that we can make them part of the normal ref transaction for\nthe backend, and could eventually support a world where a repo\ne.g. talks to remote DB service for its refs (with shared storage for\nrepos).\n\nFor the \"no reflog\" is that really a critical property to maintain, or\njust how the file backend happens to work now? In any case weren't we\ntalking about explicitly supporting the \"explicit no reflog\", \"reflog\nonly for this ref\" etc. that we support in the file backend in reftable?\nThen we could presumably turn off the reflog for these special refs.\n\nSimilarly, for \"gc\" etc. supporting that doesn't seem like such a big\ndeal in that codepath, even if these end up being stored in some \"real\"\nref store. We can just ignore them when we're checking reachability.\n\nBut I may be entirely missing the point here...\n"},{"id":"448806","messageId":"xmqq1qzzzyp1.fsf@gitster.g","threadId":"57397","inReplyTo":"220218.867d9rhqab.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH] glossary: describe \"worktree\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-02-18T20:50:34Z","receivedAt":"2022-02-18T20:50:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> But I may be entirely missing the point here...\n\nNot only FETCH_HEAD is a multi-line file, but each entry in it carry\nextra information that do not belong to a 'ref', like where it came\nfrom and whether its intended use is to merge into the current\nbranch.\n\nThe file is much closer to what \"rebase -i\" uses its \"todo list\"\nfor, than being a \"ref-like\" thing.  The only similarity with a\nloose ref is that it begins with 40-hex and get_sha1_hex() will\nhappily return success.  The file format was designed to take\nadvantage of the loose-ness of get_sha1_hex(), historically, so\nthat the reading side can reuse the logic to read loose refs.\n\nYou can blame all of that to my laziness ;-).\n\nAfter you fetch a single ref, get_oid(\"FETCH_HEAD\") should keep\nreturning the object name of what you fetched, but that does not\nmean the full multi-line trash needs to be stored in any ref\nbackend.  If you fetch multiple refs, get_oid(\"FETCH_HEAD\") can only\nreturn one of them anyway, so as long as we keep the only useful use\ncase working, we do not have to use the machinery the ref backend of\nchoice uses to store it.  It can remain an on-disk file, just like\nthe \"todo\" list \"rebase -i\" uses is an on-disk file.\n\n\n"}]}