Skip to content

lane-reconcile's on-disk sweep passes over a directory under a lane root whose .git git cannot read: a worktree whose gitdir is gone is never named, where lane-worktrees names it #258

Open

Description

@brettheap

This is left over from PR #252, lane openRepoTools-4's fix for #113, #114 and #115, which lists it as a follow-up. #252's independent review (r1, SHOULD 6) asked for it to be filed so it isn't lost when #113 closes. It is not one of #113's four reads, and #252 does not change it.

Searched first: no open or closed issue names lane-reconcile's on-disk sweep, a worktree whose gitdir is gone, or an unreadable .git under a lane root.

The finding

Lines are lanes-edit.sh at #252's head 3ffefce.

lane_reconcile's on-disk sweep walks the lane's worktree roots (lane_worktree_roots, :13135). It reports as unmanaged every child that is a repository and that no sidecar names. It decides whether a child is a repository by asking git (:13578):

git -C "$lrc_c" rev-parse --git-dir >/dev/null 2>&1 || continue

So a child that git cannot read is passed over as if it held nothing. That turns a failed read into an absence (R22, Amendment 7(d)).

The rule #170 G5 settled is the opposite: a directory with a .git entry of its own IS a repository, however broken. It is applied in three places:

  • lane-worktrees' sweep (lane-worktrees:2244-2246);
  • its no_repository (:4239);
  • lanes-edit.sh's lane_no_repository (:13238), for the lane's own checkout.

So the two readers of one lane's roots disagree.

Which children the sweep misses

Probed with git 2.43.0:

child git -C <child> rev-parse --git-dir on-disk sweep lane-worktrees (by :2244-2246)
a worktree whose admin directory is gone: a .git file whose gitdir: names a removed <checkout>/.git/worktrees/<id>, under .claude/worktrees or under .lane-worktrees/<lane> 128, fatal: not a git repository: <gitdir> skipped named (lane-root)
a .git directory git cannot read (mode 000) under .lane-worktrees/<lane>, outside any repository 128, fatal: not a git repository (or any of the parent directories): .git skipped named (clone)
the same under .claude/worktrees, inside the lane's checkout 0, because git falls back to the checkout's own .git named named

The first case is not hypothetical. On 2026-10-15, a git worktree prune run from an environment without /workspace emptied a shared checkout's .git/worktrees and orphaned every lane's trees in exactly this way.

Such a tree is in no registration, so git worktree list does not name it. Unless a sidecar records it, the on-disk sweep is the only read that could. The report then never names it. A launcher that reads resumable (a SWAPPED lane with no live holder) goes past a tree that may hold uncommitted or unpushed work.

What would fix it

Whose it is

lanes-edit.sh's lifecycle is lane openRepoTools-3's tooling. Amendment 23's act 2 (lane openRepoShape-2) rewrites it, so the fix may belong in that rewrite.

Refs #113, PR #252.

🤖 Generated with Claude Code

Lane: openRepoTools-4

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions