From easy-cheese
Resolves git merge, rebase, or cherry-pick conflicts via a structural cascade: mergiraf (AST-aware auto-resolve), then git rerere, then kdiff3 as manual fallback. Includes squash-merge residue detection and helper scripts for batch resolution.
How this skill is triggered — by the user, by Claude, or both
Slash command
/easy-cheese:meltThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill to resolve git merge, rebase, or cherry-pick conflicts using the structural cascade: **mergiraf → rerere → kdiff3**. Each tool handles what the previous could not.
Use this skill to resolve git merge, rebase, or cherry-pick conflicts using the structural cascade: mergiraf → rerere → kdiff3. Each tool handles what the previous could not.
Do not use it for general git operations without conflicts (those go to a commit or gh skill) or when no conflict markers are present.
melt orchestrates the resolution chain via bash and the helper scripts. For per-file inspection or manual edits, delegate to the cheez-* skills:
/cheez-search — locate conflict markers or related symbols across the tree./cheez-read — inspect conflicted files, view conflict hunks, list directory contents./cheez-write — apply hash-anchored resolutions when bash flows are not enough.The bash-driven flows below cover the bulk of resolution. Drop into the cheez-* skills only when you need to inspect or rewrite a specific file by hand.
| Stage | Tool | What it does | When it runs |
|---|---|---|---|
| 1 | mergiraf | Tree-sitter structural merge of base / ours / theirs. Independent additions merge cleanly even when text merge would conflict. Falls back to text merge on parse failure. | Automatically as a git merge driver, or via batch-resolve.py. |
| 2 | git rerere | Replays a previously recorded human resolution for the same conflict signature. | After mergiraf, especially during long rebases where conflicts recur. |
| 3 | kdiff3 | Manual 3-way diff for what mergiraf and rerere could not resolve. | Launched via git mergetool. |
Run this before the conflict summary. If the branch was squash-merged into base, mergiraf cannot help — the right answer is to either merge base in (non-destructive) or abort and re-cherry-pick the unique commits (destructive).
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz detect-squash-residue
If the verdict is SQUASH-MERGED, surface both printed remedies to the user verbatim and stop the cascade. Neither remedy is auto-applied — the user picks one and copy-pastes. Flags:
--base — base ref to compare against (default: origin/main).--branch — branch to check (default: current).--json — structured output for scripting.Detection cascade (strongest first; later signals run only when needed):
tree-match — walks commits on base looking for one whose tree equals the tree at some point on the branch. That commit is a squash-equivalent of branch commits up to that point. Works offline, through fork PRs and renames, and handles branches with commits past the squash (the case local-synth misses). Always runs first.gh-api — runs in parallel with tree-match. Enriches a tree-match verdict with PR metadata (number, URL, merge commit) when its SHAs correlate with the squash; supplies the verdict on its own when tree-match found nothing.local-synth — synthesizes a would-be squash commit from HEAD's tree and asks git cherry whether base contains an equivalent. Last-resort fallback that only runs when neither tree-match nor gh-api produced a verdict; cannot enumerate squashed vs unique commits.Verdict semantics:
SQUASH-MERGED (method=tree-match or tree-match+gh) — strongest signal; unique-commit list is the slice of branch commits after the matched squash point.SQUASH-MERGED (method=gh-api) — fallback when tree-match found nothing but the gh PR's SHAs overlap with branch commits.SQUASH-MERGED (method=local-synth) — detected offline only; cherry-pick list must be reviewed by hand.not-detected — proceed to the cascade.not-applicable — on the base branch.The detector prints two remedies in order:
git merge <base>. Preserves all branch history; squashed commits collapse to a no-op merge, so only real conflicts surface. Prefer this when the branch has unique work or the unique-commit list is uncertain.git reset --hard <base> + git cherry-pick <unique-shas>. Rewrites the branch and requires force-push. Use when a clean linear history is wanted and the unique-commit list looks complete.Default to suggesting [A] first; only suggest [B] when the user has stated a preference for a linear-history workflow or the unique-commit count is small and verified.
Run the summary script next; it replaces ad-hoc grep -n '<<<<<<<' parsers and is shaped for low-token output.
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz conflict-summary
Default output is terse: one metadata line per file plus minimally framed hunks. Flags:
--json — structured output for scripting.--verbose — markdown view for humans.--context N — context lines around each hunk (default 3).For raw git context:
git log --merge --oneline # commits involved in the merge
git status # conflict / staging state
For every file mergiraf supports, attempt structural merge:
# Preview (dry-run is the default)
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz batch-resolve
# Apply clean resolutions and stage them
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz batch-resolve --apply
# Markdown output and mergiraf debug logs
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz batch-resolve --verbose
To inspect what mergiraf would produce for a single file without touching the working copy, use --debug:
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz batch-resolve --debug <path>
The script extracts the three stages, runs mergiraf with RUST_LOG=mergiraf=debug, keeps the tempdir, and prints paths to the merged output, the log, and the conflict-marker count. Inspect with cat/diff against the printed paths. If the merged output is clean, apply it:
cp <merged_path> <path>
git add <path>
After the structural pass, check rerere first:
git rerere status # files with recorded resolutions
git rerere diff # show what rerere would apply
If rerere already applied, the conflict is resolved. Otherwise drop into the manual tool:
git mergetool # opens kdiff3 for each conflicted file
git mergetool <path> # or just one file
After manual resolution, finish the interrupted operation:
git add <resolved-files>
git merge --continue # or
git rebase --continue # or
git cherry-pick --continue
For shell, SQL, YAML, JSON, and other formats mergiraf does not parse, use conflict-pick.py:
# Take ours for every hunk
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz conflict-pick hooks/session-start.sh --ours
# Take theirs for every hunk
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz conflict-pick .gitignore --theirs
# Match by regex; matched hunks resolve, others remain
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz conflict-pick config.yaml --grep "timeout" --ours
Lockfile content has structure that text or AST merge cannot validate. Take one side and regenerate from the manifest:
# Auto-detect conflicted lockfiles, take theirs, regenerate, stage
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz lockfile-resolve
# Preview
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz lockfile-resolve --dry-run
# Take ours instead
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz lockfile-resolve --strategy ours
Supports Cargo.lock, package-lock.json, yarn.lock, pnpm-lock.yaml, poetry.lock, Pipfile.lock, uv.lock, Gemfile.lock, and go.sum.
When mergiraf is not resolving something it should, use --debug for a single-file inspection (keeps the tempdir, captures RUST_LOG=mergiraf=debug):
python3 ${CLAUDE_SKILL_DIR}/scripts/melt.pyz batch-resolve --debug <path>
mergiraf languages | grep <extension> # is the type registered?
git check-attr merge -- <path> # should show: merge: mergiraf
Common causes:
~/.gitattributes — regenerate after upgrade.mergiraf languages --gitattributes > ~/.gitattributes # after upgrade
git rerere status # what is currently tracked
git rerere diff # pending resolution diffs
git rerere forget <path> # forget a bad resolution
git rerere gc # clean old entries
ls .git/rr-cache/ # browse the resolution database
| Script | Purpose | When |
|---|---|---|
detect-squash-residue.py | Detect that the branch was squash-merged and emit both the merge and reset+cherry-pick remedies | Run first — short-circuits the cascade |
conflict-summary.py | Structured summary with line numbers and context | After residue check |
batch-resolve.py | Run mergiraf merge over every conflicted file | Supported languages |
conflict-pick.py | Choose ours / theirs per hunk | Shell, SQL, formats mergiraf does not parse |
lockfile-resolve.py | Take one side and regenerate the lockfile | Cargo.lock, package-lock.json, etc. |
If one branch ran a formatter while the other modified content, mergiraf can produce more conflicts because AST positions shifted. Resolution: run the formatter on the merged result after resolving conflicts.
If conflict state is unrecoverable, abort and start over:
git merge --abort # or
git rebase --abort # or
git cherry-pick --abort
/melt surfaces abort as an option; the user decides.
gh skill./cook or run project gates.git add staging — use a commit skill./age./cheez-read, /cheez-write, /cheez-search.mergiraf solve flag confusion: use --stdout / -p for preview, NOT --output..gitattributes registration.|||||||) are handled by every script in this skill.After resolution finishes, prompt the next step via the shared handoff gate in ../../shared/handoff-gate.md. Include the detected interrupted operation and upstream invocation in the context packet before asking. Default options:
git merge --continue, git rebase --continue, or git cherry-pick --continue). If the triggering skill invocation is known, return to that skill with the original context after the git operation succeeds; otherwise stop with the resumed git status./melt never resumes before the user selects. After a non-stop selection, run the selected continuation immediately.
detect-squash-residue.py first; if positive, surface both remedies and stop the cascade.conflict-summary.py before deciding the cascade order.git status agrees.npx claudepluginhub paulnsorensen/easy-cheeseAnalyzes git merge conflicts by type and context, proposes automated/manual resolutions, and validates fixes. Handles content, structural, semantic, and formatting issues.
Resolves Git merge and rebase conflicts efficiently using bulk strategies like `git checkout --theirs/--ours` over manual conflict marker editing. Activates on merge/rebase conflicts.
Resolves Git merge, rebase, cherry-pick, and stash pop conflicts by reading markers, choosing strategies, and safely continuing or aborting.