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 addmeans on a conflicted file - Use
--oursand--theirscorrectly, 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.
- Look —
git status, to see every conflicted file - Decide — open each file, choose the correct content, delete all markers
- Verify — run something that proves the file is valid
- Mark resolved —
git add <file> - Finish —
git 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 statusshows exactly which files still need a decision- Four valid resolutions: keep yours, keep theirs, keep both, or write something new
--ours/--theirstake an entire file from one side — precise but bluntgit addon a conflicted file means "resolved", not "stage my edit"- Always run
git diff --checkand something that proves the file works before committing - Say in the merge message what you decided and why