Session state should persist across git worktrees

Status Fixed / completed
Maintainer reply None cached
Activity 6 comments · opened Dec 30, 2025 · closed Aug 17, 2026

When using git worktrees, Claude Code stores session state (.claude/) in the worktree folder rather than the main repository. This causes conversation history to be lost when the worktree is deleted after merging.

Current behavior

  • Create worktree for feature branch
  • Work with Claude Code (session stored in worktree's .claude/)
  • Merge branch to main
  • Delete worktree → session history lost

Expected behavior

Session state should be associated with the git repository identity, not the filesystem path. Options:

  1. Store sessions in the main repo's .git/ directory (shared by worktrees)
  2. Associate sessions by repo remote URL or other repo identifier
  3. Allow session migration when worktree is removed

Use case

Worktrees are designed to be disposable - you create them for a branch, do work, merge, and delete. Tying session state to the worktree folder works against this workflow pattern.

View original on GitHub ↗

5 Comments

github-actions[bot] · 8 months ago

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/14036
  2. https://github.com/anthropics/claude-code/issues/4843

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

davidrimshnick · 8 months ago

I don’t think this is a duplicate

h4mn · 7 months ago

My Specific Use Case

Typical Scenario (Context Loss When Creating Worktree)

  1. Discussion on main/dev branch
  • I'm on the main (or dev) branch
  • I have an active Claude session with rich architecture discussion
  • Conversation includes: technical decisions, considered trade-offs, next steps
  • Accumulated context: 50-100 messages with important details
  1. Decision to create worktree
  • The conversation reached a point where it makes sense to implement in a separate branch
  • Example: "Let's implement this using a worktree to avoid polluting main"
  • Exit Claude: /exit or Ctrl+D
  1. Worktree creation

git worktree add ../skybridge-worktrees-feature-x -b feature/x
cd ../skybridge-worktrees-feature-x

  1. Starting Claude in worktree

claude

  1. PROBLEM: Context lost
  • Session starts from ZERO
  • All previous discussion history is gone
  • I have to:
  • Re-explain the architecture context discussed
  • Remember decisions made
  • Recap trade-offs already analyzed
  • Redo reasoning that was already consolidated

Why This Is Problematic

Natural development workflow:

  • Discussion → Decision → Implementation
  • The PRE-IMPLEMENTATION conversation is critical to understand WHAT and WHY to implement
  • The worktree is just a physical continuation (new directory), but conceptually it's the SAME task

What I lose:

  • 50-100 messages of architecture context
  • Decisions made with detailed justifications
  • Trade-off analysis already discussed
  • References to specific files mentioned in conversation
  • "Short-term memory" of what was being discussed

Cost of loss:

  • 10-20 minutes to re-explain context
  • Risk of forgetting important details discussed
  • Conversation becomes fragmented (part in main, part in worktree)
  • Loss of valuable insights from original discussion

Current Workaround (Inefficient)

I have to take screenshots or copy-paste parts of the conversation, but:

  • I lose the ability to interact with the original history
  • I can't ask "what did you say about X?"
  • The AI's "memory" of the context is lost

Expected Solution

Continue parent branch conversation in child worktree:
cd ../skybridge-worktrees-feature-x
claude --resume-from-parent # Or something similar

Or automatically detect and offer:
> claude
Detected you're in a worktree.
Want to continue the parent branch session? [Y/n]
Last session: 337c2b22-... (2 hours ago, 87 messages)

pomfrida · 4 months ago

This is a real pain point for me. I use worktrees heavily in my daily workflow — spin up a worktree for a feature branch, work with Claude Code, merge, delete the worktree. Losing all session history every time is really frustrating. I'm now saving all my worktrees and that's a lot of clutter, and it's hard to remember where the history is located and honestly I don't think that's how worktrees are supposed to be used.. 😅

I see that project configs and auto memory are now shared across worktrees (great!), but the session transcripts themselves are still tied to the worktree path. That's the critical missing piece. When the worktree goes away, so does all the conversation context — architecture decisions, trade-off discussions, everything.

Would love to see session storage resolved to the main repo's .git/ directory (or keyed by repo identity) so sessions survive worktree deletion. This would make the worktree workflow fully first-class.

pomfrida · 4 months ago

Workaround: Preserve sessions when removing git worktrees

Claude Code stores session history in ~/.claude/projects/ keyed by the working directory path. Each worktree gets its own project key, so when you remove a worktree, those sessions disappear from /resume in the main repo.

Add this function to your ~/.zshrc or ~/.bashrc — it copies sessions from the worktree's project dir to the main repo's project dir before removing the worktree:

git-wt-remove() {
  local wt="$1"
  local force="$2"
  if [[ -z "$wt" ]]; then
    echo "Usage: git-wt-remove <worktree-path> [--force]"
    return 1
  fi

  local wt_name=$(basename "$wt")
  local main_repo=$(git -C "$wt" rev-parse --path-format=absolute --git-common-dir | sed 's|/.git$||')
  local main_key=$(echo "$main_repo" | sed 's|[/.]|-|g; s|^-||')
  local src=$(echo "$HOME/.claude/projects/"*"$wt_name")
  local dst=$(echo "$HOME/.claude/projects/$main_key")

  if [[ -d "$src" && -d "$dst" ]]; then
    echo "Copying Claude sessions from worktree to main repo..."
    cp -n "$src"/*.jsonl "$dst/" 2>/dev/null
    for d in "$src"/*/; do
      [[ -d "$d" ]] && cp -rn "$d" "$dst/" 2>/dev/null
    done
    echo "Done — sessions preserved. They should now appear in /resume from the main repo."
  else
    echo "No worktree sessions found — nothing to copy."
  fi

  git worktree remove ${force:+--force} "$wt"
}

Usage:

git-wt-remove /path/to/worktree          # normal remove
git-wt-remove /path/to/worktree --force   # if worktree has untracked/modified files

After removing, the worktree sessions show up in /resume from the main repo. Verified on macOS.

Automatic version: WorktreeRemove hook

You can also automate this with a WorktreeRemove hook so sessions are preserved automatically when Claude Code cleans up worktrees (e.g., after --worktree sessions).

1. Create ~/.claude/scripts/preserve-worktree-sessions.sh:

#!/bin/bash
input=$(cat)
wt_path=$(echo "$input" | jq -r '.worktree_path // .tool_input.worktree_path // .cwd // empty' 2>/dev/null)

if [[ -z "$wt_path" ]]; then
  exit 0
fi

wt_name=$(basename "$wt_path")
main_repo=$(git -C "$wt_path" rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed 's|/.git$||')

if [[ -z "$main_repo" ]]; then
  exit 0
fi

main_key=$(echo "$main_repo" | sed 's|[/.]|-|g; s|^-||')
src=$(echo "$HOME/.claude/projects/"*"$wt_name")
dst="$HOME/.claude/projects/$main_key"

if [[ -d "$src" && -d "$dst" ]]; then
  cp -n "$src"/*.jsonl "$dst/" 2>/dev/null
  for d in "$src"/*/; do
    [[ -d "$d" ]] && cp -rn "$d" "$dst/" 2>/dev/null
  done
fi

Then chmod +x ~/.claude/scripts/preserve-worktree-sessions.sh.

2. Add to ~/.claude/settings.json:

{
  "hooks": {
    "WorktreeRemove": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/preserve-worktree-sessions.sh",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Note: the hook fires on clean exit (/quit), not on Ctrl+C. The shell function from above still covers manual removal.

Showing cached comments. Read the full discussion on GitHub ↗