Hi Patrick
On 29/04/2024 14:41, Patrick Steinhardt wrote:
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index d71b199955..4275918fa0 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -497,20 +497,28 @@ exclude;;
unusual refs.
[[def_pseudoref]]pseudoref::
- Pseudorefs are a class of files under `$GIT_DIR` which behave
- like refs for the purposes of rev-parse, but which are treated
- specially by git. Pseudorefs both have names that are all-caps,
- and always start with a line consisting of a
- <<def_SHA1,SHA-1>> followed by whitespace. So, HEAD is not a
- pseudoref, because it is sometimes a symbolic ref. They might
- optionally contain some additional data. `MERGE_HEAD` and
- `CHERRY_PICK_HEAD` are examples. Unlike
- <<def_per_worktree_ref,per-worktree refs>>, these files cannot
- be symbolic refs, and never have reflogs. They also cannot be
- updated through the normal ref update machinery. Instead,
- they are updated by directly writing to the files. However,
- they can be read as if they were refs, so `git rev-parse
- MERGE_HEAD` will work.
+ Pseudorefs are references that live in the root of the reference
+ hierarchy, outside of the usual "refs/" hierarchy. Pseudorefs have an
+ all-uppercase name and must end with a "_HEAD" suffix, for example
+ "`BISECT_HEAD`". Other than that, pseudorefs behave the exact same as
+ any other reference and can be both read and written via regular Git
+ tooling.
This changes the definition to allow pseudorefs to by symbolic refs.
When is_pseudoref() was introduced Junio and I had a brief discussion
about this restriction and he was not in favor of allowing pseudorefs to
be symbolic refs [1].
Are there any practical implications of the changes in this patch for
users running commands like "git log FETCH_HEAD" (I can't think of any
off the top of my head but it would be good to have some reassurance on
that point in the commit message)
Best Wishes
Phillip
[1] https://lore.kernel.org/git/xmqq34u2q3zs.fsf@gitster.g/
+<<def_special_ref>,Special refs>> are not pseudorefs.
++
+Due to historic reasons, Git has several irregular pseudo refs that do not
+follow above rules. The following list of irregular pseudo refs is exhaustive
+and shall not be extended in the future:
+
+ - "`AUTO_MERGE`"
+
+ - "`BISECT_EXPECTED_REV`"
+
+ - "`NOTES_MERGE_PARTIAL`"
+
+ - "`NOTES_MERGE_REF`"
+
+ - "`MERGE_AUTOSTASH`"
[[def_pull]]pull::
Pulling a <<def_branch,branch>> means to <<def_fetch,fetch>> it and
diff --git a/refs.c b/refs.c
index c64f66bff9..567c6fc6ff 100644
--- a/refs.c
+++ b/refs.c
@@ -905,6 +905,8 @@ int is_pseudoref(struct ref_store *refs, const char *refname)
if (!is_pseudoref_syntax(refname))
return 0;
+ if (is_special_ref(refname))
+ return 0;
if (ends_with(refname, "_HEAD")) {
refs_resolve_ref_unsafe(refs, refname,
diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
index 948f1bb5f4..8c92fbde79 100755
--- a/t/t6302-for-each-ref-filter.sh
+++ b/t/t6302-for-each-ref-filter.sh
@@ -52,6 +52,23 @@ test_expect_success '--include-root-refs pattern prints pseudorefs' '
test_cmp expect actual
'
+test_expect_success '--include-root-refs pattern does not print special refs' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ (
+ cd repo &&
+ test_commit initial &&
+ git rev-parse HEAD >.git/MERGE_HEAD &&
+ git for-each-ref --format="%(refname)" --include-root-refs >actual &&
+ cat >expect <<-EOF &&
+ HEAD
+ $(git symbolic-ref HEAD)
+ refs/tags/initial
+ EOF
+ test_cmp expect actual
+ )
+'
+
test_expect_success '--include-root-refs with other patterns' '
cat >expect <<-\EOF &&
HEAD