The strip broke real repositories: restore tolerance for legacy field and ref shapes #104

Closed
opened 2026-08-14 08:27:27 +00:00 by a73x · 0 comments
a73x commented 2026-08-14 08:27:27 +00:00 (Migrated from git.a73x.sh)

e5096ffc (patch bf948322) removed compatibility that live data still depends on. Two of the user's repositories are now unreadable and unsyncable.

$ git-collab sync            # in ~/code/rad/eitri
error: sync with 'a73x' failed: refs/collab/patches/0b72bae8… is in a patch ref
layout written by an older git-collab, which this version no longer reads.
Sync incomplete: 2 of 2 remote(s) failed.

Scope: eitri (17 legacy patch refs) and waystty (11). Both hold the same shapes on their sourcehut remote, byte-identical to local.

The layout is only half of it. I migrated a copy of eitri with a pre-strip binary: 17 bare refs became 17 /events refs, and the current binary still reads only 1 of 17. The rest fail with:

warning: skipping patch 0b72bae8: missing field `commit` at line 14 column 3

The event is a merge recorded before merge-recording stored a commit:

{"action": {"type": "patch.merge"}, "clock": 5, ...}

Why this happened, plainly. The strip decision was made on an audit of this clone and the five repositories on the server. The user's other clones sat in ~/code/rad the whole time, reachable, and were never examined. commit tolerance was then removed on a zero-users finding drawn from that narrow sample.

The reasoning failure is sharper than the sampling one. For base: None I argued — correctly — that "this revision has no recorded base" is a real state, not a transitional artefact, because a revision recorded before the field existed genuinely has no base and no migration can invent one. The identical argument applies to commit on a merge event, and I did not apply it. One field was kept on principle, the other removed on a headcount.

Also wrong: the recovery advice. fetch the patch from a remote holding the current layout, or delete the stale ref if it exists nowhere else offers two remedies, and neither fits the most likely case — every copy is old, so there is nothing newer to fetch and the ref exists elsewhere. It reads as helpful and is a dead end.

Wanted

  1. Restore tolerance for legacy field shapes, treating absence as the unknown it is: PatchMerge.commit optional (matching how Revision.base is handled), and anything else the audit below turns up.
  2. Restore the ability to read the bare <id> layout, or restore migration. Reading is the minimum; a repository must not become unreachable because the only copies are old.
  3. Re-audit against real data before deciding anything else. Every repository under ~/code/rad, not a sample: git-collab refs per repo for ref shapes, plus a field-level scan of every event.json for missing/empty commit, absent base, and reviews without a revision.
  4. Fix the recovery message so it covers the case where every copy is legacy.
  5. Re-scope e5096ffc. Removing dead code was fine; removing tolerance for data shapes was not. The distinction is whether the shape can still exist in data someone holds — and pre-release does not mean the user's own repositories are disposable.

Migrated from git-collab issue 05b18df6b5902b0c9cead855f916be1b75af9f59.

Original author: a73x dev@a73x.sh.

Close reason: merged in patch 2cb9ca96

`e5096ffc` (patch bf948322) removed compatibility that live data still depends on. Two of the user's repositories are now unreadable and unsyncable. ``` $ git-collab sync # in ~/code/rad/eitri error: sync with 'a73x' failed: refs/collab/patches/0b72bae8… is in a patch ref layout written by an older git-collab, which this version no longer reads. Sync incomplete: 2 of 2 remote(s) failed. ``` **Scope:** `eitri` (17 legacy patch refs) and `waystty` (11). Both hold the same shapes on their sourcehut remote, byte-identical to local. **The layout is only half of it.** I migrated a copy of `eitri` with a pre-strip binary: 17 bare refs became 17 `/events` refs, and the current binary still reads only **1 of 17**. The rest fail with: ``` warning: skipping patch 0b72bae8: missing field `commit` at line 14 column 3 ``` The event is a merge recorded before merge-recording stored a commit: ```json {"action": {"type": "patch.merge"}, "clock": 5, ...} ``` **Why this happened, plainly.** The strip decision was made on an audit of this clone and the five repositories on the server. The user's other clones sat in `~/code/rad` the whole time, reachable, and were never examined. `commit` tolerance was then removed on a zero-users finding drawn from that narrow sample. The reasoning failure is sharper than the sampling one. For `base: None` I argued — correctly — that "this revision has no recorded base" is a **real state**, not a transitional artefact, because a revision recorded before the field existed genuinely has no base and no migration can invent one. **The identical argument applies to `commit` on a merge event**, and I did not apply it. One field was kept on principle, the other removed on a headcount. **Also wrong: the recovery advice.** `fetch the patch from a remote holding the current layout, or delete the stale ref if it exists nowhere else` offers two remedies, and neither fits the most likely case — every copy is old, so there is nothing newer to fetch and the ref exists elsewhere. It reads as helpful and is a dead end. ## Wanted 1. **Restore tolerance for legacy field shapes**, treating absence as the unknown it is: `PatchMerge.commit` optional (matching how `Revision.base` is handled), and anything else the audit below turns up. 2. **Restore the ability to read the bare `<id>` layout**, or restore migration. Reading is the minimum; a repository must not become unreachable because the only copies are old. 3. **Re-audit against real data before deciding anything else.** Every repository under `~/code/rad`, not a sample: `git-collab refs` per repo for ref shapes, plus a field-level scan of every `event.json` for missing/empty `commit`, absent `base`, and reviews without a revision. 4. **Fix the recovery message** so it covers the case where every copy is legacy. 5. **Re-scope e5096ffc.** Removing dead code was fine; removing tolerance for data shapes was not. The distinction is whether the shape can still exist in data someone holds — and pre-release does not mean the user's own repositories are disposable. --- Migrated from git-collab issue `05b18df6b5902b0c9cead855f916be1b75af9f59`. Original author: a73x <dev@a73x.sh>. Close reason: merged in patch 2cb9ca96
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
a73x/git-collab#104
No description provided.