Great work!

XP to next level

BugEater

The Resolution Algorithm, Step by Step

Learning Objectives

By the end of this lesson you will be able to:

  • Follow a fixed five-step sequence from conflict to completed merge
  • Explain what git add means on a conflicted file
  • Use --ours and --theirs correctly, and know when not to
  • Verify a resolution before committing it

The Algorithm

Memorise this. It does not change, no matter how many files conflict.

  1. Lookgit status, to see every conflicted file
  2. Decide — open each file, choose the correct content, delete all markers
  3. Verify — run something that proves the file is valid
  4. Mark resolvedgit add <file>
  5. Finishgit commit

Repeat steps 2–4 for each file. Step 5 happens once, at the end.

Step 1: Look

git merge dev
Auto-merging config/test-env.yaml
CONFLICT (content): Merge conflict in config/test-env.yaml
Automatic merge failed; fix conflicts and then commit the result.
git status
Unmerged paths:
        both modified:   config/test-env.yaml

Note what this told you: only one file conflicted. Any others in the merge were combined cleanly and are already staged. It is worth taking the ten seconds to see the size of the problem before you start.

Step 2: Decide

Open the file:

timeout: 30
<<<<<<< HEAD
retries: 2
parallel: true
=======
retries: 5
parallel: false
>>>>>>> dev
base_url: https://staging.example.com

You have four honest options, and choosing between them is engineering judgement, not a Git operation:

Keep yours. Delete the incoming half and all three markers.

Keep theirs. Delete your half and all three markers.

Keep both. Sometimes both changes are wanted — two new test cases, two added config keys. Delete only the markers.

Write something new. Frequently the right answer. Neither side is correct on its own:

timeout: 30
retries: 5
parallel: true
base_url: https://staging.example.com

Here the resolution took retries from dev and parallel from main — a combination that exists in neither branch and is what the code actually needs.

If you do not know which is correct, ask. A two-minute message to the person who wrote the other side is vastly cheaper than silently choosing wrong. This is not a failure; picking blind is.

The Shortcut Flags

When a whole file should come from one side:

git checkout --ours config/test-env.yaml      # your branch's whole file
git checkout --theirs config/test-env.yaml    # the incoming branch's whole file
git add config/test-env.yaml

These are all-or-nothing for the entire file, and they discard the other side's changes to that file completely. Use them for generated files you're about to regenerate anyway, or when you are certain one version is wholly correct. Do not use them to make a conflict go away quickly.

Remember which is which: during a merge, --ours is the branch you are standing on. During a rebase, that inverts, exactly as the markers do.

Step 3: Verify

Never skip this. It is two commands and it catches the mistake everyone eventually makes.

git diff --check

Reports any leftover conflict marker. Silence is good news.

Then prove the file still works:

python -c "import yaml,sys; yaml.safe_load(open('config/test-env.yaml'))"   # YAML valid?
npx eslint tests/auth/login.spec.js                                          # JS parses?
npm test -- tests/auth                                                       # tests still pass?

Whatever your project uses. A resolution that produces a syntactically valid but semantically wrong file is the worst outcome of a merge, and only running something catches it.

Step 4: Mark Resolved

git add config/test-env.yaml

This is the step people misunderstand. On a conflicted file, git add does not mean "stage my edit". It means "I have resolved this conflict; this file's content is now correct." It is how you tell Git the decision is made, and it is what removes the file from the Unmerged paths list.

Check that the list is now empty:

git status
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Step 5: Finish

git commit

Git opens an editor with a pre-filled message:

Merge branch 'dev' into main

# Conflicts:
#       config/test-env.yaml

Accept it, or better, add one line saying what you decided:

Merge branch 'dev' into main

Resolved test-env.yaml: kept retries=5 from dev, parallel=true from main.

Six months from now, when someone runs git blame on that line and lands on this commit, that sentence is the difference between an answer and a mystery.

Pro Tip: Resolve one file completely — decide, verify, git add — before opening the next. Half-resolving three files at once is how markers get left behind.

Key Takeaways

  • The sequence never changes: look, decide, verify, git add, git commit
  • git status shows exactly which files still need a decision
  • Four valid resolutions: keep yours, keep theirs, keep both, or write something new
  • --ours / --theirs take an entire file from one side — precise but blunt
  • git add on a conflicted file means "resolved", not "stage my edit"
  • Always run git diff --check and something that proves the file works before committing
  • Say in the merge message what you decided and why

Quiz

What does git add config/test-env.yaml mean on a conflicted file?

Which is the correct order of the resolution algorithm?

The conflict is in a config file and you genuinely don't know which value is correct. What should you do?

git checkout --theirs config/test-env.yaml during a merge does what?