From: Andy Koppe Date: Sun, 01 Nov 2026 23:03:18 GMT Subject: [PATCH v2 0/5] root refs vs pseudorefs Message-ID: <20261101230326.3675597-1-andy.koppe@gmail.com> In-Reply-To: <20261022212903.177261-1-andy.koppe@gmail.com> Changes in v2: - Tweak pseudoref definition. - Add prefix lists for per-worktree refs. - Wrap lists in '--'. - Add root refs and pseudorefs to ref types in gitdatamodel(7). - Trim messages of commits 3 and 4. Andy Koppe (5): doc: glossary: add root ref and clarify pseudorefs doc: glossary: update per-worktree refs doc: stop calling root refs pseudorefs refs: stop calling root refs pseudorefs t: stop calling root refs pseudorefs Documentation/config/core.adoc | 2 +- Documentation/for-each-ref-options.adoc | 2 +- Documentation/git-ls-remote.adoc | 4 +- Documentation/git-update-ref.adoc | 13 ++- Documentation/git-worktree.adoc | 13 ++- Documentation/gitdatamodel.adoc | 18 +++- Documentation/glossary-content.adoc | 98 ++++++++++++------- Documentation/rev-list-options.adoc | 4 +- builtin/for-each-ref.c | 2 +- contrib/completion/git-completion.bash | 7 +- refs.h | 13 ++- revision.c | 2 +- t/show-ref-exists-tests.sh | 4 +- t/t0600-reffiles-backend.sh | 2 +- t/t0610-reftable-basics.sh | 2 +- t/t1400-update-ref.sh | 66 ++++++------- t/t1403-show-ref.sh | 2 +- t/t1460-refs-migrate.sh | 4 +- t/t4013-diff-various.sh | 6 +- ...iff.diff-tree_--cc_--summary_REVERSE_HEAD} | 2 +- t/t6302-for-each-ref-filter.sh | 4 +- t/t9902-completion.sh | 4 +- 22 files changed, 158 insertions(+), 116 deletions(-) rename t/t4013/{diff.diff-tree_--cc_--summary_REVERSE => diff.diff-tree_--cc_--summary_REVERSE_HEAD} (73%) Range-diff against v1: 1: 9979ad1589 ! 1: 4734fa2f2e doc: glossary: add root ref and clarify pseudorefs @@ Documentation/glossary-content.adoc: exclude;; - A ref that has different semantics than normal refs. These refs can be - read via normal Git commands, but cannot be written to by commands like - linkgit:git-update-ref[1]. -+ A name that can be used like a <> to refer to -+ <>, but that is not stored in the same way as refs. -+ For example, pseudorefs cannot be written by linkgit:git-update-ref[1] -+ or listed by linkgit:git-for-each-ref[1]. ++ A name that can be used like a <> to refer to an ++ <>, but that is not stored in the same way as refs. ++ For example, pseudorefs can be passed to linkgit:git-log[1] or ++ linkgit:git-diff[1], but they cannot be written by ++ linkgit:git-update-ref[1] or listed by linkgit:git-for-each-ref[1]. + The following pseudorefs are known to Git: - -@@ Documentation/glossary-content.adoc: The following pseudorefs are known to Git: +- +++ ++-- + - `FETCH_HEAD` is written by linkgit:git-fetch[1] or linkgit:git-pull[1]. It + may refer to multiple object IDs. Each object ID is annotated with metadata + indicating where it was fetched from and its fetch status. - `MERGE_HEAD` is written by linkgit:git-merge[1] when resolving merge conflicts. It contains all commit IDs which are being merged. ++-- ++ +When a pseudoref contains more than one object ID, using it to refer to an +object yields the first one. 2: 8932691331 ! 2: 62f4ae009c doc: glossary: update per-worktree refs @@ Documentation/glossary-content.adoc: exclude;; - that start with `refs/bisect/`, but might later include other - unusual refs. + A <> that is specific to a <>, -+ rather than shared between all worktrees. All -+ <>, such as <>, are -+ per-worktree, as are refs that start with `refs/bisect/`, -+ `refs/worktree/` or `refs/rewritten/`. ++ rather than shared between all worktrees. All <>, ++ for example <> and `ORIG_HEAD`, are per-worktree, as are ++ refs with the following prefixes: +++ ++-- ++ - `refs/bisect/` ++ ++ - `refs/rewritten/` ++ ++ - `refs/worktree/` ++-- ++ +<> are also specific to each worktree. ++ @@ Documentation/glossary-content.adoc: exclude;; +per-worktree refs of other worktrees. [[def_pseudoref]]pseudoref:: - A name that can be used like a <> to refer to + A name that can be used like a <> to refer to an @@ Documentation/glossary-content.adoc: and pseudorefs. "working tree" and repository metadata, most of which are shared among other worktrees of a single repository, and some of which are maintained separately per worktree - (e.g. the index, HEAD and pseudorefs like MERGE_HEAD, - per-worktree refs and per-worktree configuration file). -+ (e.g. the index, per-worktree refs such as HEAD, pseudorefs -+ such as MERGE_HEAD, and the per-worktree configuration file). ++ (e.g. the index, <>, and the ++ per-worktree configuration file). 3: 8cdd299c28 ! 3: 73dcb3d715 doc: stop calling root refs pseudorefs @@ Commit message there, correct "symbolics" to "symbolic refs". In git-update-ref(1), drop the incorrect mention of ORIG_HEAD. HEAD is - the only root ref that gets a reflog by default. Also restructure the - sentence to make it easier to parse. + the only root ref that gets a reflog by default. In the description of + core.logAllRefUpdates, correct the claim that "always" only applies to + refs under "refs/". It applies to root refs too. - In the description of core.logAllRefUpdates, correct the claim that - "always" only applies to refs under "refs/". It applies to root refs - too. + Distinguish root refs and pseudorefs in gitdatamodel(7). Lowercase the + "other references" list entry there to match the others. Signed-off-by: Andy Koppe @@ Documentation/git-worktree.adoc: but others are specific to an individual worktr -however: refs inside `refs/bisect`, `refs/worktree` and `refs/rewritten` are -not shared. +In general, all root refs and pseudorefs are per-worktree and all refs -+starting with `refs/` are shared. There are exceptions, however: refs -+inside `refs/bisect`, `refs/worktree` and `refs/rewritten` are not -+shared. ++starting with `refs/` are shared, except for refs with the following prefixes: ++ ++ - `refs/bisect/` ++ ++ - `refs/rewritten/` ++ ++ - `refs/worktree/` Refs that are per-worktree can still be accessed from another worktree via two special paths, `main-worktree` and `worktrees`. The former gives + ## Documentation/gitdatamodel.adoc ## +@@ Documentation/gitdatamodel.adoc: remote-tracking branches: `refs/remotes//`:: + default branch. This is the branch that `git clone` checks out by default. + + [[other-refs]] +-Other references:: ++other references:: + Git tools may create references anywhere under `refs/`. + For example, linkgit:git-stash[1], linkgit:git-bisect[1], + and linkgit:git-notes[1] all create their own references + in `refs/stash`, `refs/bisect`, etc. + Third-party Git tools may also create their own references. +-+ +-Git may also create references other than `HEAD` at the base of the +-hierarchy, like `ORIG_HEAD`. ++ ++[[root-refs]] ++root refs:: ++ Git may also create references other than `HEAD` at the root of the ++ hierarchy, for example `ORIG_HEAD` or `REBASE_HEAD`. ++ ++[[pseudorefs]] ++pseudorefs:: ++ linkgit:git-fetch[1] and linkgit:git-merge[1] create the so-called ++ pseudorefs `FETCH_HEAD` and `MERGE_HEAD`. They are not references as ++ such, as they are not stored in the same way, but they can nevertheless ++ be used to refer to objects in commands such as linkgit:git-log[1] and ++ linkgit:git-diff[1]. + + NOTE: Git may delete objects that aren't "reachable" from any reference + or <>. + ## Documentation/rev-list-options.adoc ## @@ Documentation/rev-list-options.adoc: Under `--pretty=reference`, this information will not be shown at all. 4: 8bb6d5435c ! 4: eb3d64fa96 refs: stop calling root refs pseudorefs @@ Commit message Some messages and comments in the code still use "pseudoref" in its old sense of any ref outside of "refs/", whereas the glossary now calls - those root refs and restricts pseudorefs to FETCH_HEAD and MERGE_HEAD. + those root refs and restricts pseudorefs to FETCH_HEAD and MERGE_HEAD, + so update them. - Replace "pseudoref" with "root ref" in the help text for - "git for-each-ref --include-root-refs", in comments in refs.h, and in - comments in the bash completion script, including the one for - __git_pseudoref_exists(), which is also used for root refs. The function - itself is not renamed. There is no obvious term covering both root refs - and pseudorefs, and the old name might need to be kept for third-party - completion scripts. - - Update the description of pseudorefs in refs.h to match the glossary. + Bash completion function __git_pseudoref_exists() is not renamed, as + there is no obvious term covering both root refs and pseudorefs, and + third-party completion scripts might depend on the name. Signed-off-by: Andy Koppe 5: c681a032ba = 5: 31022553a6 t: stop calling root refs pseudorefs -- 2.56.0