Skip to content

Feature: Git Worktree Isolation for Parallel CLI Sessions (hermes -w) #652

@teknium1

Description

@teknium1

Overview

When running multiple hermes-agent CLI instances concurrently on the same codebase (e.g., 10 agents fixing different issues, reviewing PRs, implementing features), they all collide in the project directory — editing each other's files, building up uncommitted changes from other tasks, getting pulled into wrong branches, and corrupting each other's git state.

Every major code agent has addressed this with git worktrees:

  • Claude Code: claude --worktree / claude -w creates .claude/worktrees/<name>/
  • Codex App: Auto-creates worktrees per task in $CODEX_HOME/worktrees/
  • Cline CLI 2.0: cline --cwd ~/worktree-a -y "task" for parallel execution

Hermes needs a --worktree / -w CLI flag that auto-creates an isolated git worktree for the session, so multiple agents can work on the same repo concurrently without interference.

Related issues: #380 (batch migration skill), #344 (multi-agent architecture). This provides the foundational infrastructure those features need.


How Git Worktrees Solve This

Git worktrees create linked working directories sharing the same .git object store but with independent HEAD, index, and working tree:

~/.hermes/hermes-agent/                    ← the "real" repo (main branch)
~/.hermes/hermes-agent/.worktrees/
  session-abc123/                          ← agent 1 works here (branch hermes/abc123)
  session-def456/                          ← agent 2 works here (branch hermes/def456)
  session-ghi789/                          ← agent 3 works here (branch hermes/ghi789)

Each agent sees the full codebase, can edit any file, run tests, commit, push, create PRs — completely independently. Zero collisions. Worktrees are lightweight (instant creation, shared objects) unlike full clones.


Implementation Plan

CLI Changes (cli.py)

Add --worktree / -w flag to the hermes CLI:

# Launch in an isolated worktree
hermes -w "Fix issue #628"
hermes --worktree

# Normal launch (no isolation, current behavior)
hermes "Fix issue #628"

On startup (when -w is passed):

  1. Detect git repo root: git rev-parse --show-toplevel
  2. Create worktree dir: <repo>/.worktrees/ (add to .gitignore if needed)
  3. Generate session-based name: hermes-<short-uuid>
  4. Create worktree: git worktree add .worktrees/<name> -b hermes/<name> HEAD
  5. Set TERMINAL_CWD to the worktree path
  6. Copy files listed in .worktreeinclude (e.g., .env, .venv/) if the file exists
  7. Inject a system prompt note so the agent knows it's in a worktree and should commit+push

On exit:

  1. Check for uncommitted changes in the worktree
  2. If clean: remove worktree (git worktree remove) and delete branch
  3. If dirty: warn user, keep worktree for manual recovery
  4. Use atexit handler for cleanup

Config Support (config.yaml)

# In ~/.hermes/config.yaml
worktree: false     # default: no auto-worktree
# worktree: true    # always create a worktree when in a git repo

When worktree: true is set in config, every CLI session in a git repo auto-creates a worktree (equivalent to always passing -w). The -w flag overrides config for a single session.

.worktreeinclude File

Optional file in repo root listing gitignored files/dirs to copy into new worktrees:

# .worktreeinclude
.env
.venv/
node_modules/
config.local.yaml

Agent Awareness

When running in a worktree, inject a system prompt note:

[System note: You are working in an isolated git worktree at <path>.
Your branch is hermes/<name>. Changes here do not affect the main
working tree. Remember to commit and push your changes, and create
a PR if appropriate.]

What This Does NOT Include (Future Work)

  • No worktree tool — agents don't need to create worktrees themselves; the CLI handles it
  • No delegate_task changes — each CLI process is its own OS process, so TERMINAL_CWD is already per-process
  • No gateway integration — gateway sessions use different isolation (Docker backends, etc.)
  • No per-agent CWD refactor — not needed since each hermes CLI is a separate process

These can be added later if needed (see #380, #344).


Pros & Cons

Pros

  • Enables true parallel work — 10 agents, 10 worktrees, zero collisions
  • Lightweight — worktrees share git objects, instant creation
  • Git-native — standard git infrastructure, no custom isolation layer
  • Simple implementation — ~100 lines in cli.py, no architectural changes
  • Matches industry standard — Claude Code, Codex App, Cline all use this pattern
  • Opt-in — doesn't change default behavior; -w flag or config to enable

Cons / Risks

  • Dependency installation — each worktree may need its own .venv/node_modules (mitigated by .worktreeinclude symlink/copy)
  • Branch cleanup — failed sessions may leave orphan branches (mitigated by atexit cleanup)
  • Mental model — user must understand changes are on a separate branch (mitigated by agent system prompt note)
  • Disk usage — each worktree is a full copy of tracked files (but shares git objects)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions