pub struct RefCas<'a> {
pub name: String,
pub old: Option<Oid<'a>>,
pub new: Option<Oid<'a>>,
pub peeled: Option<Vec<u8>>,
}Expand description
One ref edit with the value the caller expects to find.
This is the field RefUpdate lacks, and its absence is the whole reason
git push --atomic could not be expressed: GitOps::put_refs is a batch
without compare-and-swap and GitOps::update_ref is compare-and-swap
without a batch, and --atomic is defined as both at once. Neither
composes into the other — applying a batch one CAS at a time is exactly the
partial application --atomic promises never to happen.
old and new are borrowed, like every other oid in this contract: a
receive-pack command line is <old> <new> <ref> and both oids are already
slices of the pkt-line the caller is holding. peeled is
the one that is owned, because it is not on the wire — it is derived by
the server, once, at ingest.
Fields§
§name: String§old: Option<Oid<'a>>What the caller believes is there. None means must not exist — a
create that must fail if anything is already at name.
There is deliberately no third “don’t care” state. receive-pack always
names an old value (all-zeroes for a create), so a caller that genuinely
does not care wants GitOps::put_refs, which is the batch that makes no
claim about the previous value.
new: Option<Oid<'a>>The new value. None deletes.
peeled: Option<Vec<u8>>For an annotated tag, the commit new peels to — the terminal non-tag
object, following a tag-of-a-tag all the way down, exactly as git’s
packed-refs stores its ^peeled line.
Owned, and None for everything else. A branch head, a lightweight
tag and a delete peel to nothing worth storing, so they carry None;
only a new that is itself a tag object carries Some. The backend
persists it in the ref row’s peeled column so the advertisement
(GitServe) reads the peeled target straight out of the row and never
re-peels — the object read per tag that every clone, fetch and ls-remote
used to pay (gunnar stinky S-080) falls to zero.
It is owned rather than an Oid because, unlike old/new, it is not
a slice of any pkt-line the caller holds: the peel is computed by the
server from the objects the push just delivered. A backend that keeps no
peel column, or a caller that does not compute one, leaves it None and
the advertisement falls back to peeling — correct, only not free.