From: Andy Koppe Date: Mon, 02 Nov 2026 22:19:53 GMT Subject: Re: [PATCH v2 0/5] root refs vs pseudorefs Message-ID: In-Reply-To: On Mon, 2 Nov 2026 at 21:01, Julia Evans wrote: > On Mon, Nov 2, 2026, at 2:47 PM, Andy Koppe wrote: > > Root refs: > > - Can be stored in reftables instead of files in .git. > > - Contain either a single hash or a single symbolic ref such as 'ref: > > refs/heads/main'. > > - Can be modified with 'git update-ref' (generally a bad idea for > > built-in root refs) and listed with 'git for-each-ref' and similar > > commands. > > > > Pseudorefs: > > - Are always stored as files in .git. > > - May contain multiple hashes, and in the case of FETCH_HEAD, carry > > additional information about where each hash came from. > > - Are only modified by the commands they serve (i.e. fetch, merge and > > pull) and can't be listed. > > > > The big thing they have in common, apart from the *_HEAD names, is > > that you can pass both types to commands such as 'git log', 'git diff' > > or 'git checkout' to refer to a commit or tree, just like any ref > > under refs/. > > That’s very helpful. I think it would make sense to include > “may contain multiple hashes” at least, that on its own > makes it very clear what the difference is. > > My impression is that FETCH_HEAD specifically is a > relatively popular pseudoref and folks would be interested to > know that it can contain multiple hashes. > > If a pseudoref contains multiple hashes and you pass it to > a command, will the command use the first hash? > > Also are FETCH_HEAD and MERGE_HEAD the only > pseudorefs? I think the pseudoref glossary entry covers these questions. As it appears in 'man' after v2: pseudoref A name that can be used like a ref to refer to an object, but that is not stored in the same way as refs. For example, pseudorefs can be passed to git-log(1) or git-diff(1), but they cannot be written by git-update-ref(1) or listed by git-for-each-ref(1). The following pseudorefs are known to Git: • FETCH_HEAD is written by git-fetch(1) or 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 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.