Overview
After comparing attempts and choosing the best approach, it’s time to merge those changes into your main branch and clean up temporary worktrees.
The Merge Process
Merging Attempts
Via Web UI
Review Changes
Open task details → Click on completed attempt
Review Diff
Check all file changes carefully:
Files modified
Lines added/removed
Tests passing
Approve
Click “Approve & Merge” button
Confirm
Confirm merge in dialog: Merge attempt #2 (gemini) into main?
Files changed: 8
Additions: +269
Deletions: -16
[Cancel] [Merge]
Success
Task moves to “Done” column
Worktree auto-cleaned
Via CLI
# Basic merge
forge task merge 1 --attempt 2
# Merge with message
forge task merge 1 --attempt 2 \
--message "Add JWT authentication (Gemini implementation)"
# Merge and close task
forge task merge 1 --attempt 2 --close
# Merge without cleanup (keep worktree)
forge task merge 1 --attempt 2 --no-cleanup
Merge Strategies
Fast-Forward Merge (Default)
Clean, linear history:
forge task merge 1 --attempt 2 --ff
# Git history:
# * abc123 Add authentication (gemini)
# * def456 Previous commit
# * ...
When to use : Single-developer, clean history preferred
Merge Commit
Preserves attempt branch history:
forge task merge 1 --attempt 2 --no-ff
# Git history:
# * abc123 Merge task-1-gemini
# |\
# | * def456 Implement JWT tokens
# | * ghi789 Add login endpoint
# |/
# * jkl012 Previous commit
When to use : Multiple developers, want to preserve attempt context
Squash Merge
Combine all commits into one:
forge task merge 1 --attempt 2 --squash
# Git history:
# * abc123 Add user authentication
# - Implemented JWT tokens
# - Added login/signup endpoints
# - Added tests
# * def456 Previous commit
When to use : Clean up messy attempt history, single commit per feature
Pre-Merge Checks
Forge runs automatic checks before merging:
Test Suite
forge task merge 1 --attempt 2
# Automatic checks:
Running pre-merge checks...
✓ All tests pass (24/24)
✓ Linting passed
✓ Type checking passed
✓ No merge conflicts
✓ Branch up to date with main
Ready to merge!
Custom Pre-Merge Hooks
Configure in .forge/hooks.yaml:
pre_merge :
- run : "npm test"
required : true
- run : "npm run lint"
required : true
- run : "npm run build"
required : true
- run : "npm audit"
required : false # Warn but don't block
If any required check fails, merge is blocked:
❌ Pre-merge checks failed
✓ Tests passed
✓ Linting passed
❌ Build failed: TypeScript errors in src/auth/login.ts
Merge blocked. Fix errors and try again.
[View Errors] [Override] [Cancel]
Handling Merge Conflicts
Detecting Conflicts
forge task merge 1 --attempt 2
# Output:
❌ Merge conflicts detected
Conflicts in:
- src/auth/login.ts (3 conflicts )
- package.json (1 conflict )
[Resolve Manually] [Use Ours] [Use Theirs] [Abort]
Resolving Conflicts
Manual Resolution
Interactive Resolution
Automated Strategies
# Open conflicted files
forge task conflicts 1 --attempt 2
# Edit conflicts in your editor:
<<< <<< < HEAD ( main )
const PORT = 3000 ;
=======
const PORT = 8080 ;
>>>>>>> task-1-gemini
# Choose one or combine:
const PORT = process.env.PORT || 3000 ;
# Mark as resolved
git add src/auth/login.ts
# Continue merge
forge task merge 1 --attempt 2 --continue
Post-Merge Actions
Automatic Actions
After successful merge, Forge can:
post_merge :
- run : "npm run build"
- run : "git push origin main"
- notify :
slack : "#engineering"
message : "Task #{{task.id}} merged by {{user.name}}"
- create_pr : # If feature branch
title : "{{task.title}}"
body : "Closes #{{task.id}}"
Manual Post-Merge Steps
Common things you might do:
# Push to remote
git push origin main
# Tag release
git tag -a v1.2.0 -m "Add authentication"
git push origin v1.2.0
# Deploy
npm run deploy
# Notify team
forge task comment 1 \
--message "@team Authentication is live in production!"
Cleanup
Automatic Cleanup (Default)
Forge automatically cleans up after merge:
forge task merge 1 --attempt 2
# Automatic cleanup:
✓ Merged to main
✓ Removed git worktree
✓ Cleaned up temporary files
✓ Archived attempt logs
✓ Updated task status
Done! 🎉
Manual Cleanup
Sometimes you want to keep the worktree:
# Merge without cleanup
forge task merge 1 --attempt 2 --no-cleanup
# Later, clean up manually
forge worktree remove task-1-gemini
# Or clean all merged worktrees
forge worktree cleanup --merged
Cleanup Rejected Attempts
# Remove specific attempt
forge task remove-attempt 1 --attempt 1
# Remove all rejected attempts
forge task cleanup 1 --rejected-only
# Remove all attempts except winner
forge task cleanup 1 --keep-merged
Worktree Management
List Worktrees
# List all worktrees
forge worktree list
# Output:
/Users/you/project abc123 [main]
.forge/worktrees/task-1 def456 [task-1-claude]
.forge/worktrees/task-2 ghi789 [task-2-gemini]
# Git's native command
git worktree list
Remove Worktrees
# Remove specific worktree
forge worktree remove task-1-claude
# Or use git directly
git worktree remove .forge/worktrees/task-1-claude
# Force remove (if needed)
git worktree remove --force .forge/worktrees/task-1-claude
Clean Orphaned Worktrees
Sometimes worktrees get orphaned (branch deleted but directory remains):
# Detect and remove orphaned worktrees
forge worktree cleanup
# Output:
Found 3 orphaned worktrees:
- .forge/worktrees/task-old-1
- .forge/worktrees/task-old-2
- .forge/worktrees/temp-experiment
Remove all? [y/N] y
✓ Cleaned 3 orphaned worktrees
Freed 156 MB of disk space
Forge runs this automatically, but you can trigger it manually if needed
Rolling Back Merges
Made a mistake? Undo the merge:
# If you just merged
git reset --hard HEAD~1
# Via Forge
forge task rollback 1
Revert Merge
After pushing to remote:
# Create revert commit
git revert -m 1 abc123
# Via Forge
forge task revert 1 --create-issue
This creates a new commit that undoes the merge, preserving history.
Merge Best Practices
Always Review First Never merge without reviewing: # Good workflow
forge task review 1 --attempt 2
forge task test 1 --attempt 2
forge task merge 1 --attempt 2
# Bad workflow
forge task merge 1 --attempt 2 --force
Keep Main Stable Main branch should always work:
All tests must pass
No known bugs
Builds successfully
Deployed confidently
Meaningful Commit Messages # Good
forge task merge 1 --message \
"Add JWT authentication with refresh tokens
- Implemented login/signup endpoints
- Added bcrypt password hashing
- Configured JWT with 24h expiry
- Added comprehensive tests (95% coverage)"
# Bad
forge task merge 1 --message "auth stuff"
Clean Up Regularly Don’t let worktrees accumulate: # Weekly cleanup
forge worktree cleanup
# Check disk usage
du -sh .forge/worktrees
Old worktrees waste disk space
Advanced: Partial Merges
Sometimes you want only specific files from an attempt:
# Merge only specific files
forge task cherry-pick 1 --attempt 2 \
--files "src/auth/*.ts"
# Or manually
git checkout task-1-gemini -- src/auth/login.ts
git commit -m "Cherry-pick login from attempt #2"
Integration with CI/CD
Trigger Builds on Merge
.github/workflows/forge-merge.yml
name : Forge Merge
on :
push :
branches : [ main ]
# Only when Forge merges
paths :
- '!.forge/**'
jobs :
deploy :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Deploy
run : npm run deploy
Merge Gates
Require CI checks before merge:
{
"mergeGates" : {
"requireCI" : true ,
"requireReview" : true ,
"requireTests" : true ,
"minCoverage" : 80
}
}
Troubleshooting
Merge fails with 'detached HEAD'
Error : “Cannot merge: worktree is in detached HEAD state”Solution :# Checkout proper branch in worktree
cd .forge/worktrees/task-1-attempt
git checkout task-1-claude
# Retry merge
forge task merge 1 --attempt 1
'Worktree still in use' error
Error : “Cannot remove worktree: directory is locked”Solution :# Check for running processes
lsof | grep ".forge/worktrees/task-1"
# Kill processes if needed
pkill -f task-1
# Force remove
git worktree remove --force .forge/worktrees/task-1
Merge creates huge commit
Issue : Merge commit contains unintended filesSolution :
Check .gitignore is proper
Ensure node_modules/ not committed
Review files before merge:
forge task files 1 --attempt 2
Abort and fix:
git merge --abort
# Fix .gitignore
git add .gitignore
git commit -m "Update .gitignore"
# Retry merge
Error : “Updates were rejected because the remote contains work that you do not have locally”Solution :# Pull and rebase
git pull --rebase origin main
# Resolve conflicts if any
git add .
git rebase --continue
# Push
git push origin main
Cleanup Schedule
Recommended cleanup schedule:
Frequency Action Command
Daily Remove merged worktrees forge worktree cleanup --mergedWeekly Remove old attempt logs find .forge/logs -mtime +7 -deleteMonthly Archive old tasks forge task archive --older-than 30dQuarterly Compact database sqlite3 .forge/forge.db "VACUUM;"
Next Steps