Repository navigation
feat(wal): record HEAD at creation and heal a dangling HEAD on push - #59
Conversation
PR SummaryMedium Risk Overview Configuration and creation add Publish path appends an automatic HEAD retarget when a push creates Policy/docs clarify that clients cannot push Reviewed by Cursor Bugbot for commit d826e4f. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 36 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
530dad0 to
4d0935e
Compare
…ute to move it
A repository created by a push that contains no `main` kept HEAD -> refs/heads/main
(nonexistent): the UI showed "This repository is empty" and clones warned "remote HEAD
refers to nonexistent ref" although the repository had branches. Receive-pack cannot
set HEAD, and only `walgit import` wrote symbolic HEAD updates.
HEAD stays where refs live (checkpoint RefSnapshot.head_target + symbolic HEAD updates in
log transactions); no record means walgit_git::IMPLICIT_HEAD (refs/heads/main), now a
named format constant. No proto change.
- `git.default_branch` (default "main", validated as a short Git branch name) and
`PUT /{o}/{r}?default_branch=` name HEAD's branch for a new repository. The implicit
target records nothing (one manifest Create, as before); any other target is the
repository's first entry (HEAD-only REF_UPDATE): its log slot is claimed as a publish
claims one and the manifest Create lists it, so the repository appears with its HEAD in
one commit. Lost Create replies resolve through cas_landed. `walgit repo create
--default-branch`, `Registry::create_with_default_branch`.
- Heal: a publish that creates refs/heads/* while HEAD resolves to nothing before and
after it appends `HEAD -> <target>` to its own entry's transaction: default_branch if
created, else the lexicographically first created branch. Computed on each attempt's
CAS basis inside process_batch, so it commits with the refs that justify it. A txn that
names HEAD keeps it; deleting HEAD's branch leaves it dangling until such a publish.
Clients never see HEAD in report-status.
- `PUT /{o}/{r}/api[-browser]/head {"branch"}` (admin): `RepoHandle::publish_head` through
the same publisher; the target must exist on the attempt's CAS basis (re-checked on
every retry); idempotent (seq 0). 409 when the branch does not exist.
- Policy: the pushed-`HEAD <oid>` refusal (`ng funny refname` under every policy) comes
from the base, conxai/receive-pack-refname (689d96e); this commit only rewords its
comment to name the heal rule and the admin route as HEAD's symbolic writers.
- Fix: apply_txn_to_map stored a symbolic HEAD update in the ref map instead of
head_target, so later requests of the same batch saw the old HEAD.
- Events: unchanged. Symbolic retargets already emit nothing.
Round trips (docs/ROUNDTRIPS.md): push/publish unchanged (heal is 0 extra); create
1 -> 1 for the implicit HEAD, 2 sequential for any other (once per repository); admin
HEAD route = refs sync -> log PUT -> CAS (3 rounds, like a settings publish). Budget test
healthy_request_round_trip_budgets unchanged.
Docs: AGENTS.md D54, walgit.example.toml, web/API.md, SDK (repo.create({defaultBranch}),
repo.setHead), docs/CONTRACT.md, docs/POLICY.md, docs/ROUNDTRIPS.md.
Rebased onto conxai/receive-pack-refname from 846d8ed, dropping its duplicate of the
funny-refname check and test.
Adapted: the decision is D54 here (D50-D53 are taken); create keeps this branch's reset marker and resolves a 412 or lost reply on its claimed log slot through slot_evidence, so a retried Create that already landed never loses its own segment.
(cherry picked from commit e3cab23)
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
default_branch_is_chosen_at_creation_healed_by_push_and_moved_by_admin declared two consts after statements; clippy -D warnings (items_after_statements, all targets) failed on them. They are promoted 'static lets now, renamed so they do not shadow the test's array-valued writer/admin. (cherry picked from commit 9e347a4) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Every sim scenario pushes refs/heads/p<N> into a fresh repository, so since the HEAD heal (D54) each first push's log entry also carries `HEAD -> refs/heads/p0` (a symbolic update, no oid). check_truth folded every update's new_oid and then parsed each as an object id: `A hash sized 0 hexadecimal characters is invalid`, 10 of 19 sim tests red under `just sim`. conxai/default-head did not touch sim.rs; the failure is the topic's, surfaced by the full tree run. The fold now tracks object moves only; HEAD's target is not an object to materialize. (cherry picked from commit fe8c639) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
… one refs_at_seq and refs_as_of started from an empty snapshot, so a repository with no HEAD record reported no HEAD at a cut while every live copy and checkpoint says refs/heads/main. The replay now starts from the implicit default, and the sim comment names the renumbered decision (D54). Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
4d0935e to
d826e4f
Compare
mainhad no way to say so at creation or to move HEAD afterwards without touching the bucket by hand.