git-merge
Skill4 starsChanged 17 days agoMITView on GitHub
Merge one branch (usually the default branch) into the current branch while preserving local unstaged changes, resolving conflicts by understanding both sides, and catching silent semantic conflicts with the repo's own checks. Trigger on explicit `/git-merge`, or when the user asks to merge a branch or the default branch into their current branch — especially when they want to keep local-only unstaged changes.
- Reads credentials
- Commits and pushes
8 other projects use a version of this.
Adopted by
Most recently taken up by
- Zenobia000/agent-skills-startertheir own version, first seen Nov 1, 2026
- futex-ai/skillstheir own version, first seen Oct 25, 2026
- microsoft/hve-coretheir own version, first seen Oct 13, 2026
- cognis-digital/skillsmiththeir own version, first seen Oct 11, 2026
- rohanhong/tmpl.general-repotheir own version, first seen Oct 11, 2026
- aws-solutions/konductortheir own version, first seen Sep 23, 2026
Other versions8 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 8
- microsoft/hve-core★ 1.6ksame name
- aws-solutions/konductor★ 11same name
- Cogni-AI-OU/cogni-ai-agent-skills★ 4same name
- Zenobia000/agent-skills-starter★ 4same name
- rohanhong/tmpl.general-repo★ 3same name
- ogromwang/skills★ 2same name
- futex-ai/skills★ 1same name
- cognis-digital/skillsmith★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository17 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ask-firstSkill
- claude-project-rulesSkill
- compact-markdownSkill
- humanizeSkill
- pr-reviewSkill
- empty-commitSkill
- github-issue-creatorSkill
- git-worktreeSkill
- handoff-sessionSkill
- html-landing-pageSkill
- offload-taskSkill
- readme-craftSkill
- skill-auditSkill
- study-notesSkill
- visualize-itSkill
- zoom-outSkill
The file
We split this skill into the rules it gives an agent
11 rules. 0 are common, 4 are distinctive, and 7 are very specific to this project.
0
Common
Most of the 6 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 14
Read-only investigation first.
- Very specific: line 15
Never auto-commit beyond the one merge the user authorized.
- Distinctive: line 17
Keep the user's local-only unstaged files OUT of any commit.
- Distinctive: line 18
Never push unless asked.
- Distinctive: line 19
Never install tooling mid-merge.
- Very specific: line 68
Read full file region (Read tool), not just combined diff --cc.
- Distinctive: line 74
After each file, git add it to mark resolved.
- Very specific: line 88
No script but a tracked tsconfig.json → npx --no-install tsc --noEmit -p tsconfig.json.
- Very specific: line 89
Not a TS repo → same rule with its own tooling (go build ./..., cargo check, mypy).
- Very specific: line 109
After the commit, run bash scripts/merge-verify.sh [-- <check command>] again.
- Very specific: line 113
Remove scratch files from investigation (e.g.
“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Git Merge — Safe Branch Integration
Workflow the main agent runs. Investigate before mutating; preserve local-only unstaged changes; resolve conflicts by diagnosis; verify with the repo's own checks before done.
Scripts in this skill's scripts/ folder (bash, run with cwd = repo root, as bash <skill-dir>/scripts/<name>.sh) do the mechanical steps and print compact digests. Below, scripts/ means that folder.
Hard rules
- Read-only investigation first.
merge-recon.sh(fetch + map state) before anystash/merge. - Never auto-commit beyond the one merge the user authorized.
git commit/--amendneed explicit user approval — ask (amend / separate fixup / leave it). git add/stash/mergeare mutating — explain, then run (user already asked to merge = authorization for the merge itself).- Keep the user's local-only unstaged files OUT of any commit. Stage only merge-resolution files.
- Never push unless asked.
- Never install tooling mid-merge. Run only checks the repo already has.
1. Recon
bash scripts/merge-recon.sh <target> # default target: origin's default branch; current branch from HEADRuns git fetch origin (all of origin, not one branch: fetch origin <target> leaves origin/<current-branch> outdated, and recon compares both), then prints one digest: target commits + merge-base, ahead/behind OWN remote (+ partial remote merge), files both merges bring, local unstaged/untracked/ignored, COLLISIONS. Dies on merge/rebase in progress, unmerged paths, detached HEAD, missing origin/<target>.
Why:
- Local branch may be behind its own remote, remote may already hold a partial
Merged <target>commit → "merge properly" = two steps: sync (--ff-only) toorigin/<current-branch>, then mergeorigin/<target>. Decide before touching tree. - Ignored files matter. Plain
git statushides them;mergeoverwrites an ignored file silently, exit 0 when incoming side tracks that path (local.env/config lost). Script uses--ignored. - Both merges checked.
--ff-onlysync rewrites tree too → same collisions. - COLLISIONS: modified → stash (step 3); untracked → merge aborts, move aside; ignored → silent overwrite, move aside. None → no stash needed.
- Lists are capped (
+N more), counts exact. Merge attempt names every conflict; trust it over lists.
2. Confirm approach (when branch is behind its remote)
Hard-to-reverse + user's call. Ask: sync-then-merge (recommended, fully up to date, clean FF push) vs merge-into-outdated-HEAD (diverges from remote → messy push). Note it creates one merge commit.
Recon says DIVERGED (behind and ahead) → --ff-only sync fails. Ask instead: rebase local-only commits onto origin/<current-branch> (linear, rewrites unpushed commits only) vs merge origin/<current-branch> first (extra merge commit). Then merge target.
3. Preserve local unstaged changes
bash scripts/merge-stash.sh push # records new stash SHA only if this call created one
git merge --ff-only --no-overwrite-ignore origin/<current-branch> # sync step, if branch was behind
git merge --no-ff --no-commit --no-overwrite-ignore origin/<target> # always stops before commit, even when clean or FF-able
# ... resolve conflicts (step 4), verify (step 5) ...
git commit -m "Merge remote-tracking branch 'origin/<target>' into <current-branch>" > commit.log 2>&1 # hook output to file; then check exit code + grep -iE 'error|fail' commit.log
bash scripts/merge-stash.sh pop # pops recorded SHA; no-op if push created none- Nothing to merge → before the target merge (after sync, if any),
git merge-base --is-ancestor origin/<target> HEADexit 0 means target already in HEAD;git mergewould printAlready up to date.and leave nothing to commit. Skip merge + commit, go straight to stash pop. - Stash first, then sync.
merge --ff-onlyalso refuses to run when local edits overlap files the remote changed. Stash before either merge, not between them. git stash pushexits 0 with nothing to stash, so baregit stash poppops whatever is on top (maybe a days-old user stash).merge-stash.shcomparesrefs/stashbefore/after, pops by SHA only if it created the stash. Pop conflict → git keeps the stash; script prints ref; resolve, thengit stash drop <ref>.- Short commit message — one line only.
git commit --no-editafter a conflicted merge auto-appends aConflicts:file list → bloated message. Always commit with explicit-m "Merge remote-tracking branch 'origin/<target>' into <current-branch>". Same for--amend(step 6):git commit --amend -m "<same one-liner>", never--amend --no-edit(keeps bloated message). - Redirect pre-commit hook output. Lint/typecheck hook can dump tens of KB on
git commit. Send to file (> commit.log 2>&1); never--no-verify, hook must run; surface only exit code +grep -iE 'error|fail' commit.log.git commitonly;git stash popruns no hooks. - Stash pop usually auto-merges shared files cleanly (3-way: stash base / merged file / local edits). Re-conflict → combine merged-target version + local tweaks, then
git restore --staged <file>, notgit add(clears the conflict, keeps local edits unstaged and out of any commit), thengit stash drop <ref>. --no-overwrite-ignoreon both merges. Untracked files abort a merge by default; ignored files are overwritten silently. Flag makes git abort on those too — verified on--ff-only; NOT on a true merge with git 2.54 (defaultortstrategy overwrote silently). Treat it as a backstop only: move every recon-reported ignored collision aside before merging.- Non-colliding untracked files (scratch dir, local notes, Windows
nulartifact) don't block merge; leave them.git stash pushleaves them too. - Colliding path (recon COLLISIONS, untracked/ignored): either merge adding a tracked file where an untracked/ignored file sits aborts (
untracked working tree files would be overwritten),--ff-onlysync included. Move colliding ones aside (orgit stash push -u -- <path>) before merging. Never restore over the path after: it now holds the tracked version. Diff moved copy vs tracked, ask user how to reconcile (local secrets must not land in the tracked file). Leave every non-colliding file alone.
4. Resolve conflicts — diagnose, don't guess
Understand both sides before editing.
- Most conflicts additive — both sides added different methods/fields/params adjacent → keep both.
- Read full file region (Read tool), not just combined
diff --cc; it hides shared context. - Overlapping logic → combine faithfully (keep both guards/branches).
- Both sides changed SAME action → prefer newer/more-robust pattern, consistent with already-merged sibling blocks.
- Parameterized method (HEAD) whose defaults reproduce target's plain version → keep parameterized superset.
- Examples + removed/renamed-param caller handling:
references/conflict-resolution.md(load on demand).
After each file, git add it to mark resolved. Final marker/unmerged check is in step 5.
5. Catch SILENT semantic conflicts — verify
Git merges files independently. Signature change in file A + call in file B do NOT textually conflict but will NOT compile. Always run the repo's OWN checks after resolving — and only those. A merge must not introduce a toolchain the branch didn't have.
Find what already exists before running anything:
git show HEAD:package.json # declared scripts: typecheck / lint / build / test
git ls-files | grep -iE 'tsconfig|eslint|biome|go\.mod|Cargo\.toml|pyproject'- Declared script → use it (
npm run typecheck,npm run lint). Repo's choice wins. - No script but a tracked
tsconfig.json→npx --no-install tsc --noEmit -p tsconfig.json.--no-installkeeps it on the repo's own TypeScript; if that errors, TS isn't a dependency here → don't install one, skip. - Not a TS repo → same rule with its own tooling (
go build ./...,cargo check,mypy). Configured-only. - Nothing configured → no static check available. Say that plainly and rely on the marker/unmerged checks. Don't add tooling mid-merge.
Pass the chosen command to the verify script:
bash scripts/merge-verify.sh -- npm run typecheck # or no `--` part when nothing is configuredPrints: conflict markers (tracked, non-binary), unmerged files, check exit code + first 20 error lines (command runs from repo root, output redirected to a temp file), pre-push checks, final PASS/FAIL: reasons. Mid-merge (before commit) push checks are skipped; staged resolution files expected.
- Param removed/renamed across merge: grep all CALLERS; don't invent a mapping (see
references/conflict-resolution.md).
6. Commit discipline
- Authorized merge commit must pass whatever step 5 found. Check reveals a fix only AFTER committing → ask user: amend merge commit / separate fixup commit / leave unstaged.
- Amend = stage ONLY the fix file (local-only unstaged files stay out); explicit one-line
-mfrom step 3, never--amend --no-edit.
7. Pre-push verification
After the commit, run bash scripts/merge-verify.sh [-- <check command>] again. PASS = no conflict markers, check clean, FF-safe (origin/<current-branch> ancestor of HEAD; clean push, no force), nothing staged. Local-only unstaged changes are not committed → won't push. Don't run git push; tell user the command.
8. Cleanup
Remove scratch files from investigation (e.g. commit.log, temp git show > file; Read can't open /tmp on Windows).
Extra
Fix an already-pushed merge message (rewrites published history, confirm first): references/fix-pushed-merge-message.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

