~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A git killed part way no longer leaves a mirror's refs stuck

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/mirror-stale-lock

What changes

Before a mirror's refs move, any lock file under its refs/ is removed.

Why

A git killed while it sets the refs leaves refs/heads/<branch>.lock. Every later update-ref is then refused, and every read of that repository answers 502 with cannot lock ref, until someone removes the file by hand. Nothing clears it, as the turns the mirror's processes take are held by the system's lock, not this file.

It failed e2e on another pull, in "merging a pull": every page of bob.test/tally was 502 for the whole 30 seconds the flow waited, naming refs/heads/bytes.lock, from the first read of that repository in the flow. The flows' setup stops the server that seeded the world (world.server.kill()) and starts another over the same mirrors, which is the likely way the file got there, though the log does not show it being left. A server stopped by a deploy could do the same.

It is safe because settle is the only thing that sets a mirror's refs, and it holds their lock while it does.

How it was checked

A new test in mirror.rs leaves a lock beside the branches and one in a folder under them, and the refs still move. The rest is left to CI.

Shortcomings

The lock is cleared only when the refs move. One that is left with the refs already right stays there harmlessly until they next do. HEAD.lock is not handled: nothing has shown it being left, and a repository's default branch rarely moves.

🤖 Generated with Claude Code

Approved

Before settle moves a mirror's refs, it now removes every *.lock file under refs/. A git killed part way no longer leaves the refs stuck. The safety argument holds. settle is the only writer of the refs and holds the cache's lock. The tidy path only runs repack, which takes no ref locks. Git refuses ref names ending in .lock, so the sweep can't delete a real ref. The test covers a lock beside the branches and one in a subfolder. The docs page and the change file are updated. No changes needed. The limits you list (a lock is cleared only when the refs move, and HEAD.lock is not handled) are fair.

Approved

The pull still clears every *.lock file under a mirror's refs/ before settle moves the refs. My earlier approval had no requested changes, so there is nothing to check off. The sweep is safe: settle holds the refs' lock, and git refuses ref names ending in .lock, so the sweep can't remove a real ref. The test covers a lock beside the branches and one in a subfolder. The changeset and the storage doc are updated. Nothing blocks merging.

Merged as 1732db5