Worktree cleanup silently deletes branches with unmerged commits

Resolved 💬 9 comments Opened Mar 24, 2026 by lastdomovoi Closed May 5, 2026

Description

When using claude -w to create a worktree session, Claude Code creates a temporary branch (e.g., worktree-expressive-painting-starfish). When the session ends, the worktree is cleaned up and the branch is deleted — even if it contains commits that were never pushed or merged.

This results in silent data loss. The commits become dangling objects recoverable only via git fsck --unreachable, but the user has no indication that work was lost.

Steps to reproduce

  1. Run claude -w to start a worktree session
  2. Make changes, commit them to the worktree branch
  3. End the session (or let it end naturally)
  4. The worktree branch is deleted along with all commits
  5. git log --all shows no trace of the commits

Expected behavior

Before deleting a worktree branch, Claude Code should check for unmerged/unpushed commits:

git log --oneline master..HEAD

If there are unmerged commits, either:

  • Block the cleanup and warn the user
  • Auto-push the branch to a remote before deleting
  • At minimum, warn that commits will be lost

Actual behavior

Branch is silently deleted. Commits are only recoverable via git fsck --no-reflogs --unreachable | grep commit until git gc runs.

Impact

Lost 2 commits today (CSS fixes) that were made in a worktree session. The user explicitly asked "is everything merged?" and the AI confirmed — because git branch --no-merged doesn't show deleted branches. The commits were only found hours later via git fsck.

Workaround

Added a PreToolUse hook on ExitWorktree matcher that checks for unmerged commits and blocks exit:

{
  "hooks": [{ "command": "bash ~/.claude/hooks/worktree-exit-guard.sh", "type": "command" }],
  "matcher": "ExitWorktree"
}

This should be built into Claude Code's worktree lifecycle.

View original on GitHub ↗

This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗