Advent Day 14: gitattributes for Binary Files

December 14, 2018

This is day 14 of my Git Tips and Tricks Advent Calendar. If you want to see the whole list of tips as they're published, see the index.

Earlier this month, I talked about using .gitattributes to handle text files. And I talked about using Git LFS for large files.

But what if you have small binary files that aren't so large that they warrant using Git LFS, and you want to keep them in the repository?

In that case, you should still set attributes for those files. If you have some small binary file named binary.dat then you should give it the binary attribute. Your .gitattributes file will look like:

binary.dat binary

The binary attribute is actually a shorthand for several other attributes: -text -diff -merge. So:

  • -text turns off any text translations for end-of-line conversion. Can you imagine turning every occurrence of byte 0x0a into an occurrence of 0x0d 0x0a on a Windows computer because it thought that was an end-of-line? Instant corruption! -text ensures that doesn't happen.

  • -diff turns off diff'ing this file. If you try to run git diff against a different commit and your binary file was changed, Git will not show you these changes, instead simply telling you:

    diff --git a/binary.dat b/binary.dat
    index 9edd229..36813fa 100644
    Binary files a/binary.dat and b/binary.dat differ

    This avoids you seeing a bunch of binary garbage in your terminal output.

  • -merge disables any attempts to automerge this file. Without this, if two branches change the same binary file, it will try to automerge the file and add conflict markers all over it. So you'll have those annoying arrows (<<<<<<<<<<) all over the file in your working directory which is certainly not helpful.

    Instead, -merge will just mark the file as conflicted and not try to do anything in the working directory; you'll be on your own to sort out the problem.

Although Git is pretty good about detecting whether a file is binary or not, it's not perfect. Explicitly marking binary files with the binary attribute will ensure that you never accidentally corrupt a binary with line ending conversion or merge conflict markers.