Problem
git worktree remove is not transactional. If DMC cleanup times out or is interrupted while Git is deleting files, the handle stays registered and the checkout is left with mass tracked deletions.
Observed on static-site-importer@fix-1397-release-profile:
- DMC metadata:
lifecycle_state=cleanup_eligible, cleanup_policy=remove_on_success, liveness=stopped / lifecycle_finalized
- Git still lists the worktree;
.git marker still points at the primary worktree admin dir
- Working tree has 34 tracked deletions (
LICENSE, tools/*, bench/*, blocks/importer/*, …) and zero modifications/untracked files
- Inventory still reports the handle (
dirty: 34, stale: dirty)
remove_worktree_by_path() in inc/Workspace/WorkspaceWorktreeCleanupEngine.php already distinguishes:
- Git error + directory gone → treat as partial success and drop metadata (
filesystem_removed_git_metadata_failed)
- Git error + directory still present → return the error and leave the checkout as-is
A timed-out git worktree remove hits the second branch after files have already been deleted. The next apply then skips the row as dirty unless --force is used.
Expected
- Interrupted/timed-out remove is either completed or rolled back to a complete checkout before metadata is left in place.
- A registered worktree is never left with only tracked deletions from a failed remove.
- Retry is idempotent: complete the remove if the handle is still cleanup-eligible and the only dirt is those deletions, or restore from HEAD and skip without
--force.
- Evidence names the incomplete-remove state (
remove_incomplete / remove_timeout) instead of generic dirty.
Reproduction
- Mark a populated worktree
cleanup_eligible with remove_on_success.
- Start bounded cleanup-eligible apply with a removal timeout short enough to kill
git worktree remove mid-delete.
- Observe the directory still present,
git status showing only tracked deletions, and inventory still listing the handle.
Related
AI assistance
xAI grok-4.6 via OpenCode inspected the live static-site-importer@fix-1397-release-profile git/DMC state and WorkspaceWorktreeCleanupEngine::remove_worktree_by_path, then drafted this issue. Chris Huber directed the investigation. No code was changed in this repo.
Problem
git worktree removeis not transactional. If DMC cleanup times out or is interrupted while Git is deleting files, the handle stays registered and the checkout is left with mass tracked deletions.Observed on
static-site-importer@fix-1397-release-profile:lifecycle_state=cleanup_eligible,cleanup_policy=remove_on_success,liveness=stopped/lifecycle_finalized.gitmarker still points at the primary worktree admin dirLICENSE,tools/*,bench/*,blocks/importer/*, …) and zero modifications/untracked filesdirty: 34,stale: dirty)remove_worktree_by_path()ininc/Workspace/WorkspaceWorktreeCleanupEngine.phpalready distinguishes:filesystem_removed_git_metadata_failed)A timed-out
git worktree removehits the second branch after files have already been deleted. The next apply then skips the row as dirty unless--forceis used.Expected
--force.remove_incomplete/remove_timeout) instead of generic dirty.Reproduction
cleanup_eligiblewithremove_on_success.git worktree removemid-delete.git statusshowing only tracked deletions, and inventory still listing the handle.Related
git worktree removemutation.worktree_remove_incomplete/remove_timeoutcodes do not restore or finish a half-deleted checkout.AI assistance
xAI grok-4.6 via OpenCode inspected the live
static-site-importer@fix-1397-release-profilegit/DMC state andWorkspaceWorktreeCleanupEngine::remove_worktree_by_path, then drafted this issue. Chris Huber directed the investigation. No code was changed in this repo.