About git-merge-to-main
git-merge-to-main is a guided skill for merging the current Git branch into main. It checks repository state, requests confirmation, preserves protected branches, and avoids automatic conflict resolution or pushing.
Key features
- 01Checks repository and working-tree state
- 02Shows merge plan and waits for confirmation
- 03Keeps protected source branches
- 04Stops on conflicts without resolving
- 05Deletes eligible branches with git branch -d
- 06Does not auto-push or pull
Use cases
- 01Merge a finished feature branch into main
- 02Keep long-lived branches after merging
- 03Review conflicts and resolve them manually
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ chann/ skills --skill git-merge-to-mainAfter installing, type/git-merge-to-mainin Claude Code to confirm it loaded.
Bundled filesagents/openai.yamlevals/evals.json
Details
From the project READMEGit Merge to Main
Overview
Merge the current branch into main, then delete the source branch locally because it's now fully merged, unless the source is protected. Safe by design — never --force, never -D (only -d), never auto-resolves conflicts, never auto-pushes.
Announce at start: "I'm using the git-merge-to-main skill to merge <source-branch> into main and delete it unless it is protected."
Protected Source Branches
The following source branch names are protected and must be kept locally after the merge:
main, master, dev, develop, development, stg, stage, staging, root
If src is a protected source branch, still show the merge plan and proceed after confirmation, but skip the local delete step. Do not run git branch -d "$src" for protected branches, and do not suggest remote deletion for them.
Preconditions
Run these checks before touching anything. Fail closed on any violation — report and stop.
| # | Check | Command | On fail |
|---|---|---|---|
| 1 | In a git repo | git rev-parse --is-inside-work-tree | Abort: "Not a git repository." |
| 2 | HEAD attached (not detached) | git symbolic-ref -q HEAD | Abort: "Detached HEAD; checkout a branch first." |
| 3 | Current branch is not main | [ "$(git branch --show-current)" != "main" ] | Abort: "Already on main; nothing to merge." |
| 4 | Working tree clean | [ -z "$(git status --porcelain)" ] | Abort: "Working tree has uncommitted changes; commit/stash first." |
| 5 | main branch exists locally | git rev-parse --verify main | Abort: "main branch not found locally; create it or use git-merge-to-dev." |
Workflow
Step 1: Capture state
src=$(git branch --show-current)
echo "Source branch: $src"
git log --oneline "main..$src" | head -20 # what will be merged
If main..$src is empty → tell the user "$src has no new commits beyond main; nothing to merge" and stop.
Determine whether the source branch is protected before showing the plan:
protected=(main master dev develop development stg stage staging root)
delete_src=1
case " ${protected[*]} " in
*" $src "*) delete_src=0 ;;
esac
Step 2: Show the plan and confirm
Plan:
1. git checkout main
2. git merge $src
3. git branch -d $src (safe delete; refuses if not fully merged)
4. (you stay on main; push manually when ready)
N commits will be merged. Proceed? (y/N)
If delete_src=0, replace step 3 with:
3. skip the local delete for protected source branch $src
Wait for explicit confirmation. Default is no.
Step 3: Optional — fetch and check divergence (informational only)
git fetch origin main 2>/dev/null || true
behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo 0)
if [ "$behind" -gt 0 ]; then
echo "Heads up: local main is $behind commits behind origin/main."
echo "After merge, you'll want to: git pull --rebase (or reconcile manually) before pushing."
fi
Don't auto-pull. The user controls when to sync.
Step 4: Switch to main and merge
git checkout main
git merge "$src"
Use plain git merge — fast-forward if possible, otherwise create a merge commit. Do not use --no-ff unless the user asks. Do not use --ff-only (it would error on diverged history; let merge handle it).
If merge produces conflicts:
- Stop. Don't try to auto-resolve.
- Report the conflicting paths.
- Tell the user to resolve and either
git commit(to finish the merge) orgit merge --abort(to roll back). - Do not delete the source branch.
Step 5: Delete or keep the source branch
After the merge succeeds and the working tree is clean:
if [ "$delete_src" -eq 0 ]; then
echo "Source branch $src is a protected source branch; skip the local delete."
else
git branch -d "$src"
fi
For non-protected source branches, use -d (lowercase). Git will refuse if the branch isn't fully merged — that's the safety net. Never use -D (force) here. If -d refuses:
- Most likely cause: the merge didn't actually include all of
$src's commits (e.g. the user picked--ff-onlyand it became a no-op, or a hook rewrote the merge). Report and stop; do not escalate to-D.
Step 6: Summary
git log --oneline -5
git branch --show-current
if [ "$delete_src" -eq 0 ]; then
echo "Merged $src into main and kept protected source branch $src locally. Push when ready: git push"
else
echo "Merged $src into main and deleted $src locally. Push when ready: git push"
fi
If a remote-tracking branch origin/$src exists and src is not protected, mention it but do not auto-delete:
Note: origin/$src still exists. Delete the remote branch with:
git push origin --delete $src
For protected source branches, do not suggest deleting the remote branch.
Worked Example
User: 이 브랜치를 main에 머지해줘
Step 1:
src = feature/oauth-login
git log --oneline main..feature/oauth-login →
a1b2c3d feat(auth): add OAuth login flow
e4f5g6h test(auth): add OAuth login tests
Step 2 (plan):
→ checkout main, merge feature/oauth-login, delete feature/oauth-login
User confirms.
Step 3 (divergence): origin/main is 0 commits ahead. ✓
Step 4: git checkout main && git merge feature/oauth-login → fast-forward.
Step 5: git branch -d feature/oauth-login → "Deleted branch feature/oauth-login (was a1b2c3d)."
Step 6: Show git log -5; remind user to push.
Protected source branch example:
User: dev를 main에 머지해줘
Source: dev (protected)
Plan:
1. git checkout main
2. git merge dev
3. skip the local delete for protected source branch dev
User confirms.
→ checkout main, merge succeeds, keep dev locally.
→ Remind user to push main when ready.
Red Flags
Never:
git branch -D(force delete) — use-dand respect the safety check- Auto-resolve merge conflicts — stop and let the user resolve
- Auto-push after the merge — the user pushes when ready
- Run
git pull/git pull --rebasewithout explicit user consent - Delete the remote branch (
git push origin --delete) without explicit user consent - Delete a protected source branch:
main,master,dev,develop,development,stg,stage,staging,root - Use
--forceanywhere - Operate when the working tree is dirty
Always:
- Show the plan and wait for confirmation before merging
- Report conflicts and stop without auto-fixing
- Use
git branch -d(safe) for non-protected source-branch deletion - Identify protected source branches and skip the local delete
- Run
git status --shortafter the merge to verify the tree
Common Mistakes
Force-deleting when -d refuses
- Problem: "branch was not fully merged" → reaching for
-D - Fix: Investigate why the merge was incomplete; never escalate to
-Dautomatically
Deleting a long-lived branch after release merge
- Problem:
dev/staging/masterwas merged intomain, then deleted as if it were a feature branch - Fix: Treat protected source branches as keep-after-merge; skip the local delete
Auto-pushing after merge
- Problem: Surprises the user; may break collaborator workflows if main was behind
- Fix: Stop after the merge; tell the user to push manually
Pulling main without permission
- Problem:
git pullmay rebase or merge unexpected commits - Fix: Only
git fetch origin main(informational); leave reconciliation to the user
Integration
Pairs with:
git-commit/git-commit-push— commit working-tree changes first, then mergegit-branch-cleanup— bulk-delete other branches that are already merged into maingit-merge-to-dev— same pattern, target =dev(ordevelop)
Called by: Manual user invocation only. Never auto-run during another skill's workflow.