# Merging Branches

> Use BEFORE any git merge, rebase, or branch integration. Reads the project conventions file (CLAUDE.md or AGENTS.md) to determine merge strategy, runs pre-merge safety checks (diff name-status both sides, clean working tree, up-to-date with remote, conflict scan), requires explicit user confirmation for merge to main/master/release branches. Trigger phrases — "merge X into Y", "rebase onto", or a…

- **Type:** Skill
- **Install:** `agentstack add skill-kirkruglov-officina-merging-branches`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [KirKruglov](https://agentstack.voostack.com/s/kirkruglov)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [KirKruglov](https://github.com/KirKruglov)
- **Source:** https://github.com/KirKruglov/OFFICINA/tree/main/skills/merging-branches

## Install

```sh
agentstack add skill-kirkruglov-officina-merging-branches
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Merging Branches

When invoked, follow this procedure step by step. Create a TodoWrite task per step.

## Rule Hierarchy

1. Explicit user instruction in the current message — wins.
2. Project conventions file — `CLAUDE.md` or `AGENTS.md` — sections `## Git workflow`, `## Branching`, `## Release process`.
3. Global conventions — `~/.claude/CLAUDE.md` (or your harness's global agents file, e.g. `~/.codex/AGENTS.md`).
4. This SKILL.md.

## Step 1: Read conventions and determine strategy

- Read the project conventions file — `CLAUDE.md` or `AGENTS.md`. Look for sections: `## Git workflow`, `## Branching`, `## Release process`.
- Read the global conventions file — `~/.claude/CLAUDE.md` (or the equivalent for your harness) — as fallback.
- If you find merge-strategy guidance, surface the relevant quote to the user and ask to confirm interpretation:

```
From project conventions file:
> On release push — squash-merge the branch's commits.

Interpreted strategy: squash. Confirm? (y/n/other)
```

If strategy is NOT described in any conventions file — ask user directly: squash / merge commit / rebase / ff-only.

## Step 2: Identify source and target

- Both must come from user request. If either is ambiguous — ask. Do NOT guess based on current branch.

## Step 3: Classify target

**Protected branches** (require extra confirmation):
- `main`, `master`
- `release/*`
- `production`, `prod`, `staging`

For protected target, add an explicit confirmation gate:

```
⚠ Target = main (protected branch).
This will change commit history on `main` permanently. Confirm explicitly by typing the exact phrase: "yes merge to main"
```

Only proceed if user types the exact confirmation phrase.

Note: the phrase must include the full branch name including any `/` characters. For `release/0.1.0` the confirmation is `"yes merge to release/0.1.0"`.

## Step 4: Pre-merge safety checks

Run all four in order. Any failure → STOP and report.

### 4a. Clean working tree

```bash
git status --porcelain
```

If non-empty → STOP. List dirty files. Ask user: stash / commit (invoke committing-changes) / cancel.

After `committing-changes` completes and reports success, resume this skill from Step 4b. The merge has NOT been performed yet — only the working tree was cleaned.

### 4b. Up-to-date with remote

Detect target's configured upstream (avoid hardcoding `origin`):
```bash
git rev-parse --abbrev-ref @{upstream}
```

If this fails (no upstream configured) → skip the rest of 4b with a note in the plan: "step 4b skipped — no upstream for ".

Otherwise:
```bash
git fetch
git rev-list --count ..@{upstream}
```

If count > 0 (local target is behind upstream) → STOP. Offer `git pull --ff-only` on target before proceeding.

Also check source the same way:
```bash
git rev-parse --abbrev-ref @{upstream} 2>/dev/null && \
  git rev-list --count ..@{upstream}
```

If source is behind its upstream — warn user but allow continuing.

### 4c. Diff name-status both sides

```bash
git diff --name-status ...
git diff --name-status ...
```

Show both lists. Highlight files that appear in BOTH (potential conflicts).

### 4d. Pre-conflict scan (cascading fallback)

**Phase 1: detect Git version**
```bash
git --version
```

**Phase 2: pick strategy by version**

- **Git ≥ 2.38** — modern `merge-tree`:
  ```bash
  git merge-tree --write-tree  
  ```
  Parse output for conflict markers (`>>>>>>`). Git auto-computes the merge base.

- **Git ≥ 2.0,  )
  git merge-tree "$base"  
  ```
  Old format: blocks "changed in both" + conflict markers.

- **Any version — fallback via temp worktree** (if `merge-tree` failed or gave unreadable output):
  ```bash
  WT=/tmp/claude-conflict-check-$$
  git worktree add --detach "$WT" 
  git -C "$WT" merge --no-commit --no-ff  || true
  git -C "$WT" diff --name-only --diff-filter=U
  git -C "$WT" merge --abort 2>/dev/null || true
  git worktree remove --force "$WT"
  ```
  
  Uses `git -C ` to avoid `cd` (each Bash call resets working directory in Claude's model). `|| true` ensures cleanup runs even if merge fails.

**Results:**
- No conflicts → note "predicted conflicts: none", continue.
- Conflicts → show file list (+ blocks if available), ask user: proceed and resolve manually / cancel.
- Scan failed (worktree fallback also failed, e.g., shallow clone) → say "pre-conflict scan not performed", ask user to OK skipping.

**Edge case:** Git  ()
  target:  (protected: true/false)
  strategy:  (source: conventions | user)

  Files changed: 
  Overlaps with target: 
  Predicted conflicts: none | 

  Commands:
    git checkout 
    git merge ... 

Confirm? (y/n)
```

Without `y`, do NOT execute.

## Step 6: Execute merge

| Strategy | Commands |
|---|---|
| squash | `git checkout  && git merge --squash ` then invoke `committing-changes` with context: "this is a squash merge — skip atomic-split check (Step 4), produce a single commit". |
| merge commit | `git checkout  && git merge --no-ff  -m "merge:  into "` |
| rebase | `git checkout  && git rebase  && git checkout  && git merge --ff-only ` |
| ff-only | `git checkout  && git merge --ff-only ` (fails if not fast-forward — feature, not bug) |

## Step 7: Conflict during actual merge

- STOP. Do NOT run `git merge --abort` without confirmation.
- Show conflicts: `git diff --name-only --diff-filter=U`.
- Ask user: resolve manually / abort.
- Do NOT auto-edit conflict files.

## Step 8: Final report

- SHA of merge commit (or new HEAD for ff/rebase).
- Run `git status` and confirm clean.
- Brief: "Merged N commits into ".
- **Do NOT push.** Push is always separate, explicit.
- **Do NOT delete source branch** without explicit user command.

## Step 9: Forbidden without explicit user command

These require a separate, explicit user instruction:
- `git push` (any form)
- `--force` / `--force-with-lease`
- `git branch -D `
- `git push origin --delete `
- `git reset --hard`

If Claude is tempted to use any of these — STOP, report to user, wait for explicit go-ahead.

## Override phrases

| Phrase | Effect |
|---|---|
| "force squash/merge/rebase" | Set strategy manually, skip conventions read |
| "skip checks" | Skip 4b (remote sync) and 4d (conflict pre-scan) only. 4a (clean working tree) and 4c (diff display) always run. |
| "force" | Does NOT enable `--force` push. Force-push still requires "yes force push to " |

## Absolute prohibitions

- Any `git config` modifications.
- `git push --force` to protected branch without typed phrase "yes force push to ".
- `git reset --hard` if untracked files exist — first offer stash, then separate confirmation.

## Edge cases (handle and report)

- **Not a git repository**: report and stop. Never run `git init`.
- **Detached HEAD on target**: report and stop — cannot meaningfully merge into detached HEAD without explicit user intent.
- **No `origin` remote**: skip step 4b (up-to-date check) with a note in the plan. Local-only merge still proceeds.
- **Shallow clone** (`.git/shallow` exists): pre-conflict scan may be inaccurate — warn user before step 4d.
- **Submodules** in either branch: warn separately — submodule pointer changes can surprise users.
- **Existing `.git/MERGE_HEAD`**: STOP. A previous merge is unfinished. Ask user to resolve or abort it first.
- **Existing `.git/rebase-merge/` or `.git/rebase-apply/`**: STOP. A previous rebase is unfinished. Ask user to resolve (`git rebase --continue`) or abort (`git rebase --abort`) first.
- **Pre-conflict scan fails entirely** (worktree fallback also fails): say "pre-merge conflict prediction unavailable", require explicit user OK to proceed without it.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [KirKruglov](https://github.com/KirKruglov)
- **Source:** [KirKruglov/OFFICINA](https://github.com/KirKruglov/OFFICINA)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kirkruglov-officina-merging-branches
- Seller: https://agentstack.voostack.com/s/kirkruglov
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
