Serving a page rewrites the hosted repo: anonymous HTTP triggers ref migration #80
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
state::list_patchescallsmigrate_patch_layout(repo)(state.rs:1722), and the server callslist_patcheson every repo page —repo/mod.rs:59,overview.rs:65,patches.rs:190. So rendering a page writes to the repository being served.Demonstrated against a live server with one repo holding a single old-layout patch ref, and one unauthenticated request:
The data survives. The events tip is byte-identical afterwards and the patch reads correctly from a fresh clone, so this is not corruption. The migration is careful and resumable, which is why it has gone unnoticed.
What is wrong is that it happens at all, on a read, from an unauthenticated request, with no lock:
migrate_patch_layouttakes no lock. Two concurrent requests can migrate the same repo at once, and a request can migrate whilereceive-packis writing.Pre-existing, from
20afe11— the migration was written for the client, where the caller owns the repo, and the server inherited it by calling the same function.Fix: the server must not migrate. Options: a read path that tolerates both layouts without writing; or migration behind an explicit
git-collab-server migratean operator runs; or a flag the server sets to make reads non-migrating. Whichever, it needs to hold untile5096ffcstrips legacy support, after which the server would simply fail to read an unmigrated repo — which is an argument for the explicit command, so an operator can migrate before upgrading rather than discovering it afterwards.Found while checking whether upgrading a deployed server would damage existing repos.
Migrated from git-collab issue
5174338fb305c0c0d4b9f7eb5a2ec207c57d00a7.Original author: a73x dev@a73x.sh.
Close reason: merged in patch
46c3cdc5