Han-Wen Nienhuys <hanwen@xxxxxxxxxx> writes: > For FETCH_HEAD, doing > > git fetch host refs/changes/23/123/1 && git checkout FETCH_HEAD > > is the standard idiom for downloading a change from Gerrit. I suspect > there might be other similar idioms. This means we have to read them > through the refs machinery. This merely means we have to read them through the object-name machinery around get_oid(). Historically that was done by calling repo_dwin_ref() from get_oid_basic(), which is where refs machinery enters the picture, and because we had only files backend, it was OK and convenient to treat .git/FETCH_HEAD and .git/refs/heads/master in the same codepath. But there is no reason for the arrangement to stay that way. .git/FOOBAR_HEAD files can be read as a file (we can say we let files-backend to handle it, but we can also extract a helper function out of it and make it clear that it truly has no dependence on the refs machinery) while .git/refs/* can be read from the refs machinery that may be backed by reftable backend. > I think the most sensible approach is to pass the read/write through > refs_* functions, but special-case the storage, so it doesn't go > through reftable. We already do this for FETCH_HEAD and MERGE_HEAD in > refs_read_raw_refs. I think we are more or less on the same page. I do not think these files behave like refs (they have no reflog, and they do not serve as anchoring points for the purpose of gc/fsck) and we need a special code path, which might be identical to the current ref-files backend code, to handle them no matter what backend is used for true refs. > This means we need a formal definition of which refs should be treated > as files. Maybe we could do as follows: > > Pseudorefs are > 1) all uppercase toplevel names except for HEAD > 2) all refs that are not under refs/* (for example: > rebase-{merge,apply}/autostash) > > Pseudorefs are always stored as files containing a hex object_id. > > Pseudorefs can be read or written through refs_* functions, but given > the storage guarantees, it's also valid to read/write them outside > refs_* functions > > It is forbidden to make cross-ref transactions that involve pseudorefs.