AgentSkillsCN

execute-merge

将已完成任务的 worktree 合并至主分支。通过顺序合并队列,防止冲突发生。

SKILL.md
--- frontmatter
name: execute-merge
description: Merges completed task worktree to main branch. Handles sequential merge queue to prevent conflicts.
context: fork
allowed-tools: Read Write Bash Glob
model: claude-sonnet-4-5

Merge Agent

You merge a completed task's worktree branch into the main branch. Tasks complete in parallel but merge sequentially to avoid conflicts.

Input Arguments

Parse these from the prompt:

ArgumentRequiredDescription
--task-id <id>YesTask ID to merge (e.g., "L1-001")
--project-path <path>YesMain project directory
--worktree-path <path>YesPath to task's worktree
--task-file <path>YesTask XML for commit context
--tasks-path <path>YesTasks directory for state update

Execution Flow

Step 1: Parse Task XML

Read task file for commit message context:

bash
cat {task_file}

Extract:

  • <meta><id>: Task ID
  • <meta><name>: Task name
  • <meta><layer>: Layer name
  • <requirements>: For commit message summary

Step 2: Verify Worktree State

Check worktree is ready for merge:

bash
cd {worktree_path}

# Check we're on the right branch
git branch --show-current
# Expected: worktree-{task_id}

# Check for uncommitted changes
git status --porcelain
# Expected: empty (all changes committed)

# Get commit count
git rev-list --count main..HEAD
# Expected: >= 1

Step 3: Ensure Changes Committed

If there are uncommitted changes (shouldn't happen normally):

bash
cd {worktree_path}
git add .
git commit -m "$(cat <<'EOF'
[{task_id}] Uncommitted changes before merge

Auto-committed by merge agent.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
EOF
)"

Step 4: Switch to Main Project

bash
cd {project_path}

# Ensure we're on main
git checkout main

# Pull latest (in case of external changes)
git fetch origin main
git merge origin/main --ff-only 2>/dev/null || true

Step 5: Merge Worktree Branch

Use --no-ff to preserve merge history:

bash
cd {project_path}

git merge --no-ff worktree-{task_id} -m "$(cat <<'EOF'
Merge worktree-{task_id}: {task_name}

Layer: {layer}
Task: {task_id}
Commits: {commit_count}

Implements:
- {requirement_1_summary}
- {requirement_2_summary}

Verification: Passed
EOF
)"

Step 6: Handle Merge Result

If merge succeeds:

  • Capture merge commit hash
  • Proceed to cleanup

If merge fails (conflict):

  • This should NOT happen with sequential merging
  • Abort merge: git merge --abort
  • Report conflict details
  • Keep worktree for debugging

Step 7: Cleanup Worktree

After successful merge:

bash
cd {project_path}

# Remove worktree
git worktree remove {worktree_path}

# Delete the branch
git branch -d worktree-{task_id}

If removal fails:

bash
git worktree remove --force {worktree_path}
git branch -D worktree-{task_id}

Step 8: Update State

Update execute-state.json:

python
state["tasks"][task_id]["status"] = "completed"
state["tasks"][task_id]["merged_at"] = now()
state["tasks"][task_id]["worktree_path"] = None
state["tasks"][task_id]["branch"] = None

# Update merge queue
for item in state["merge_queue"]:
    if item["task_id"] == task_id:
        item["status"] = "merged"

# Add to completed list
state["completed"].append(task_id)

# Remove from worktrees
del state["worktrees"][task_id]

# Update metrics
state["metrics"]["tasks_completed"] += 1
state["metrics"]["tasks_remaining"] -= 1

Step 9: Report Result

Success:

json
{
  "task_id": "L1-001",
  "status": "merged",
  "merge_commit": "abc1234567890",
  "commits_merged": 2,
  "worktree_cleaned": true,
  "branch_deleted": true
}

Conflict (should not happen):

json
{
  "task_id": "L1-001",
  "status": "conflict",
  "conflict_files": ["app/models/__init__.py"],
  "conflict_type": "both_modified",
  "worktree_preserved": true,
  "resolution_needed": true,
  "suggested_action": "Manually resolve conflict in worktree, then re-run merge"
}

Merge Commit Format

code
Merge worktree-L1-001: Create enums and constants

Layer: 1-foundation
Task: L1-001
Commits: 2

Implements:
- ProjectStatus enum (draft, in_progress, complete)
- PersonaType enum (developer, designer, pm)

Verification: Passed

Sequential Merge Guarantee

The layer agent ensures merges happen in priority order:

code
Merge Queue:
  Priority 1: L1-001 (status: ready)   ← Merge this first
  Priority 2: L1-002 (status: ready)   ← Wait
  Priority 3: L1-006 (status: pending) ← Still implementing

Each task waits for lower-priority tasks to merge before proceeding.

This ensures:

  • No merge conflicts between parallel tasks
  • Deterministic commit history
  • Easy rollback of specific tasks

Worktree Preservation

On merge failure:

  • Never delete worktree
  • Worktree contains all implementation work
  • User can inspect and manually resolve
  • Resume will re-attempt merge after manual fix

Error Handling

Branch Not Found

bash
git merge worktree-{task_id}
# fatal: worktree-L1-001 - not something we can merge

Action: Check if branch exists, report error if not.

Worktree Not Found

bash
git worktree remove {worktree_path}
# fatal: '{worktree_path}' is not a working tree

Action: Already removed (maybe manual cleanup). Continue.

Uncommitted Changes in Main

bash
git checkout main
# error: Your local changes would be overwritten

Action: Error - main should always be clean. Report and stop.

Merge Conflict

bash
git merge --no-ff worktree-{task_id}
# CONFLICT (content): Merge conflict in app/models/__init__.py
# Automatic merge failed; fix conflicts and then commit.

Action:

  1. Abort: git merge --abort
  2. Report conflict details
  3. Preserve worktree
  4. Return conflict status

Output Format

Status Line

code
[MERGE] L1-001 → main (abc1234)

Final Result

code
MERGE_RESULT:
{json object}

Git Commands Reference

CommandPurpose
git merge --no-ff branchMerge preserving history
git merge --abortCancel conflicting merge
git worktree remove pathRemove worktree
git worktree remove --force pathForce remove
git branch -d branchDelete merged branch
git branch -D branchForce delete branch
git rev-parse HEADGet current commit hash
git rev-list --count main..HEADCount commits since main