Resolve conflicts
Input
$ARGUMENTS
You merge the base branch into a feature branch and resolve the conflicts
correctly — preserving the intent of both sides, never blindly picking one.
All work happens in an isolated worktree, never the user's main checkout. A
wrong conflict resolution silently corrupts code, so verify before you push.
Requires the superpowers plugin.
Step 1 — Resolve the target branch and its isolated worktree
$ARGUMENTS is a PR number or a branch name (default: the current branch). Get the
branch, then reuse its existing ha worktree or create one — never edit the
main checkout.
ARG="<pr-number | branch | empty>"
CLAUDE_SKILL_HA_DIR="${CLAUDE_SKILL_DIR}" # ha-recognizable alias of the built-in skill dir
if [ -z "$ARG" ]; then ARG="$(gh pr view --json number --jq .number 2>/dev/null)"; fi # no arg -> current branch's PR
if printf '%s' "$ARG" | grep -qE '^[0-9]+$'; then
PR="$ARG"; BRANCH="$(gh pr view "$PR" --json headRefName --jq .headRefName)"
else
PR=""; BRANCH="${ARG:-$(git branch --show-current)}"
fi
eval "$(bash "$CLAUDE_SKILL_HA_DIR/scripts/attach-or-create-worktree.sh" "$BRANCH")"
[ -n "${WORKTREE_PATH:-}" ] || { echo "error: worktree was not resolved — aborting"; exit 1; }
echo "Resolving in: $WORKTREE_PATH on $BRANCH (reused=$REUSED)"
If attach-or-create-worktree.sh exits non-zero (e.g. the branch is checked out in
the main checkout), stop and report; do not fall back to resolving in place.
Absolute-path rule (MUST): the main session cwd is NOT this worktree, and a
cd does not persist between Bash calls. So: every Edit/Write targets an
absolute path under $WORKTREE_PATH; every git/test/build runs as
git -C "$WORKTREE_PATH" ... or cd "$WORKTREE_PATH" && <cmd> in one Bash call;
every subagent is given the absolute $WORKTREE_PATH.
Step 2 — Merge the base branch and surface the conflicts
BASE="$(bash "$CLAUDE_SKILL_HA_DIR/scripts/detect-base-branch.sh" "$WORKTREE_PATH")"
echo "Base branch: $BASE"
git -C "$WORKTREE_PATH" fetch origin "$BASE" --quiet
git -C "$WORKTREE_PATH" merge --no-edit "origin/$BASE" || true # conflicts are expected
echo "=== Conflicting files ==="
git -C "$WORKTREE_PATH" diff --name-only --diff-filter=U
If there are no conflicting files, the merge already succeeded — skip to Step 5 (verify) and finish. If the working tree was dirty and the merge refused to start, stop and report; do not force it.
Step 3 — Plan each resolution (intent first, before editing)
For every conflicted file, read the conflict hunks (<<<<<<< / ======= /
>>>>>>>) and the surrounding code, and decide the resolution strategy per
hunk — keep ours, keep theirs, or combine both (the common correct answer:
both sides changed for a reason). Record one line per file: the strategy and why.
Resolving a conflict by deleting one side's real change is a silent regression.
Step 4 — Resolve (in $WORKTREE_PATH)
- 1–2 conflicted files: resolve them yourself, editing absolute paths under
$WORKTREE_PATH, thengit -C "$WORKTREE_PATH" add <file>. - 3+ conflicted files: partition into file-disjoint slices and dispatch one
general-purpose subagent per slice in parallel (one
Agentmessage), each following thecode-reviewstandards and given the absolute$WORKTREE_PATH, the exact files it owns, and the per-hunk strategy. Each resolves andgit adds only its own files; then you integrate.
The code-review standards auto-activate — a resolution must not introduce a new
bug or drop either side's intent.
Step 5 — Integration review (CRITICAL) + verify the build
Conflict resolution is exactly where parallel edits silently break each other.
Before committing, dispatch a verifier subagent against the claim "the merge is
resolved correctly — no hunk lost either side's intent, no conflict markers remain,
the seams between independently-resolved files are coherent". Also confirm no
markers survive and run the build:
git -C "$WORKTREE_PATH" diff --check
grep -rnE '^(<<<<<<<|=======|>>>>>>>)' "$WORKTREE_PATH" --exclude-dir=.git && echo "MARKERS REMAIN — fix before commit" || echo "no markers"
cd "$WORKTREE_PATH" && {
if [ -f Makefile ] && grep -qE '^(check|test|ci):' Makefile; then make check 2>&1 || make test 2>&1
elif [ -f package.json ]; then npm test 2>&1 || npm run test 2>&1
elif [ -f pyproject.toml ]; then { command -v uv >/dev/null && uv run pytest 2>&1; } || pytest 2>&1
elif [ -f go.mod ]; then go test ./... 2>&1
elif [ -f Cargo.toml ]; then cargo test 2>&1
else echo "No standard check found — verify the touched paths manually"; fi
}
If the verifier refutes the resolution or checks fail, REQUIRED SUB-SKILL: Use
superpowers:systematic-debugging to find the root cause, fix, and re-review
before committing — do not improvise a patch on a broken merge.
Step 6 — Commit the merge and push
Only once markers are gone, the verifier upholds the resolution, and checks pass:
git -C "$WORKTREE_PATH" add -A
git -C "$WORKTREE_PATH" commit --no-edit # completes the merge commit
git -C "$WORKTREE_PATH" push
If a PR was resolved (given or auto-detected), leave a short note:
[ -n "$PR" ] && gh pr comment "$PR" --body "Merged origin/$BASE and resolved conflicts:
- <file> — <strategy>
Verification: <result>"
If it goes wrong
Abort cleanly without touching anything else — the worktree isolates the damage:
git -C "$WORKTREE_PATH" merge --abort
Then report what conflicted and why you stopped.
Final report
result: PR/branch <id> — merged origin/<base>, resolved <k> conflicted files in <worktree>; verifier <UPHELD|REFUTED>, checks <green/red>, <pushed|stopped>.