Skip to main content

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

sf merge [options]

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
--cleanup
boolean
default:"false"
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

git fetch origin
Updates remote tracking branches to ensure we’re merging onto the latest target.

2. Create Temporary Worktree

git worktree add --detach .stoneforge/.worktrees/_merge-<timestamp> origin/<target>
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-branch>
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:<target>
Pushes the squash-merge commit directly to the target branch on origin.

6. Cleanup Temp Worktree

git worktree remove --force .stoneforge/.worktrees/_merge-<timestamp>
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-path>

# Delete source branch locally
git branch -D <source-branch>

# Delete source branch on remote
git push origin --delete <source-branch>

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:
  1. Fetch latest and rebase:
    git checkout feature/login
    git fetch origin
    git rebase origin/main
    
  2. Resolve conflicts, commit, and push:
    git add .
    git rebase --continue
    git push --force
    
  3. Retry merge:
    sf 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

Commit Message Format

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.

Build docs developers (and LLMs) love