Guides
Git Flow Automation
Execute hundreds of tasks in parallel using Git worktrees. Orchestrate agents across isolated branches with automatic conflict resolution and safe merging to main.
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
When you need to apply changes across hundreds of files, sequential execution becomes a bottleneck. Autohand solves this by creating isolated Git worktrees for each task, allowing multiple agents to work simultaneously without stepping on each other.
The problem
Consider migrating a codebase from CommonJS to ESM. With 500 files to update, sequential processing would take hours. Each file needs analysis, transformation, and testing. Traditional approaches fail because:
- File locks prevent concurrent modifications
- Partial failures leave the codebase in an inconsistent state
- No isolation means one bad change affects everything
- Rollback requires reverting the entire batch
The solution
Git worktrees provide the foundation for true parallelism. Each worktree is a separate working directory with its own branch, sharing the same Git history. Autohand orchestrates agents across these worktrees:
┌─────────────────────────────────────────────────────────────────┐
│ Autohand Orchestrator │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Agent 1 │ │ Agent 2 │ │ Agent 3 │ ... │ Agent N │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼─────────────┼─────────────┼─────────────────┼──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│Worktree │ │Worktree │ │Worktree │ │Worktree │
│ 001 │ │ 002 │ │ 003 │ ... │ N │
│ branch: │ │ branch: │ │ branch: │ │ branch: │
│ task-1 │ │ task-2 │ │ task-3 │ │ task-n │
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
│ │ │ │
└─────────────┴──────┬──────┴─────────────────┘
▼
┌────────────────┐
│ Main Branch │
│ (merge) │
└────────────────┘
Key capabilities
| Capability | Description |
|---|---|
| Parallel execution | Run 100+ agents concurrently, each in isolated worktrees |
| Task dependencies | Define execution order when tasks depend on each other |
| Automatic branching | Each task gets its own feature branch automatically |
| Per-task testing | Run tests in each worktree before merge |
| Conflict detection | Identify overlapping changes before merge attempt |
| AI-assisted resolution | Automatically resolve conflicts using semantic understanding |
| Selective rollback | Discard individual tasks without affecting others |
| Resume from failure | Continue execution after fixing failed tasks |
Architecture
Understanding the orchestration model helps you configure and troubleshoot parallel execution effectively.
Orchestrator components
The parallel execution system consists of four main components:
- Task Queue: Prioritized queue of pending tasks with dependency resolution
- Agent Pool: Pool of concurrent agents bounded by
max_concurrent - Worktree Manager: Creates, tracks, and cleans up Git worktrees
- Merge Coordinator: Handles conflict detection, resolution, and final merge
Task lifecycle
Each task progresses through defined states:
PENDING ──▶ QUEUED ──▶ RUNNING ──▶ TESTING ──▶ COMPLETED
│ │ │ │ │
│ │ ▼ ▼ ▼
│ │ FAILED FAILED MERGED
│ │ │ │
│ ▼ ▼ ▼
└───────── BLOCKED (dependency not met)
CANCELLED (user cancelled)
SKIPPED (condition not met)
Resource management
The orchestrator manages system resources to prevent overload:
# .autohand/config.yaml
orchestrator:
# Maximum concurrent agents
max_concurrent: 50
# Resource limits per agent
agent:
memory_limit: 2GB
cpu_limit: 2
# API rate limiting
api:
requests_per_minute: 100
retry_on_rate_limit: true
retry_delay: 60s
# Disk management
disk:
min_free_space: 10GB
cleanup_threshold: 5GB
worktree_size_limit: 1GB
Disk space planning: Each worktree is a full copy of your working directory (excluding .git). For a 500MB codebase with 100 concurrent tasks, plan for 50GB+ of disk space.
Task definition
Tasks are defined in YAML files with rich configuration options for controlling execution behavior.
Basic structure
# tasks.yaml
version: "1.0"
name: ESM Migration
description: Migrate CommonJS modules to ES Modules
defaults:
model: claude-sonnet
timeout: 5m
retries: 2
tasks:
- id: migrate-utils
description: Migrate utility modules
files:
- src/utils/**/*.js
prompt: |
Convert this CommonJS module to ES Module syntax.
Replace require() with import statements.
Replace module.exports with export statements.
Ensure named exports are used where appropriate.
Task options
| Option | Type | Description |
|---|---|---|
id |
string | Unique identifier for the task |
description |
string | Human-readable description for logs and PRs |
files |
array | Glob patterns for files to process |
prompt |
string | Instructions for the AI agent |
depends_on |
array | Task IDs that must complete first |
priority |
number | Execution priority (higher runs first) |
condition |
string | Shell command that must exit 0 to run task |
timeout |
duration | Maximum execution time per task |
retries |
number | Retry count on failure |
test |
object | Test configuration for validation |
Task dependencies
When tasks must execute in a specific order, use depends_on:
tasks:
- id: update-types
description: Update TypeScript type definitions
files: ["src/types/**/*.ts"]
prompt: Update type definitions for new API schema
priority: 100 # Run first
- id: update-api-client
description: Update API client implementation
files: ["src/api/**/*.ts"]
prompt: Update API client to match new types
depends_on: [update-types] # Wait for types
- id: update-components
description: Update React components
files: ["src/components/**/*.tsx"]
prompt: Update components to use new API client
depends_on: [update-api-client] # Wait for API client
- id: update-tests
description: Update test files
files: ["src/**/*.test.ts"]
prompt: Update tests for new implementations
depends_on: [update-types, update-api-client, update-components]
Conditional execution
Skip tasks based on conditions:
tasks:
- id: update-legacy-module
description: Update legacy authentication
files: ["src/legacy/**/*.js"]
prompt: Migrate legacy auth to new system
condition: "test -d src/legacy" # Only if directory exists
- id: generate-openapi
description: Regenerate OpenAPI client
files: ["src/api/generated/**/*"]
prompt: Regenerate API client from schema
condition: "git diff --name-only HEAD~1 | grep -q openapi.yaml"
Per-task testing
Validate changes before marking tasks complete:
tasks:
- id: refactor-auth
files: ["src/auth/**/*.ts"]
prompt: Refactor authentication module
test:
# Commands to run in the worktree
commands:
- npm run typecheck
- npm test -- --testPathPattern=auth
# Test behavior
required: true # Fail task if tests fail
timeout: 5m # Test timeout
retry_on_flaky: true # Retry flaky tests once
# Coverage requirements
coverage:
enabled: true
min_percent: 80
fail_on_decrease: true
Parallel execution
Once tasks are defined, execute them with the orchestrator.
Running tasks
# Execute all tasks from file
autohand parallel run --tasks tasks.yaml
# Limit concurrency
autohand parallel run --tasks tasks.yaml --concurrency 20
# Run specific tasks only
autohand parallel run --tasks tasks.yaml --only update-types,update-api
# Exclude specific tasks
autohand parallel run --tasks tasks.yaml --exclude update-tests
# Dry run (preview without executing)
autohand parallel run --tasks tasks.yaml --dry-run
Execution modes
# .autohand/config.yaml
execution:
# How to handle task failures
on_failure: continue # continue, pause, or abort
# Whether to run tests automatically
auto_test: true
# Notification settings
notify:
on_complete: true
on_failure: true
channels:
- slack:#dev-automation
- email:[email protected]
Monitoring progress
# Real-time status dashboard
autohand parallel status --watch
# Output:
# ┌─────────────────────────────────────────────────────────────┐
# │ Parallel Execution: ESM Migration │
# ├─────────────────────────────────────────────────────────────┤
# │ Progress: ████████████████░░░░░░░░░░░░░░░░ 47/100 (47%) │
# │ Running: 20 │ Completed: 45 │ Failed: 2 │ Queued: 53 │
# ├─────────────────────────────────────────────────────────────┤
# │ Active Tasks: │
# │ migrate-utils-023 [████████░░] 80% src/utils/date.js │
# │ migrate-api-017 [██████░░░░] 60% src/api/users.ts │
# │ migrate-components-8 [████░░░░░░] 40% src/Button.tsx │
# │ ... │
# ├─────────────────────────────────────────────────────────────┤
# │ Failed Tasks: │
# │ migrate-legacy-auth [FAILED] TypeError in transformation│
# │ migrate-db-client [FAILED] Test assertion failed │
# ├─────────────────────────────────────────────────────────────┤
# │ Resources: CPU 45% │ Memory 12GB/32GB │ Disk 23GB free │
# │ API: 45 req/min (limit: 100) │ Est. remaining: 12 min │
# └─────────────────────────────────────────────────────────────┘
# View logs for specific task
autohand parallel logs migrate-utils-023
# Follow logs in real-time
autohand parallel logs migrate-utils-023 --follow
# Export execution report
autohand parallel report --format json --output report.json
Pause and resume
# Pause execution (finish running tasks, don't start new ones)
autohand parallel pause
# Resume execution
autohand parallel resume
# Cancel all running tasks
autohand parallel cancel --all
# Cancel specific task
autohand parallel cancel migrate-legacy-auth
# Retry failed tasks
autohand parallel retry --failed
# Retry specific task
autohand parallel retry migrate-legacy-auth
Conflict resolution
When multiple tasks modify overlapping code, conflicts arise during merge. Autohand provides detection, prevention, and resolution strategies.
Conflict detection
# Analyze potential conflicts before merge
autohand parallel conflicts --analyze
# Output:
# Conflict Analysis Report
# ========================
#
# High Risk (3 conflicts):
# ┌──────────────────────────────────────────────────────────────┐
# │ task-001 vs task-003 │
# │ File: src/api/users.ts │
# │ Lines: 45-67 (both tasks modify getUserById function) │
# │ Recommendation: Manual review required │
# ├──────────────────────────────────────────────────────────────┤
# │ task-002 vs task-005 │
# │ File: src/utils/helpers.ts │
# │ Lines: 12-15 (overlapping import statements) │
# │ Recommendation: Auto-resolvable (merge both imports) │
# ├──────────────────────────────────────────────────────────────┤
# │ task-007 vs task-012 │
# │ File: package.json │
# │ Lines: dependencies section │
# │ Recommendation: Auto-resolvable (merge dependencies) │
# └──────────────────────────────────────────────────────────────┘
#
# Medium Risk (5 conflicts):
# ...
#
# Total: 8 potential conflicts across 47 completed tasks
Prevention strategies
Reduce conflicts through task design:
# .autohand/config.yaml
conflicts:
prevention:
# Automatically split tasks that would conflict
auto_split: true
# Lock files during task execution
file_locking: true
# Merge order optimization
optimize_merge_order: true
# Protected paths (never auto-resolve)
protected_paths:
- package.json
- package-lock.json
- yarn.lock
- .env*
- "*.config.js"
Resolution strategies
# Automatic resolution using AI
autohand parallel resolve --auto
# Interactive resolution (shows diff, prompts for choice)
autohand parallel resolve --interactive
# Apply specific resolution strategy
autohand parallel resolve --strategy ours # Keep current branch
autohand parallel resolve --strategy theirs # Keep incoming branch
autohand parallel resolve --strategy union # Keep both (for additive changes)
AI-assisted resolution
For complex conflicts, the AI analyzes both changes and produces a merged result:
# .autohand/config.yaml
conflicts:
resolution:
strategy: ai_assisted # manual, auto, or ai_assisted
ai:
# Context to provide for resolution
include_file_history: true
include_task_prompts: true
# Confidence threshold for auto-apply
auto_apply_threshold: 0.9
# Require human review below threshold
require_review_below: 0.7
# Rules for specific file patterns
rules:
- pattern: "*.test.ts"
strategy: merge_both
- pattern: "package.json"
strategy: merge_dependencies
- pattern: "*.generated.*"
strategy: regenerate
- pattern: "*.lock"
strategy: regenerate
Merging to main
After tasks complete and conflicts are resolved, merge changes to the target branch.
Merge strategies
| Strategy | Use case | Commit history |
|---|---|---|
sequential |
When order matters or conflicts are complex | One merge commit per task |
batch |
Fast merge of non-conflicting changes | Single merge commit for all tasks |
squash |
Clean history with one commit per task | Squashed commits, linear history |
rebase |
Linear history without merge commits | Rebased commits on target |
pr |
Code review required | Creates pull requests |
Direct merge
# Merge all completed tasks to main
autohand parallel merge --to main
# Preview merge without applying
autohand parallel merge --to main --dry-run
# Merge with specific strategy
autohand parallel merge --to main --strategy squash
# Merge only specific tasks
autohand parallel merge --to main --tasks task-001,task-002,task-003
# Skip failed tasks and merge successful ones
autohand parallel merge --to main --skip-failed
Pull request mode
# Create individual PRs for each task
autohand parallel merge --strategy pr
# Create draft PRs
autohand parallel merge --strategy pr --draft
# Add labels and reviewers
autohand parallel merge --strategy pr \
--labels "automated,migration" \
--reviewers "@team/backend"
# Link to issues
autohand parallel merge --strategy pr --link-issues
# Create single PR for all tasks
autohand parallel merge --strategy pr --combine
Commit message generation
# .autohand/config.yaml
commit:
message:
# Template for individual task commits
task_template: |
{{type}}: {{description}}
Task: {{task_id}}
Files: {{file_count}} modified
{{#if breaking}}
BREAKING CHANGE: {{breaking_description}}
{{/if}}
Generated by Autohand
# Template for batch commits
batch_template: |
{{type}}: Complete {{task_count}} parallel tasks
Tasks completed:
{{#each tasks}}
- {{id}}: {{description}}
{{/each}}
Generated by Autohand
# Infer commit type from changes
infer_type: true
# Types: feat, fix, refactor, docs, test, chore
default_type: refactor
Push and cleanup
# Merge, push, and cleanup in one command
autohand parallel merge --to main --push --cleanup
# Push to specific remote
autohand parallel merge --to main --push --remote upstream
# Keep worktrees for inspection
autohand parallel merge --to main --push --no-cleanup
# Manual cleanup
autohand parallel cleanup --merged # Only merged tasks
autohand parallel cleanup --all # All worktrees
autohand parallel cleanup --older-than 7d # Stale worktrees
Safety and guardrails
Prevent unintended changes with configurable safety controls.
Protected paths
# .autohand/config.yaml
safety:
protected_paths:
# Never modify these files
readonly:
- .github/workflows/*
- .env*
- secrets/*
- "*.pem"
- "*.key"
# Require explicit approval
require_approval:
- package.json
- tsconfig.json
- "*.config.js"
- migrations/*
# Allow but flag for review
flag_for_review:
- src/core/*
- src/auth/*
Change limits
# .autohand/config.yaml
safety:
limits:
# Maximum changes per task
max_files_per_task: 50
max_lines_changed: 1000
max_files_deleted: 5
# Maximum total changes
max_total_files: 500
max_total_lines: 10000
# Abort if limits exceeded
on_limit_exceeded: abort # abort, warn, or ignore
Approval gates
# .autohand/config.yaml
safety:
approval:
# Require approval before merge
require_before_merge: true
# Approval methods
methods:
- slack_reaction # React with :white_check_mark:
- github_review # Approve in PR
- cli_confirm # Confirm in terminal
# Approvers
approvers:
- team:platform
- user:tech-lead
# Auto-approve low-risk changes
auto_approve:
enabled: true
conditions:
- "files_changed < 10"
- "no_protected_paths"
- "all_tests_pass"
- "no_conflicts"
Rollback procedures
# Rollback specific task (before merge)
autohand parallel rollback task-001
# Rollback all changes from a session
autohand parallel rollback --session abc123
# Rollback merged changes (creates revert commits)
autohand parallel rollback --merged --session abc123
# Rollback with PR for review
autohand parallel rollback --merged --pr
# View rollback history
autohand parallel rollback --list
Observability
Monitor execution with metrics, logs, and alerts.
Metrics
# View execution metrics
autohand parallel metrics
# Output:
# Session Metrics: abc123
# ──────────────────────────────────────────────────
# Duration: 45 minutes
# Tasks: 100 total, 95 completed, 5 failed
# Success rate: 95%
# Avg task duration: 2.3 minutes
#
# Resource Usage:
# Peak CPU: 78%
# Peak Memory: 24GB
# Disk used: 45GB
# API calls: 4,521
# API cost: $12.34
#
# Merge Stats:
# Conflicts: 12 detected, 10 auto-resolved
# Manual reviews: 2
# Lines changed: +4,521 / -2,103
Logging
# .autohand/config.yaml
logging:
level: info # debug, info, warn, error
# Log destinations
destinations:
- type: file
path: .autohand/logs/parallel.log
rotate: daily
retain: 7d
- type: stdout
format: pretty
- type: json
path: .autohand/logs/parallel.jsonl
# What to log
include:
- task_start
- task_complete
- task_failed
- conflict_detected
- merge_complete
- api_calls
Alerts
# .autohand/config.yaml
alerts:
channels:
slack:
webhook: ${SLACK_WEBHOOK_URL}
channel: "#dev-automation"
email:
to: ["[email protected]"]
from: "[email protected]"
triggers:
- event: task_failed
severity: warning
channels: [slack]
- event: execution_complete
channels: [slack, email]
- event: conflict_unresolved
severity: error
channels: [slack, email]
- event: approval_required
channels: [slack]
mention: ["@oncall"]
Advanced patterns
Monorepo support
Execute tasks across multiple packages in a monorepo:
# tasks.yaml
version: "1.0"
name: Monorepo Migration
# Define packages
packages:
- name: web
path: packages/web
test: npm test
- name: api
path: packages/api
test: npm test
- name: shared
path: packages/shared
test: npm test
tasks:
- id: update-shared-types
package: shared
files: ["src/**/*.ts"]
prompt: Update shared type definitions
- id: update-web-client
package: web
files: ["src/**/*.tsx"]
prompt: Update web client components
depends_on: [update-shared-types]
- id: update-api-handlers
package: api
files: ["src/**/*.ts"]
prompt: Update API handlers
depends_on: [update-shared-types]
Cross-repository execution
# cross-repo-tasks.yaml
version: "1.0"
name: Cross-Repository Migration
repositories:
- name: frontend
url: [email protected]:company/frontend.git
branch: main
- name: backend
url: [email protected]:company/backend.git
branch: main
- name: shared-libs
url: [email protected]:company/shared-libs.git
branch: main
tasks:
- id: update-api-schema
repository: backend
files: ["src/api/schema.ts"]
prompt: Update API schema with new fields
- id: regenerate-client
repository: frontend
files: ["src/api/generated/*"]
prompt: Regenerate API client from schema
depends_on: [update-api-schema]
- id: update-shared-types
repository: shared-libs
files: ["src/types/*"]
prompt: Update shared type definitions
depends_on: [update-api-schema]
Distributed execution
For very large task sets, distribute across multiple machines:
# .autohand/config.yaml
distributed:
enabled: true
# Coordinator settings
coordinator:
host: autohand-coordinator.internal
port: 8080
# Worker settings
workers:
- host: worker-1.internal
max_concurrent: 20
- host: worker-2.internal
max_concurrent: 20
- host: worker-3.internal
max_concurrent: 20
# Task distribution
distribution:
strategy: round_robin # round_robin, least_loaded, affinity
# Affinity rules (run related tasks on same worker)
affinity:
- pattern: "src/api/*"
worker: worker-1
- pattern: "src/web/*"
worker: worker-2
Incremental execution
Resume from checkpoints after failures:
# Save checkpoint periodically
autohand parallel run --tasks tasks.yaml --checkpoint-interval 5m
# Resume from last checkpoint
autohand parallel resume --from-checkpoint
# Resume from specific checkpoint
autohand parallel resume --checkpoint abc123-checkpoint-5
# List available checkpoints
autohand parallel checkpoints --list
CI/CD integration
GitHub Actions
# .github/workflows/parallel-migration.yml
name: Parallel Migration
on:
workflow_dispatch:
inputs:
tasks_file:
description: 'Tasks YAML file'
required: true
default: 'tasks.yaml'
concurrency:
description: 'Concurrent tasks'
required: false
default: '20'
dry_run:
description: 'Dry run only'
type: boolean
default: false
jobs:
execute:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Autohand
run: npm i -g autohand-cli
- name: Run parallel tasks
env:
AUTOHAND_API_KEY: ${{ secrets.AUTOHAND_API_KEY }}
run: |
autohand parallel run \
--tasks ${{ inputs.tasks_file }} \
--concurrency ${{ inputs.concurrency }} \
${{ inputs.dry_run && '--dry-run' || '' }}
- name: Create pull requests
if: ${{ !inputs.dry_run }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
autohand parallel merge \
--strategy pr \
--draft \
--labels "automated,migration"
- name: Upload execution report
uses: actions/upload-artifact@v4
with:
name: execution-report
path: .autohand/reports/
GitLab CI
# .gitlab-ci.yml
parallel-migration:
stage: migrate
image: node:20
variables:
AUTOHAND_API_KEY: $AUTOHAND_API_KEY
before_script:
- npm i -g autohand-cli
script:
- autohand parallel run --tasks tasks.yaml --concurrency 20
- autohand parallel merge --strategy pr --draft
artifacts:
paths:
- .autohand/reports/
expire_in: 7 days
when: manual
Troubleshooting
Common issues
| Issue | Cause | Solution |
|---|---|---|
| Worktree creation fails | Insufficient disk space | Free up disk or reduce concurrency |
| Tasks timeout frequently | Complex files or slow API | Increase timeout or reduce file scope |
| Many conflicts detected | Overlapping file patterns | Split tasks to reduce overlap |
| Tests fail in worktree | Missing dependencies | Add setup step to install deps |
| Merge fails silently | Protected branch rules | Use PR strategy or adjust rules |
| API rate limited | Too many concurrent requests | Reduce concurrency or add delay |
Debug mode
# Enable verbose logging
autohand parallel run --tasks tasks.yaml --debug
# Trace specific task
autohand parallel run --tasks tasks.yaml --trace task-001
# Inspect worktree state
autohand parallel inspect task-001
# Validate task file
autohand parallel validate tasks.yaml
Recovery procedures
# If execution is stuck
autohand parallel status --diagnostics
autohand parallel cancel --force
# If worktrees are corrupted
autohand parallel cleanup --force --all
git worktree prune
# If branches are orphaned
autohand parallel cleanup --branches --orphaned
# Reset to clean state
autohand parallel reset --hard
Command reference
| Command | Description |
|---|---|
autohand parallel run |
Execute tasks from YAML file |
autohand parallel status |
View execution status and progress |
autohand parallel logs |
Stream logs from task |
autohand parallel pause |
Pause execution |
autohand parallel resume |
Resume paused execution |
autohand parallel cancel |
Cancel running tasks |
autohand parallel retry |
Retry failed tasks |
autohand parallel conflicts |
Analyze potential conflicts |
autohand parallel resolve |
Resolve conflicts |
autohand parallel merge |
Merge completed tasks |
autohand parallel cleanup |
Remove worktrees and branches |
autohand parallel rollback |
Rollback changes |
autohand parallel metrics |
View execution metrics |
autohand parallel report |
Generate execution report |
autohand parallel validate |
Validate task file |