Claude Code's context window is a liability. The longer a session runs, the more you're paying to re-read your own conversation history — and the more likely the model drifts on earlier context. Here's the workflow I landed on to fix it: one task, one worktree, one session, one commit.
The Problem
When you use Claude Code on a long task, context accumulates fast:
- Earlier decisions get buried
- Token costs climb
-
/clearwipes everything, including useful state - Switching between tasks in the same session bleeds context
Most people either let sessions balloon or /clear and lose everything. There's a better path.
The Insight
Git commit messages are free, durable, searchable context. A well-written commit body is a session summary that survives /clear, costs nothing to store, and is already part of your workflow. The trick is treating them as first-class context artifacts, not afterthoughts.
The Workflow
1. One Worktree Per Task
git worktree add ../task-foo -b task/foo
Each task gets its own branch and working directory. No context bleeding between tasks. When you open Claude Code, you open it in that worktree.
2. Work in a Focused Session
Keep the session scoped to the task. Don't mix concerns.
3. Write a Rich Commit Message
This is the key step. Use the commit body as your session summary:
feat: add user auth flow
what: JWT-based auth with refresh token rotation
why: existing session cookie approach didn't work cross-subdomain
tried: httpOnly cookie sharing — blocked by Safari ITP
next: wire up logout endpoint (separate task)
The tried and next fields are the most valuable — they capture reasoning that doesn't live in the code. You don't write this manually — at the end of a session, just tell Claude Code to commit, and it follows the format automatically (see CLAUDE.md below).
4. Clear and Close
/clear
Or just close the session. The context is committed.
5. Resume Any Time
Just open Claude Code in the worktree. Because of the Session Start rule in CLAUDE.md, it automatically reads git log and orients itself before asking any questions. No manual context passing needed.
Fixing the Gaps
What about exploration sessions that produce no commits?
Commit a NOTES.md or SCRATCH.md anyway. One file, one commit, body = session summary. The commit is the log entry, not just the code change.
What about nuance that's hard to fit in a commit?
Write more. Commit bodies have no length limit. A 20-line body that captures a tricky decision is worth more than 5 lines of clean code with no context.
What about multi-session tasks?
Each worktree is on its own branch, so there's no conflict between tasks. For context across sessions on the same task, just use git log — each session's commit body is the running log. If you want a freeform scratchpad, keep a CONTEXT.md in the worktree but add it to .gitignore so it never enters git. It lives in the directory, stays out of the PR, and disappears when you remove the worktree.
What Goes in CLAUDE.md
The commit messages handle task-level context. Your CLAUDE.md handles project-level context — conventions, architecture decisions, things every session needs to know. That file is loaded automatically and costs nothing per session. Keep it sharp.
Critically, put the commit format here so Claude Code writes it correctly every time without being told:
## Session Start
At the start of each session, run `git log -5 --format="%s%n%b"` to orient yourself on recent work before asking any questions.
## Commit Format
Always write commit messages in this format:
type: short summary
what: what changed
why: motivation
tried: dead ends / rejected approaches
next: follow-up tasks (if any)
With these two rules, Claude Code self-orients at the start and self-documents at the end — no manual context passing required.
The Full Loop
git worktree add ../task-name -b task/name
↓
Open Claude Code in that worktree
→ Claude reads git log, orients itself automatically
↓
Work on the task
↓
Tell Claude Code: "commit"
→ Claude writes the rich commit message, you review and confirm
↓
/clear (or close the session)
↓
git worktree remove ../task-name (when merged)
Why This Works
- Token efficient — fresh sessions stay small
-
Durable — context survives
/clearand machine restarts -
Searchable —
git log --grep="auth"finds past decisions - Discipline forcing — writing the commit makes you articulate what you actually did
- Zero overhead tooling — it's just git
The mental shift is treating the commit message as a briefing document, not a changelog entry. You're writing for your next session's Claude Code, not for git blame.
Have a different approach to managing Claude Code context? I'd love to hear it.
Top comments (0)