51

In order to diff binary files in git, I assume I need to set up a difftool.

What difftools work? How do you put the parameters in?

1
  • What kind of output are you expecting to get from a diff tool of a binary file? What kind of binary file is this? Is it something that can be rendered to a text format and then compared? – Zoredache Jan 24 '14 at 1:04
34

You can set a textconv config option for a filetype. See "Performing text diffs of binary files" in gitattributes(5). What you should use depends on the filetype.

Example 1:

Say you want to diff the contents of zip files. In that case you should put in one of the following files $XDG_CONFIG_HOME/git/config or $HOME/.gitconfig or $GIT_DIR/config .

[diff "zip"]
    textconv = unzip -v

Next time you ask for a diff on a zip file in a repo, it will call unzip -v on both version and diff the resulting text.

Example 2:

For pdf files you could use e.g. pdfinfo;

[diff "pdf"]
    textconv = pdfinfo

Example 3:

If there is no specific infomation utility for a filetype, you could e.g. use hexdump (comes with FreeBSD and OSX, also available on Linux):

[diff "bin"]
    textconv = hexdump -v -C
13
  • I could diff it in hex. I'd be happy enough just knowing how many bytes are different, or at what positions the bytes differ. I ended up using Hex Fiend by cloning my git repository so I could check out both versions of the file, because I couldn't figure out how to get git to launch the program. – Nick Retallack Jan 25 '14 at 6:09
  • 2
    I added Example 3 to my git config, but when I do "git diff" it still just gives me the same short message: "Binary files a/file and b/file differ" – Nick Retallack Jan 31 '14 at 18:25
  • 1
    If you want to use libmagic, you'll have to look into the git source code to see if that works... – Roland Smith Feb 8 '14 at 20:50
  • 10
    I finally got this to work, after adding *.bin diff=bin to my .gitattributes – Justin Rowe Jan 7 '15 at 13:09
  • 1
    @nilskp You need to both define a diff in your .gitconfig file and assign that attribute to a path in .gitattributes. – Roland Smith Nov 20 '16 at 10:53
32

If you want to force git to show binary files diff as a plain text diff use --text option like so:

git diff --text
1
  • I love this answer because it's so simple and quick! One thing that I'm noticing is that it seemingly doesn't work for a merge conflict. If anyone knows how to get that to work, I think that would be a great addition. – paulkernfeld Jan 12 at 19:04
23

The answer from Roland Smith was helpful but is currently incomplete (see the comments) - there are two parts to this.

You can define a new diff commands in your repository's .git/config file or your personal global $XDG_CONFIG_HOME/git/config/.gitconfig (usually $HOME/.gitconfig) file, for example a hex diff command using hexdump:

[diff "hex"]
    textconv = hexdump -v -C
    binary = true

Next, you need to use the repository's .gitattributes file to tell git which files should be used with this special diff command:

# Binary files (no line-ending conversions), diff using hexdump
*.bin binary diff=hex

Like the .gitignore file, the .gitattributes file should be checked into your repository.

In my case I have several different file extensions which I want to treat as binary (e.g. avoid any line ending conversions if using git on Windows), and also see any differences via hexdump:

https://github.com/peterjc/galaxy_blast/commit/5ec4695e6c3da3926fb100ca006f0f3e88c53c3d

See also https://github.com/resin-io/etcher/pull/1367 for another example defining a hexdump diff command for use with image files.

1
  • 4
    You can set the .gitattributes globally as well (to go along with the [diff] entries in your global .gitconfig). If you make the .gitattributes local to the repo, then the user will have to modify his local .gitconfig repo settings because for security reasons those will not be pushed to the remote. Either way, each user has to update their local files/config somehow to enable this behavior. In .gitconfig under [core] add attributesfile = c:/users/<username>/.gitattributes or wherever you want to store it if you make it global (note the forwardslashes, even in windows). – LightCC Nov 1 '19 at 20:40
4

To create a binary patch, a patch that works for binaries instead of just saying "Binary files differ", use

git diff --binary file1 file2

This produces a "GIT binary patch" using only ASCII characters (unlike --text), suitable for emailing.

-1

The above are comprehensive ways to do so.. however, if you just need to do it for a few files, the following method is what I use:

git checkout HEAD -- /path/to/file > ~/file
vimdiff ~/file /path/to/file

Here I am using vimdiff but you can use any other tool. The above can be also combined into a small script if you need to do this over and over again.

1
  • This appears to have discarded the changes to my file (and created an empty file where I wanted the committed version to be). – Erhannis Dec 6 '18 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.