src/skills/x-merge-branches/SKILL.md
Merges source into target locally with strategy, conflict rollback, and idempotent no-op.
npx skillsauth add edercnj/claude-environment x-merge-branchesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Single, idempotent entry point for merging one local branch into another with three strategies (merge / squash / rebase), automatic conflict detection and rollback, and a structured result payload. Centralises the develop → feature/XXXX sync used when closing a feature, replacing ad-hoc inline git merge blocks. Callers receive either {mergeSha, conflicts:false} or {conflicts:true, rolledBack:true, conflictedFiles:[...]} — never a half-merged working tree.
/x-merge-branches --source develop --target feature/0049 — default merge strategy, push after success/x-merge-branches --source develop --target feature/0049 --strategy squash --message "sync develop" — squash with custom message/x-merge-branches --source feat/foo --target develop --strategy rebase — linear history via rebase/x-merge-branches --source develop --target feature/0049 --no-push — merge locally only| Argument | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| --source | string | Yes | — | Source branch to merge from. Must exist locally. |
| --target | string | Yes | — | Target branch that receives the merge. Must exist locally. |
| --strategy | enum | No | merge | One of merge (default, git merge --no-ff), squash (git merge --squash + commit), rebase (git rebase). |
| --message | string | No | auto | Commit message for merge / squash. Ignored for rebase. Max 255 chars. |
| --no-push | boolean | No | false | Skip git push origin <target> after a successful merge. |
Single-line JSON to stdout:
| Field | Type | Description |
|-------|------|-------------|
| mergeSha | string(40) | null | SHA of resulting merge/squash/rebase-HEAD commit; null on conflict or no-op |
| conflicts | boolean | true when any conflict was detected during the merge attempt |
| conflictedFiles | string[] | List of unmerged paths captured before rollback; [] on success / no-op |
| rolledBack | boolean | true when git merge --abort / git rebase --abort executed successfully |
| noOp | boolean | true when target already contained source HEAD (ancestor check) |
| Exit | Code | Condition |
|------|------|-----------|
| 0 | SUCCESS / NO_OP | Merge committed (or target already contains source) |
| 1 | WORKING_TREE_DIRTY / INVALID_STRATEGY / missing required flag | Argument or precondition error |
| 2 | SOURCE_NOT_FOUND | Source branch missing locally |
| 3 | TARGET_NOT_FOUND | Target branch missing locally |
| 10 | MERGE_CONFLICT_ROLLED_BACK | Conflict detected, rollback succeeded |
| 11 | ROLLBACK_FAILED | git merge --abort / git rebase --abort failed; manual cleanup needed |
1. PARSE_FLAGS -> extract --source/--target/--strategy/--message/--no-push; validate enum
2. PRE_CHECKS -> git status --porcelain clean; rev-parse source + target exist
3. CHECKOUT_TARGET -> git checkout <target>
4. IDEMPOTENCY -> git merge-base --is-ancestor → emit noOp envelope + exit 0
5. ATTEMPT_MERGE -> dispatch on strategy: merge --no-ff / squash + commit / rebase
6. DECIDE -> success → capture mergeSha; conflict → git diff --diff-filter=U + abort
7. PUSH (optional) -> git push origin <target> unless --no-push (WARN on failure, not abort)
8. EMIT_RESULT -> single-line JSON envelope
Detailed bash per step, per-strategy invocation, conflict-capture awk pipeline, and rollback semantics in references/full-protocol.md:
case flag parsing; enum validation for --strategy.git rev-parse --verify --quiet.git checkout.git merge-base --is-ancestor ancestor check; noOp envelope emission.merge --no-ff --no-edit, merge --squash + commit, rebase); per-strategy conflict flag setting.git diff --diff-filter=U to capture unmerged paths BEFORE abort; awk JSON-array formatting; git merge --abort or git rebase --abort per strategy; exit 11 on rollback failure.printf of single-line JSON envelope with success fields.| Scenario | Action |
|----------|--------|
| --source or --target missing | exit 1; print usage hint |
| --strategy invalid | exit 1 INVALID_STRATEGY; print accepted values |
| Dirty working tree | exit 1 WORKING_TREE_DIRTY; no side effects |
| Source/target branch missing | exit 2 / 3 with suggestion git fetch origin |
| Target already contains source HEAD | exit 0 with noOp:true; no commit, no push |
| Conflict during merge/squash/rebase | capture conflictedFiles, abort, exit 10 MERGE_CONFLICT_ROLLED_BACK |
| git merge --abort / git rebase --abort fails | exit 11 ROLLBACK_FAILED; stderr carried verbatim; manual cleanup |
| git push fails | WARN only; local merge is preserved; caller can retry push |
| Skill | Relationship | Context |
|-------|--------------|---------|
| x-close-feature | caller (Phase 2) | develop → feature/XXXX sync before opening the final feature PR |
| x-implement-story | caller (future refactor — story-0049-0019) | Optional auto-sync of story branch with parent feature branch |
| x-internal-ensure-feature-branch | related (story-0049-0008) | Ensures feature/XXXX exists before this skill merges develop into it |
| x-merge-pr | sibling (story-0049-0003) | Remote PR merge via gh pr merge; this skill handles local-only merges |
| x-create-git-branch | sibling (story-0049-0001) | Bare branch creation; this skill assumes both branches exist |
Minimum viable contract above. Detailed bash for all 8 steps (flag parsing, pre-checks, idempotency check, per-strategy dispatch, conflict-capture with git diff --diff-filter=U + awk JSON formatting, rollback semantics, optional push, JSON emission), worked examples, and story-local rule references live in references/full-protocol.md per ADR-0012 (skill body slim-by-default).
development
Documentation freshness gate: validates 6 dimensions (readme, api, adr, etc.) per PR.
testing
Conditional dep-policy gate: CVEs, licenses, versions, freshness; SARIF + report.
documentation
Incrementally updates the service or system architecture document; never regenerative.
development
Scans code and git history for leaked credentials, API keys, and tokens; SARIF output.