Re: [PATCH v2 0/5] root refs vs pseudorefs

From
Junio C Hamano <hidden>
Date
2026-11-02 21:49:03
Reply to
Julia Evans, 2026-11-02
"Julia Evans" [off-list ref] writes:

... 200 lines of quoted material omitted ...
quoted
    ++[[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
When I look at my .git directory during a merge conflict, I see these
files:

$ ls .git | grep HEAD
FETCH_HEAD
HEAD
MERGE_HEAD
ORIG_HEAD

From the above, it sounds like ORIG_HEAD is a "root ref" and
MERGE_HEAD is a "pseudoref", but naively it does look like
they're stored in the same way. What's the difference?
A pseudoref cannot be treated as a true ref because it can describe
multiple objects.  If you force it to be interpreted as an object,
you will still get one of the objects, but that is not the primary
way it is designed to be used.  FETCH_HEAD even describes the nature
of each object, e.g.,

a018953...4		branch 'maint' of gitolite.kernel.org:/pub/scm/git/git
8d1b215...8	not-for-merge	branch 'master' of gitolite.kernel.org:/pub/scm/git/git
882cbad...5	not-for-merge	branch 'next' of gitolite.kernel.org:/pub/scm/git/git
4231a2f...4	not-for-merge	branch 'jch' of gitolite.kernel.org:/pub/scm/git/git
2fa90fe...8	not-for-merge	branch 'seen' of gitolite.kernel.org:/pub/scm/git/git

The other kind, just like a normal ref, describes one and only one
object.  The only special trait it has is that it is outside the
refs/ hierarchy, so it may be a slight misnomer to call them "root"
refs.  We do accept $GIT_DIR/ORIG_HEAD as if it were a real ref, but
if we did:

        $ mkdir -p .git/foo/bar
        $ git rev-parse HEAD~24 >.git/foo/bar/baz
        $ git show -s foo/bar/baz

we would end up treating "foo/bar/baz" as if it were a real ref,
too, with exactly the same mechanism used to treat ORIG_HEAD.

The only difference between .git/ORIG_HEAD and .git/foo/bar/baz in
the above example is that we _do_ create "root" refs ourselves,
while we do not create such funky things like foo/bar/baz (hence
they do not deserve a name, and such "use" may suddenly break
without notice).

By the way, *please* trim your quote.  Having to scroll past 200
lines of material that are totally irrelevant to understanding your
comment is a real pain.

Thanks.
Thread (45 messages) 45 messages, 4 authors, last reply 1d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help