Files
orca/docs/reference/malformed-worktree-registration-removal.md
Neil 41e42beab4 fix(worktrees): safely remove prunable git-file registrations (#20617)
Preserve checkout files and the named branch when removing a positively attested malformed Git-file registration. Reject file/symlink targets in deferred directory deletion.

Verified exact head with 75 focused tests including actual Git malformation, preserved marker/file bytes and branch HEAD. Independent review and complete product CI passed. WSL routing is covered by unit tests; direct SSH fails safely without local recovery.

Fixes #17316
2026-09-14 14:52:45 -07:00

44 lines
2.5 KiB
Markdown

# Malformed worktree registration removal
Git can report a linked worktree at `<checkout>/.git` when its administrative
`gitdir` backlink incorrectly ends in `.git/.git`. That reproduces #17316's
validation error. The reproduction establishes the malformed registration, not
which program created it; current OMP uses ordinary `git worktree add`.
Orca's desktop and runtime removal entry points use registration-only recovery
when Git positively marks the row prunable, the row has a named local branch and
HEAD, it is neither main nor locked, and the execution filesystem confirms the
selected `.git` path is a regular file. Missing or unknown evidence does not
permit this recovery. A symlink or directory is not a regular-file proof.
Recovery reuses `git worktree prune` followed by a strict worktree listing that
must confirm the selected registration is gone. It does not delete the selected
file, infer a parent path for deletion, or delete the branch. Archive hooks and
checkout teardown are skipped because the selected row is not a checkout.
Two consequences are intentional:
- Git's prune also clears other stale, unlocked registrations in the repository;
it is not a path-scoped command. Live and locked registrations remain Git's
responsibility, and Orca verifies that the requested registration disappeared.
- The surviving checkout's `.git` file points at removed administrative metadata.
Files and its named branch are preserved; recovery removes the broken navigation
entry and does not repair or claim to restore that checkout.
Native and WSL checks use the existing execution-filesystem accessor. WSL prune
and verification use the same selected distro. Paired runtimes run the recovery
on their owning host. Direct SSH does not enter this local recovery: its current
provider has no registration-only removal operation, and a failed remote removal
never authorizes a local fallback.
The Git commands already exist in the 2.25-compatible cleanup path. On an older
Git that cannot positively attest this file-shaped registration as prunable, Orca
refuses this recovery. Deferred deletion independently rejects non-directory and
symlink targets, so force cannot move a `.git` file into deletion trash.
Regression coverage is in `worktree-prunable-git-file.test.ts`,
`worktrees-removal-recovery.test.ts`, and
`worktree-deferred-removal-real-git.test.ts`. The latter reproduces the exact
malformation against the installed Git binary in a disposable repository and
checks surviving file contents, branch HEAD, and removed registration.