Related Skills: Automate your Git workflows with specialized skills from Skilled. Explore Git automation workflows, branch management skills, and code review automation skills to streamline your development process.

Overview

Large changes, such as a module migration or a dependency upgrade across many packages, often split into tasks that do not touch the same files. Autohand Code can work on those tasks at the same time when each one runs in its own Git worktree. A worktree is a separate working directory with its own branch that shares the repository's history, so one task's edits never appear in another task's files.

When to use parallel worktrees

  • The work splits into tasks with little or no file overlap, such as one package or one service per task.
  • Each task can be checked on its own with tests, a build, or a linter.
  • You want to review, merge, or discard each task separately.

For a single focused change, one session in one worktree is simpler. For tasks that edit the same files, run them one after another on the same branch.

How it works

           your repository (main)
                    │
     ┌──────────────┼──────────────┐
     ▼              ▼              ▼
 ../app-auth    ../app-billing  ../app-search     one worktree and branch per task
 branch: auth   branch: billing branch: search
     │              │              │
 Autohand       Autohand        Autohand          one session or teammate per worktree
 session        session         session
     │              │              │
     └──────── review, test, merge ┘
                    ▼
                  main

Key capabilities

Capability How Autohand Code provides it
Isolated sessions autohand --worktree <name> creates a worktree and branch and runs the session inside it
Agent-managed worktrees The git_worktree_* tools let the agent add, list, sync, and remove worktrees when you ask it to
Parallel commands git_worktree_run_parallel runs one command, such as your test suite, in every worktree
Coordinated teams Agent teams split a task among teammates, with a shared task list in /tasks
Branch upkeep git_worktree_sync rebases or merges main into every worktree
Merging and cleanup git_merge, git_rebase, and git_worktree_cleanup finish the work and remove merged worktrees
Rollback /undo reverts the last agent file change; Git removes or reverts a whole task branch

Architecture

Autohand Code gives you three ways to put work in a worktree. Choose based on who starts the task: you, the agent, or an auto-mode loop.

Session worktrees

The --worktree [name] flag creates a worktree before the session starts and runs the whole session inside it. With a name, the branch uses that name. Without a name, Autohand generates one that starts with autohand-. The worktree is created next to your repository, at ../<repo>-<branch>, and stays in place after the session ends so you can review it.

# Interactive session on a new branch named migrate-auth
autohand --worktree migrate-auth

# Command mode in its own worktree
autohand --worktree migrate-billing -p "Convert src/billing to ESM imports and run npm test"

# Dedicated tmux session; implies --worktree
autohand --tmux

Agent worktree tools

Inside a session, the agent can manage worktrees with built-in tools. You ask in plain language, and the agent picks the tool. Tools that change Git state ask for approval unless your permission settings allow them.

Tool What it does
git_worktree_addAdds a worktree at path for a branch or commit (ref)
git_worktree_create_from_templateAdds a worktree from a template: feature, hotfix, release, review, or experiment, with an optional base_branch and setup commands
git_worktree_listLists worktrees
git_worktree_status_allReports changes, commits, and sync state for every worktree
git_worktree_run_parallelRuns a command in every worktree, with optional timeout (milliseconds, default 5 minutes) and max_concurrent (default: number of CPU cores)
git_worktree_syncBrings main into every worktree with a rebase or merge strategy; supports dry_run
git_worktree_removeRemoves one worktree; force removes it with local changes
git_worktree_cleanupRemoves stale worktrees and, with remove_merged, worktrees whose branches are merged; supports dry_run

Auto-mode worktrees

Auto-mode runs a task as a loop and uses a worktree by default. It creates a branch named autohand-automode-<timestamp>, commits checkpoints as it goes, and merges the branch back into the branch you started from when the task completes. Use --no-worktree to work on the current branch instead.

autohand --auto-mode "Migrate src/search to the new query client" \
  --max-iterations 30 --max-runtime 60 --max-cost 5 --checkpoint-interval 3

Disk space planning: Each worktree is a full checkout of your files, and templates such as feature run a package install. Plan for the size of your working directory, including node_modules or similar folders, times the number of worktrees.

Task definition

Parallel work goes well when every task has a clear boundary and a clear check. Write the plan down before you start any sessions.

Split the work

Group changes so each task owns a set of files. A package, a service, or a directory makes a good boundary. List shared files, such as a root configuration or a lockfile, and give them to one task only.

# ESM migration plan

| Task    | Branch          | Owns                    | Check                     |
|---------|-----------------|-------------------------|---------------------------|
| auth    | esm-auth        | packages/auth/**        | npm test -w auth          |
| billing | esm-billing     | packages/billing/**     | npm test -w billing       |
| search  | esm-search      | packages/search/**      | npm test -w search        |
| root    | esm-root        | package.json, tsconfig  | npm run build             |

Write one prompt per task

Each prompt should name the files the task owns, the files it must leave alone, and the check that proves it is done.

Convert packages/billing to ESM imports.
Edit only files under packages/billing.
Do not change package.json at the repository root or the lockfile.
Run npm test -w billing and report the result.
Commit the changes on this branch with a short message.

Order dependent tasks

When one task needs another's result, run them in order. Finish and merge the first task, then start the next worktree from the updated main, or ask the agent to run git_worktree_sync so existing worktrees pick up the change.

Define the check

Put the test, build, and lint commands in AGENTS.md so every session uses the same checks. The agent reads it when it starts in a worktree.

Parallel execution

Start one session per task, or let an agent team split the work for you.

Run separate sessions

Open a terminal for each task, or start command-mode runs in the background. Each run gets its own worktree and branch.

autohand --worktree esm-auth    -p "$(cat prompts/auth.txt)"    --yes --max-duration 1800 > logs/auth.txt 2>&1 &
autohand --worktree esm-billing -p "$(cat prompts/billing.txt)" --yes --max-duration 1800 > logs/billing.txt 2>&1 &
autohand --worktree esm-search  -p "$(cat prompts/search.txt)"  --yes --max-duration 1800 > logs/search.txt 2>&1 &
wait

--yes confirms actions without prompting. Pair it with a run budget such as --max-duration and a denyList in your config for commands the agent must never run, such as git push.

Use an agent team

An agent team has a lead agent that splits a task among teammates and tracks it in a shared task list. Start a team inside a session:

/team create esm-migration
# Describe the task; the lead assigns work to teammates
/tasks          # task list with status and owners
/team status    # teammates and progress
/team view      # live team activity view
/team shutdown  # stop all teammates

Ask the lead to give each teammate its own worktree when their tasks edit different parts of the repository.

Run a command in every worktree

After the tasks finish, ask the agent to check them all at once. The agent uses git_worktree_run_parallel and reports the result for each branch.

Run npm test in every worktree, at most 4 at a time, with a 10 minute timeout.
List the branches that failed and the first error for each.

Monitor progress

# Active Autohand agents on this machine
autohand agents          # live dashboard
autohand agents --once   # one snapshot, then exit

# Git view of every worktree
git worktree list

Inside a session, ask "Show the status of all worktrees" and the agent runs git_worktree_status_all.

Conflict resolution

Tasks that own separate files rarely conflict. When they do, find the conflict early and resolve it on the task branch before it reaches main.

Keep branches current

Ask the agent to preview a sync first, then apply it:

Preview syncing main into all worktrees with the rebase strategy.
If the preview looks clean, run the sync.

Detect conflicts before merging

A trial merge shows conflicts without creating a commit. Run it on main, then abort it:

git switch main
git merge --no-commit --no-ff esm-billing
git diff --name-only --diff-filter=U   # conflicted files, if any
git merge --abort

Prevention strategies

  • Give shared files, such as the lockfile, to one task only.
  • Keep tasks small so branches live for a short time.
  • Sync main into open worktrees after each merge.

Resolve conflicts with the agent

Start a session in the task's worktree and ask the agent to rebase onto main. The agent uses git_rebase, edits the conflicted files, and continues with git_rebase_continue. If the result is wrong, it can stop with git_rebase_abort.

cd ../app-esm-billing
autohand -p "Rebase this branch onto main. Resolve conflicts by keeping both changes where possible. Run npm test -w billing. If tests fail, abort the rebase and explain why."

Merging to main

Review each task before it reaches main. Merge directly for small, well-tested changes, or open a pull request when others need to review.

Merge strategies

Strategy git_merge option Use it when
Merge commitno_ff: trueYou want each task to appear as one merge in history
Squashsquash: trueYou want one commit per task on main
Fast-forwarddefaultThe branch is already up to date with main
Rebase firstgit_rebase, then mergeYou want a linear history

Direct merge

Switch to main. For each branch esm-auth, esm-billing, esm-search:
merge it with no fast-forward, run npm run build, and stop at the first failure.
Report which branches were merged.

Pull request mode

Push each branch and open a pull request with the GitHub CLI. Keep the push step in your own script if your denyList blocks git push for the agent.

for b in esm-auth esm-billing esm-search; do
  git push -u origin "$b"
  gh pr create --head "$b" --base main --title "ESM migration: ${b#esm-}" --fill
done

Commit message generation

Ask the agent to commit when a task is done, or start the session with -c (--auto-commit). Auto-commit runs lint and tests first, then writes a commit message from the changes.

Push and cleanup

After merging, remove the worktrees and their branches. Preview first:

Preview a cleanup of merged and stale worktrees, then run it.

Or clean up with Git directly:

git worktree remove ../app-esm-billing
git branch -d esm-billing
git worktree prune

Safety and guardrails

Parallel runs multiply both progress and mistakes. Set limits before you start them.

Protected paths and commands

Add a denyList to your Autohand config (~/.autohand/config.json, or the file passed with --config). Entries use the tool:pattern form and apply to every run, including runs started with --yes.

{
  "permissions": {
    "denyList": [
      "run_command:git push*",
      "run_command:rm -rf *",
      "write_file:.github/*",
      "write_file:migrations/*"
    ]
  }
}

Change limits

Limit each run with a budget and a tool list:

autohand --worktree esm-search -p "$(cat prompts/search.txt)" \
  --yes \
  --allowed-tools "read_file,write_file,apply_patch,find_grep,list_tree,git_status,git_diff,git_add,git_commit,run_command" \
  --max-requests 60 --max-duration 1800

When a budget is reached, the run stops and command mode exits with status 1.

Approval gates

Without --yes, Autohand asks before tools that change Git state, including git_worktree_add, git_worktree_remove, git_worktree_sync, git_worktree_cleanup, git_worktree_run_parallel, git_merge, git_rebase, git_reset, and git_commit. Keep merges to main interactive, or run them in your own script after review.

Rollback procedures

What to undo How
The agent's last file change in a session/undo
A task that is not mergedgit worktree remove --force ../app-esm-search, then git branch -D esm-search
A merged taskgit revert -m 1 <merge-commit> on main
A merge in progressgit merge --abort, or ask the agent to run git_merge_abort
A rebase in progressgit rebase --abort, or git_rebase_abort

Observability

Track parallel work through agent activity, Git state, run output, and hooks.

Agent activity

autohand agents opens a dashboard of active Autohand agents on the machine. autohand agents --once prints one snapshot for scripts. In a team, /team status and /tasks show each teammate and task.

Logging

For command-mode runs, capture the event stream per task:

autohand --worktree esm-auth -p "$(cat prompts/auth.txt)" --yes \
  --output-format stream-json > logs/esm-auth.jsonl

Each line is one JSON event, such as tool_start, tool_end, file_modified, result, or error. Use autohand sessions to list saved sessions and autohand resume <id> to reopen one.

Alerts

Hooks run a shell command at points in the agent lifecycle. Useful events for parallel work include session-end, subagent-stop, task-completed, automode:complete, and automode:error.

{
  "hooks": {
    "enabled": true,
    "hooks": [
      {
        "event": "session-end",
        "command": "echo \"$(date -u +%FT%TZ) $HOOK_WORKSPACE $HOOK_SESSION_END_REASON\" >> ~/autohand-sessions.log",
        "description": "Record when each worktree session ends",
        "async": true
      }
    ]
  }
}

Advanced patterns

Monorepo support

Give each package its own worktree and scope the prompt and the check to that package. See monorepo workflows for workspace commands and shared file rules.

Review a pull request in its own worktree

Ask the agent to check out a pull request without touching your current branch. It uses git_worktree_create_for_pr, which fetches the pull request from origin by default.

Create a worktree for PR 482 and review it for bugs and missing tests.

Worktree templates

git_worktree_create_from_template places worktrees in a consistent layout next to the repository:

TemplatePathSetup
feature../<repo>-feature-<branch>Package install
hotfix../<repo>-hotfix-<branch>Package install
release../<repo>-release-<branch>Package install
review../<repo>-review-<branch>None
experiment../<repo>-experiment-<timestamp>None

Resume and branch sessions

If a task stops early, reopen its session with autohand resume <id> and continue. To try a different approach without changing the original session history, use autohand --fork <id>.

CI/CD integration

CI runners already give each job its own checkout, so each parallel job can work on its own branch without worktrees.

CI runners have no stored Autohand sign-in, so these examples run Autohand with --bare and set AUTOHAND_PROVIDER, AUTOHAND_API_KEY, and AUTOHAND_AI_API_KEY. Without --bare, the CLI waits for a browser sign-in and the job hangs. See Authenticate in CI and containers.

GitHub Actions

name: ESM migration

on:
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write

jobs:
  migrate:
    runs-on: ubuntu-latest
    timeout-minutes: 40
    strategy:
      fail-fast: false
      max-parallel: 3
      matrix:
        package: [auth, billing, search]
    steps:
      - uses: actions/checkout@v4

      - name: Install Autohand Code
        run: |
          mkdir -p "$HOME/.local/bin"
          curl -fsSL https://autohand.ai/install.sh | AUTOHAND_INSTALL_DIR="$HOME/.local/bin" bash
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      - name: Migrate package
        env:
          AUTOHAND_PROVIDER: autohandai
          AUTOHAND_API_KEY: ${{ secrets.AUTOHAND_API_KEY }}
          AUTOHAND_AI_API_KEY: ${{ secrets.AUTOHAND_API_KEY }}
          PACKAGE: ${{ matrix.package }}
        run: |
          git checkout -b "esm-$PACKAGE"
          autohand --bare -p "Convert packages/$PACKAGE to ESM imports. Edit only files under packages/$PACKAGE. Run npm test -w $PACKAGE and report the result." \
            --yes --max-duration 1800 --json local > result.json

      - name: Open pull request
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PACKAGE: ${{ matrix.package }}
        run: |
          git diff --quiet && exit 0
          git config user.name "Autohand Bot"
          git config user.email "bot@autohand.ai"
          git add -A && git commit -m "Convert $PACKAGE to ESM"
          git push -u origin "esm-$PACKAGE"
          jq -r '.content' result.json > body.md
          gh pr create --head "esm-$PACKAGE" --base main --title "ESM migration: $PACKAGE" --body-file body.md

GitLab CI

migrate:
  image: node:20
  parallel:
    matrix:
      - PACKAGE: [auth, billing, search]
  before_script:
    - mkdir -p "$HOME/.local/bin"
    - curl -fsSL https://autohand.ai/install.sh | AUTOHAND_INSTALL_DIR="$HOME/.local/bin" bash
    - export PATH="$HOME/.local/bin:$PATH"
  script:
    - git checkout -b "esm-$PACKAGE"
    - autohand --bare -p "Convert packages/$PACKAGE to ESM imports. Edit only files under packages/$PACKAGE. Run npm test -w $PACKAGE." --yes --max-duration 1800
  variables:
    AUTOHAND_PROVIDER: autohandai
    AUTOHAND_API_KEY: $AUTOHAND_API_KEY
    AUTOHAND_AI_API_KEY: $AUTOHAND_API_KEY

Troubleshooting

Common issues

Issue Cause Solution
--worktree requires a git repository The command ran outside a Git repository Run it from inside the repository
Failed to create git worktree The branch is already checked out in another worktree, or the disk is full Pick a new branch name, or remove the old worktree with git worktree remove
Parallel command times out The default timeout is 5 minutes per worktree Ask for a longer timeout, for example 20 minutes
Machine slows down Too many sessions or parallel commands at once Run fewer sessions, or ask for a lower max_concurrent
Merge conflicts on shared files Two tasks edited the same file Give shared files to one task, and sync main into worktrees after each merge

Debug mode

autohand --debug --worktree esm-auth -p "$(cat prompts/auth.txt)"

Recovery procedures

# See every worktree and its branch
git worktree list

# Remove worktree records whose folders were deleted
git worktree prune

# Reopen the session that was working on a task
autohand sessions
autohand resume <session-id>

Command reference

CLI options

Option or commandDescription
--worktree [name]Run the session in a new worktree and branch
--tmuxLaunch in a dedicated tmux session; implies --worktree
--auto-mode [prompt]Run an autonomous loop, in a worktree by default
--no-worktreeRun auto-mode on the current branch
--checkpoint-interval <n>Auto-mode commits every n iterations
-c, --auto-commitCommit after tasks complete, after lint and tests
--max-requests, --max-tokens, --max-durationStop a run at a budget
autohand agents [--once]Show active agents
autohand sessions, autohand resume, --forkList, reopen, or branch sessions

Slash commands

CommandDescription
/team create <name>Create an agent team
/team status, /team view, /team shutdownCheck, watch, or stop the team
/tasksShow the team task list with status and owners
/undoRevert the last agent file change and conversation turn

Agent Git tools

Worktrees: git_worktree_add, git_worktree_create_from_template, git_worktree_create_for_pr, git_worktree_list, git_worktree_status_all, git_worktree_run_parallel, git_worktree_sync, git_worktree_remove, git_worktree_cleanup.

Branches and history: git_branch, git_switch, git_merge, git_merge_abort, git_rebase, git_rebase_continue, git_rebase_abort, git_rebase_skip, git_cherry_pick, git_stash, git_stash_pop, git_reset, git_commit, auto_commit.