Introduction
Git cannot automatically merge binary files like images, PDFs, or compiled binaries because it cannot determine line-by-line differences. When two branches modify the same binary file, Git requires manual intervention to resolve which version to keep.
Symptoms
git statusshows "Unmerged paths" with binary filesgit mergeoutput: "warning: Cannot merge binary files: path/to/file.png"- File shows as "Both modified" or "Both added"
- Diff tools cannot show meaningful differences
CONFLICT (content): Merge conflict in file.bin- Repository contains large binary files (should use Git LFS)
Common Causes
- Two designers modify the same image/asset
- Compiled binaries checked into version control
- Generated PDFs or documents on different branches
- Database files or cache files tracked by Git
- Large media files without Git LFS
- Merge branches with different asset versions
Step-by-Step Fix
- 1.Check merge status:
- 2.```bash
- 3.git status
- 4.# Shows: both modified: assets/logo.png
- 5.
` - 6.For binary files, choose which version to keep:
Keep your branch's version (ours):
``bash
git checkout --ours path/to/binary.file
git add path/to/binary.file
Keep their branch's version (theirs):
``bash
git checkout --theirs path/to/binary.file
git add path/to/binary.file
- 1.Use merge tool for complex conflicts:
- 2.```bash
- 3.# Configure external diff tool for binaries
- 4.git config merge.tool opendiff
- 5.git mergetool
- 6.
` - 7.Mark as resolved after choosing:
- 8.```bash
- 9.git add path/to/binary.file
- 10.git commit -m "Merge branch 'feature' - kept version X of binary files"
- 11.
` - 12.For multiple binary conflicts, use batch resolution:
- 13.```bash
- 14.# Accept all ours
- 15.git checkout --ours .
- 16.git add -A
- 17.git commit -m "Merge - accepted all our binary versions"
# Or accept all theirs git checkout --theirs . git add -A git commit -m "Merge - accepted all their binary versions" ```
- 1.Set up merge drivers for specific file types in
.gitattributes: - 2.
` - 3.# Mark as binary and never auto-merge
- 4.*.png binary
- 5.*.jpg binary
- 6.*.pdf binary
# Use union merge for specific files *.lock binary merge=union
# Use custom merge driver *.docx merge=docx-merge ```
- 1.**Configure merge driver in
.git/config**: - 2.```bash
- 3.git config --local merge.docx-merge.driver "docx-merge %O %A %B"
- 4.
` - 5.If repository has large binaries, migrate to Git LFS:
- 6.```bash
- 7.# Install Git LFS
- 8.git lfs install
# Track file types git lfs track "*.psd" git lfs track "*.png" git lfs track "*.jpg" git lfs track "*.pdf" git lfs track "*.zip"
# Add .gitattributes git add .gitattributes git commit -m "Add Git LFS tracking"
# Migrate existing files git lfs migrate import --include="*.psd,*.png,*.jpg" ```
- 1.For compiled binaries, don't track in Git:
- 2.```bash
- 3.# Add to .gitignore
- 4.echo "dist/" >> .gitignore
- 5.echo "build/" >> .gitignore
- 6.echo "*.exe" >> .gitignore
- 7.echo "*.dll" >> .gitignore
- 8.echo "*.so" >> .gitignore
# Remove already tracked binaries git rm --cached dist/ git commit -m "Remove compiled binaries from Git" ```
- 1.Use union merge for lock files:
- 2.
` - 3.# In .gitattributes
- 4.package-lock.json merge=union
- 5.yarn.lock merge=union
- 6.composer.lock merge=union
- 7.
`
Prevention
- Use Git LFS for all binary assets (>100KB)
- Don't commit compiled/generated files to Git
- Store design assets in DAM (Digital Asset Management) when possible
- Use semantic versioning for asset files
- Branch naming conventions to indicate asset changes
- Regular communication between designers/developers
- Use
git diff --checkbefore committing - Configure pre-commit hooks to prevent large binary commits
Git LFS Best Practices
- Set up LFS at project start, not after binaries are tracked
- Use
git lfs ls-filesto verify LFS tracking - Configure LFS batch size for better performance
- Use
GIT_LFS_SKIP_SMUDGE=1to skip LFS downloads when not needed - Regular
git lfs pruneto clean old objects - Monitor LFS storage quotas and costs