Merge Command
The sf merge command squash-merges a branch into the default branch (master/main). This is primarily used by agents when completing tasks, but can also be run manually.
Usage
Options
--branch
string
default: "current branch"
Source branch to merge (defaults to current branch)
--into
string
default: "auto-detected"
Target branch to merge into (defaults to master/main, auto-detected)
--message
string
default: "Merge <branch>"
Commit message for the squash merge
Delete source branch and worktree after merge
Examples
# Merge current branch into master/main
sf merge
# Merge with custom commit message
sf merge --message "feat: implement user authentication"
# Merge a specific branch
sf merge --branch feature/login --into main
# Merge and cleanup source branch
sf merge --cleanup --message "docs: automated documentation fixes"
Output
Merged feature/login into main
Commit: a1b2c3d4
Message: feat: implement user authentication
With --cleanup:
Merged feature/login into main
Commit: a1b2c3d4
Message: feat: implement user authentication
Cleanup: source branch and worktree removed
How It Works
The merge command performs a safe, atomic squash-merge:
1. Fetch Latest
Updates remote tracking branches to ensure we’re merging onto the latest target.
2. Create Temporary Worktree
git worktree add --detach .stoneforge/.worktrees/_merge- < timestam p > origin/ < targe t >
Creates an isolated worktree at the target branch HEAD. This ensures:
No impact on current working directory
No conflicts with other agent worktrees
Atomic merge operation
3. Squash Merge
git merge --squash < source-branc h >
Squashes all commits from the source branch into a single staged change.
4. Commit
git commit -m "<message>"
Creates a single commit with all changes.
5. Push to Origin
git push origin HEAD: < targe t >
Pushes the squash-merge commit directly to the target branch on origin.
6. Cleanup Temp Worktree
git worktree remove --force .stoneforge/.worktrees/_merge- < timestam p >
Removes the temporary merge worktree.
7. Optional Cleanup
If --cleanup is specified:
# Remove source worktree (if current directory is a worktree)
git worktree remove --force < source-worktree-pat h >
# Delete source branch locally
git branch -D < source-branc h >
# Delete source branch on remote
git push origin --delete < source-branc h >
Merge Conflicts
If a merge conflict occurs, the command fails and reports:
Merge conflict detected when merging feature/login into main. Resolve conflicts manually.
The temporary worktree is automatically cleaned up. To resolve:
Fetch latest and rebase:
git checkout feature/login
git fetch origin
git rebase origin/main
Resolve conflicts, commit, and push:
git add .
git rebase --continue
git push --force
Retry merge:
Agent Workflows
Worker Completion
When an ephemeral worker completes a task:
# Worker commits changes
git add .
git commit -m "feat: implement feature X"
# Worker pushes to branch
git push origin HEAD
# Worker merges (via orchestrator API, which calls sf merge internally)
sf merge --message "feat: implement feature X" --cleanup
The --cleanup flag ensures the worker’s branch and worktree are removed after merge.
Merge Steward
The merge steward uses this command to review and merge completed work:
# Steward runs tests on the branch
# If tests pass:
sf merge --branch agent/worker-1/task-123-feature-x \
--message "feat: implement feature X" \
--cleanup
# If tests fail:
# Steward creates a task handoff instead of merging
Best Practices
Use conventional commit format:
sf merge --message "feat: add user authentication"
sf merge --message "fix: resolve login bug"
sf merge --message "docs: update API documentation"
sf merge --message "chore: upgrade dependencies"
Branch Naming
Workers use structured branch names:
agent/<worker-name>/<task-id>-<slug>
Examples:
agent/worker-1/task-123-implement-login
agent/merge-steward/task-456-fix-api-bug
Cleanup Strategy
Use --cleanup when:
Agent completes a task (ephemeral workers)
Merge steward auto-merges after tests pass
One-off branches that won’t be reused
Don’t use --cleanup when:
Working on long-lived feature branches
Multiple tasks share the same branch
Need to preserve branch history
Error Handling
Same Source and Target
Source branch "main" is the same as target "main". Nothing to merge.
Solution: Check out a different branch or specify --branch.
Branch Not Found
Failed to merge: pathspec 'feature/xyz' did not match any file(s) known to git
Solution: Verify the branch exists:
git branch -a | grep feature/xyz
No Changes to Merge
Failed to merge: fatal: No changes to commit
Solution: The source branch is already merged or has no new commits.
Agent Commands Agents use merge internally when completing tasks
Task Commands Tasks trigger merges when closed by agents
Advanced Usage
Merge from Different Remote
# Fetch from fork
git remote add fork https://github.com/user/repo.git
git fetch fork
# Merge fork branch
sf merge --branch fork/feature-x --into main
Dry Run (Manual Verification)
To verify what would be merged without actually merging:
# Show diff
git fetch origin
git diff origin/main...feature/login
# Show commits
git log origin/main..feature/login --oneline
Manual Squash Merge (Without sf merge)
If you need more control:
git checkout main
git pull origin main
git merge --squash feature/login
git commit -m "feat: implement login"
git push origin main
git branch -D feature/login
git push origin --delete feature/login
The sf merge command automates this workflow with safety checks and worktree isolation.