agentleFS
alexgrebeshok-coderalexgrebeshok-coder/dirigent-skills/skills/merge-conflict-resolution/SKILL.md

merge-conflict-resolution

Skill0 starsChanged 4 months agoMITView on GitHub

Use when resolving git merge/rebase/cherry-pick conflicts — especially resolving "all in favor of one side", resolving with a script or bulk command, or resolving multiple conflict blocks in one file. Also use before committing any conflict resolution, and when reviewing a merge someone (or some agent) claims is done. Triggers — "разреши конфликт", merge conflict markers, checkout --theirs/--ours, "возьми вариант ветки X".

4 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

4 rules. 0 are common, 2 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    All green, data lost. This exact sequence shipped a deleted "critical security notice" line in a 17-second baseline test, and lost README …

    line 23
  2. Very specific:

    Keep the pre-resolution file: cp file file.conflicted before touching it.

    line 37
  3. Distinctive:

    Only after all three: git add + commit.

    line 53
  4. Very specific:

    No pre-resolution copy and no checkout -m recovery before verifying

    line 90

“Common” is measured: kept by at least 6 in 10 of the 4 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

merge-conflict-resolution — resolve blocks, never replace files

Overview

A merge conflict file has THREE kinds of content: conflict blocks (both sides shown), auto-merged lines git already combined for you, and untouched context. Every data-loss incident in this class comes from treating the file as two-kinds: a resolver that replaces the whole file, or a script that eats the lines between blocks.

Core rule: resolve conflict BLOCKS. Anything that replaces the FILE destroys auto-merged work — silently, with a clean git status.

The trap that passes every naive check

git checkout --theirs <file> does NOT mean "take their side of the conflicts". It replaces the whole file with their version — every line the other side added outside the conflicts is gone. Then:

  • git status — clean ✓ (loss is staged, status can't see it)
  • git diff --check — no markers ✓
  • git log --graph — proper merge commit, two parents ✓

All green, data lost. This exact sequence shipped a deleted "critical security notice" line in a 17-second baseline test, and lost README lines twice in production.

Doing it right

IntentCorrect tool
All conflicts in favor of one side, merge not started yetgit merge -X theirs <branch> (block-level; keeps auto-merged lines)
All conflicts one side, conflict already openRe-do properly: git merge --abort && git merge -X theirs <branch>. Or edit only the blocks.
Mixed choices per blockEdit each block (by hand or state-machine script), never whole-file commands
Whole file genuinely from one side (binary, generated)git checkout --theirs — the ONLY case it's correct; say so in the commit message

Script rules (if you automate block editing):

  • Process line-by-line with a state machine (<<<<<<< opens, >>>>>>> closes). Never a regex spanning from <<<<<<< to >>>>>>> — greedy or multiline matching eats everything between two blocks. This is the production bug this skill exists for.
  • Fail fast on anything unmapped (unknown section, nested markers) — crash beats guess.
  • Keep the pre-resolution file: cp file file.conflicted before touching it.

Verify before commit — three checks, all mandatory

# 1. No markers anywhere in the repo (not just the file you edited)
git -C "$R" diff --check && git -C "$R" grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ; # grep must find nothing

# 2. NO LINE OUTSIDE CONFLICT BLOCKS WAS LOST — the check that catches --theirs and greedy regex
awk '/^<<<<<<</{c=1} /^>>>>>>>/{c=0;next} !c' file.conflicted > /tmp/outside
grep -Fxvf <resolved-file> /tmp/outside   # must print NOTHING; every printed line was eaten
# (file.conflicted is the copy you kept; recover one with `git checkout -m <file>` if you didn't)

# 3. Each block resolved to the INTENDED side — grep the distinctive line of each choice

Only after all three: git add + commit. If you resolved during a review/приёмка of someone else's merge — run the same three checks on their result; a clean status is not evidence.

Acceptance merges — merging someone's finished branch

Same discipline, different trap: here nothing conflicts, so nothing feels dangerous. Two real incidents in one:

Pre-flight (before any merge command):

git -C "$R" status --short          # whose tree is this? CLEAN? In multi-agent setups the
                                    # checkout may belong to a LIVE agent mid-task — uncommitted
                                    # files here mean STOP, not stash.
git -C "$R" branch --show-current   # you merge INTO where HEAD points. If it's not the target
                                    # branch, checkout first — a merge "into main" executed on
                                    # someone's work-branch lands there silently and looks fine.

Post-push (after any push):

git -C "$R" ls-remote origin <target-branch>   # compare to local SHA yourself

The push command's own output is not evidence: Everything up-to-date prints on a no-op push (wrong branch pushed = nothing rejected, nothing transferred, success-looking output, remote unchanged). Report the ls-remote SHA, not the push output.

Rationalizations — heard in real incidents

ExcuseReality
"checkout --theirs = take theirs in the conflicts"It takes theirs for the FILE. Auto-merged lines from the other side die.
"git status is clean, работа сдана"Status sees staged-ness, not meaning. The loss is inside what you staged.
"Merge commit has two parents, graph is correct"Graph proves ancestry, not content.
"It's mechanical, one-two commands, 13 more repos waiting"The 17-second version of this job deleted a security notice. Check #2 costs 5 seconds.
"My resolver script printed 'resolved 3 blocks'"It resolved what it matched. Verify what it didn't match survived.

Red flags — STOP

  • Typing checkout --ours/--theirs on a text file while auto-merged changes exist
  • A conflict-parsing regex with [\s\S]*? or multiline mode across markers
  • Declaring a merge done having checked only git status / git log
  • No pre-resolution copy and no checkout -m recovery before verifying
  • Accepting an executor's merge because their report says "conflicts resolved"
  • Typing a merge command without knowing what branch --show-current says
  • Reporting a push as done based on the push command's output instead of ls-remote

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.