Merge Conflict Resolution skill for Codex

Keep both intents, not just one side's text. Codex resolves conflicts by reading why each side changed the code, using zdiff3 to see the common base and keeping the rebase ours/theirs inversion straight. Lockfiles, codegen output, snapshots and parallel migrations are regenerated with the right tool rather than spliced, rerere handles repeat conflicts, and every merge is built and tested because clean merges can still be broken.

  • Engineering Workflow
  • $merge-conflict-resolution
  • 167 lines
  • 2 files
  • ~1,850 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- merge-conflict-resolution

Installs to ~/.agents/skills/merge-conflict-resolution/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $merge-conflict-resolution, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Resolves git merge, rebase and cherry-pick conflicts by intent rather than by picking a side - reading base, ours and theirs with zdiff3, handling the ours/theirs inversion during rebase, regenerating lockfiles (npm, pnpm, Yarn, uv, Poetry, Go, Cargo) and generated files instead of hand-merging them, merging parallel migrations, reusing resolutions with rerere, and catching semantic conflicts that produce no markers. Use when a merge or rebase stops with conflicts, a lockfile or snapshot conflicts, or a merge compiled but broke behaviour.

Use it when

  • A merge, rebase or cherry-pick stops with conflicts
  • Lockfiles, snapshots or generated code conflict
  • A clean merge compiles but behaviour broke

Use something else when

  • You want to restructure commits rather than combine branches: use git-history-surgery
  • The failure predates the merge and you need the commit that caused it: use git-bisect

How to check the result

No conflict markers remain, the lockfile diff touches only expected packages, and build, types and tests pass on the merged result.

The mistake it prevents

Taking --theirs during a rebase believing it means the main branch, when in a rebase theirs is your own commit being replayed.

~/.agents/skills/merge-conflict-resolution/SKILL.md

--- name: merge-conflict-resolution description: Resolves git merge, rebase and cherry-pick conflicts by intent rather than by picking a side - reading base, ours and theirs with zdiff3, handling… license: MIT ---

A conflict is resolved when the result contains the intent of both sides, not just the text of one, the project builds and its tests pass on the merged result, no conflict markers remain, and generated files were regenerated rather than spliced by hand.

First, look before editing

git status                                     # which operation is in progress
git diff --name-only --diff-filter=U           # conflicted paths
git config merge.conflictStyle zdiff3          # show the common base inside markers (Git 2.35+)
git checkout --conflict=zdiff3 -- <path>       # re-render an existing conflict with the base

Understand why each side changed the code before choosing:

git log --merge --oneline -- <path>            # commits from both sides touching the path
git show :1:<path> > "$TMPDIR/base"            # common ancestor
git show :2:<path> > "$TMPDIR/ours"            # stage 2
git show :3:<path> > "$TMPDIR/theirs"          # stage 3
git log -1 --format=%B <sha>                   # read the commit message for intent

Which side is “ours”

Operationours / stage 2theirs / stage 3
git merge feature (on main)main, the branch you are onfeature, being merged in
git rebase main (on feature)main plus already-replayed commitsyour feature commit being replayed
git cherry-pick <sha>current branchthe picked commit

The rebase inversion causes most wrong resolutions. Say out loud which side is yours before using --ours or --theirs.

Resolve by conflict type

Pattern in the hunkResolution
Both sides added different lines at the same spot (imports, list entries, routes)Keep both; order them by the file’s convention; remove duplicates
One side changed logic, the other reformatted or renamedTake the structural change, then re-apply the logic change by hand
One side moved or extracted code, the other edited it in the old placeApply the edit to the code’s new location; delete the old copy
Same line changed differently for different reasonsCombine both intents; if incompatible, ask the user which wins
Modify/delete (one side deleted the file)Find out why it was deleted; usually port the modification to wherever the code went
Both sides fixed the same bug differentlyKeep one fix, not both; prefer the one with a test

Edit the file to the final intended content, remove every marker, then:

git add <path>
rg -n '^(<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|)( |$)' .   # no markers anywhere
git diff --cached --check                                  # also flags leftover markers

Files you regenerate, never hand-merge

Lockfiles

Resolve the manifest (package.json, pyproject.toml, go.mod, Cargo.toml) first, then let the tool rebuild the lockfile. Most of these need registry access, which may need network approval in the Codex sandbox.

LockfileCommand after the manifest is resolved
package-lock.jsonnpm install (npm resolves lockfile conflict markers itself)
pnpm-lock.yamlpnpm install (pnpm resolves lockfile conflicts on install)
yarn.lock (Berry)yarn install
uv.lockuv lock
poetry.lockpoetry lock (Poetry 1.x: poetry lock --no-update)
go.sumkeep both sides’ lines, then go mod tidy
Cargo.lockgit checkout --theirs Cargo.lock (or ours), then cargo metadata >/dev/null to re-sync
Gemfile.lockbundle lock

Do not delete the lockfile and regenerate from scratch; that upgrades every dependency. Check afterwards that only expected packages changed: git diff --cached --stat.

Other generated output

  • Codegen (GraphQL types, protobuf stubs, ORM clients, OpenAPI clients): resolve the source schema, re-run the generator from AGENTS.md or package.json scripts.
  • Built assets and minified bundles committed to the repo: rebuild.
  • Test snapshots: resolve the code, re-run the tests with the update flag (-u), and review the snapshot diff like code.
  • Changelogs: keep both entries in the right section.

Database migrations

Two branches each adding a migration create parallel heads even without a textual conflict:

alembic heads                        # more than one head means a merge migration is needed
alembic merge heads -m "merge heads"
python manage.py makemigrations --merge     # Django

Sequential numbered migrations with the same number: renumber the one that has not been deployed anywhere, after confirming with the user.

Semantic conflicts (no markers, still broken)

Git merges text, not meaning. A clean merge can still break when one side renamed a function and the other added a call to the old name, changed a default the other relies on, or added an enum value the other’s exhaustive switch does not handle. Always run the build, type checker and tests after a merge, even a clean one. Review what the resolution itself introduced:

git show --remerge-diff <merge-sha>   # Git 2.36+: how the committed merge differs from git's automatic attempt

Continue, abort, repeat

GIT_EDITOR=true git rebase --continue      # non-interactive: keeps the original message
git commit --no-edit                       # finish a merge with the default message
git cherry-pick --continue
git merge --abort                          # back to the start (or rebase/cherry-pick --abort)

For long rebases that hit the same conflict repeatedly, enable rerere so git records and replays resolutions:

git config rerere.enabled true
git rerere diff                  # what rerere recorded for the current conflicts
git rerere forget <path>         # drop a wrong recorded resolution

rerere replays silently; review its auto-resolved files before continuing, and forget any resolution you later find wrong.

Hard rules

  • Never resolve a whole conflicted file wholesale with --ours/--theirs unless you have confirmed the other side’s changes are fully obsolete.
  • Never commit with markers; never use git add . to mark everything resolved without checking each file.
  • Do not force-push the result of a rebase on a shared branch without the user’s confirmation (--force-with-lease --force-if-includes only).
  • If both intents cannot be combined, stop and ask the user. Do not silently drop one.

Verification

  • No conflict markers: the rg search above returns nothing.
  • Build, type check and full test suite pass on the merged result.
  • Lockfile diff contains only expected packages.
  • For each conflicted file, git diff <ours-ref> -- <path> and git diff <theirs-ref> -- <path> show that each side’s change survived.

Report

Resolved 5 conflicts rebasing feature/bulk-pricing onto origin/main:
  src/cart.py         main extracted tier logic to tiers.py; re-applied our single-tier cap there
  src/routes.ts       both added routes; kept both, sorted
  package-lock.json   regenerated with npm install after resolving package.json
  tests/__snapshots__ re-recorded; 1 snapshot changed (new route in sitemap)
  migrations/         added alembic merge revision 7c1e2f
Checks: build OK, tsc clean, 512 tests passed. Not pushed.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Merge Conflict Resolution"
  short_description: "Keep both intents, not just one side's text"
  default_prompt: "$merge-conflict-resolution My rebase onto main stopped with conflicts in five files, resolve them properly"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
New

Introducing Codex Skills Pro

79 professional skills that take Codex through complete engagements, each with its own scripts, references and a report that verifies the result.

All-AccessOne-time payment, no subscription
$49
Get All-AccessOr browse individual skills from $2.99 →

Secure checkout by Creem