Resolve a conflict in a binary file
Git says a binary file conflicts — how do I resolve it?
Short answer
Binary files can't be merged line by line, so Git asks you to choose one version wholesale. Use git checkout --ours or --theirs to pick, then stage it. Mark such files as binary in .gitattributes so Git stops trying to diff them.
git checkout --theirs assets/logo.png
git add assets/logo.png
Take the incoming version of a binary file and mark the conflict resolved
Does this match your situation?
- 'warning: Cannot merge binary files: <file> (HEAD vs. <branch>)'.
- A conflict in a .png, .psd, .fbx, .wav, .pdf or .xlsx file.
- Conflict markers appear inside a binary file and break it.
Step-by-step fix
See which binary files conflict
Filter the status down to unmerged paths so you're dealing with a concrete list rather than a wall of output.
step 1git status --short | grep '^UU\|^AA' git diff --name-only --diff-filter=UShow the PowerShell (Windows) version
PowerShell (Windows)git diff --name-only --diff-filter=ULook at both versions before deciding
Extract each side to a temporary file and open them. For images and audio this is the only sane way to choose, and it takes seconds.
step 2git show :2:assets/logo.png > /tmp/ours.png # your version git show :3:assets/logo.png > /tmp/theirs.png # incoming versionStage 1 is the common ancestor, 2 is yours, 3 is theirs. This numbering is the same for every conflicted file.
Pick a side and stage it
There is no third option for a true binary — one version wins. Staging the file is what marks the conflict resolved.
step 3# keep yours: git checkout --ours assets/logo.png # take theirs: git checkout --theirs assets/logo.png git add assets/logo.png git merge --continueDuring a REBASE the meanings flip: --ours is the branch you're replaying onto, --theirs is your own commit.
Or produce a new version by hand
When both changes genuinely matter, redo them in the source application and stage that result instead. Git is content with any file you stage.
step 4# edit the asset in Photoshop / Audacity / Blender, save over the path, then: git add assets/logo.png git merge --continueStop Git treating them as text in future
Marking a pattern as binary in .gitattributes prevents conflict markers ever being written into these files, and makes diffs report 'binary files differ' instead of garbage.
step 5# .gitattributes *.png binary *.psd binary *.fbx binary *.wav binary *.pdf binary
Why this works
Git's merge algorithm works on lines, and a line is a meaningless unit inside a compressed image or a 3D model — interleaving bytes from two versions produces a corrupt file, not a merged one. So when Git detects binary content it declines to merge and leaves both complete versions in the index at stages 2 and 3, letting you choose. Marking files as binary in .gitattributes makes that behaviour explicit rather than heuristic, which is what stops conflict markers being injected into files that can't survive them.
How to stop it happening again
- Declare binary formats in .gitattributes from the start.
- Use Git LFS for large binaries - it also makes them unmergeable by design, which is correct.
- Split ownership so two people rarely edit the same asset; for art pipelines, locking beats merging.
- Keep editable sources (.psd, .blend) and exported assets in separate commits so conflicts are easier to reason about.
Commands used in this guide
git checkoutThe old all-in-one: switch branches, restore files, or detach HEAD.
.gitattributesPer-path rules for line endings, diffing, merging and export.
git mergeCombine another branch's history into the current one.
git lfsStore large binary files outside history and keep the repo small.
git showDisplay a single commit, tag or file-at-a-commit in full.
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
Can Git merge binary files?
No. Merging works by combining line-level changes, which is meaningless for compressed or structured binary formats. Git keeps both complete versions and asks you to choose one, or to supply a new file you've produced yourself.
What do --ours and --theirs mean during a conflict?
--ours is the version from the branch you're currently on and --theirs is the incoming one. During a rebase the sides are reversed, because your commits are being replayed on top of the other branch - check with git status if you're unsure.
How do I see both versions of a conflicted binary file?
git show :2:path extracts your version and git show :3:path extracts theirs (:1: is the common ancestor). Write them to temporary files and open them in the appropriate application to compare.
Related rescue guides
Two people edited the same Unity scene — how do I merge it without losing work?
Unity scenes and prefabs are YAML, so they can be merged — but only if Force Text serialization is on and you've registered Unity's own UnityYAMLMerge tool with Git. Without that setup Git mangles them, and the only safe resolution is to pick one side entirely.
Read the fix →Always fixableGit says I have merge conflicts — how do I fix them?
Git pauses and marks the clashing sections with <<<<<<<, ======= and >>>>>>>. Edit each file to the version you actually want, delete the markers, git add the file, then git merge --continue. If it gets overwhelming, git merge --abort returns you to exactly where you started.
Read the fix →Always fixableI committed a large file and my push is rejected — how do I remove it?
If it's still the last commit, git reset --soft HEAD~1 and re-commit without it. If it's further back, purge it from history with git filter-repo --strip-blobs-bigger-than. Going forward, route large binaries through Git LFS.
Read the fix →Always fixablegit status says every file changed but I didn't touch them — how do I fix line endings?
Windows writes CRLF and Unix writes LF, and without a policy Git records whichever your editor produced. Commit a .gitattributes with `* text=auto`, then renormalise the repository once — this fixes it for everyone, unlike the per-machine core.autocrlf setting.
Read the fix →