Git says "Binary files a... and b... differ" on for *.reg files

To tell git to explicitly diff a filetype, put the following in a .gitattributes file in your repository’s root directory:

*.reg diff

Quick Answer

As others have pointed out, this issue is caused by an encoding mix up. You have two options:

  • Change the file encoding to UTF-8 by re-saving it accordingly.

  • Create a .gitattributes file, and include the following:

    *.reg working-tree-encoding=UTF-16LE-BOM eol=CRLF

Cause

By default, registry exports from the Windows Registry Editor are saved in a particular UTF-16 encoding. Under the hood, Git only supports UTF-8 and its supersets, so when Git sees a UTF-16 encoded file, it sees a lot of unexpected non-character bytes and interprets that as a binary file.

Asking Git to treat the file as text by setting a *.reg diff attribute doesn't work because Git is still expecting the wrong encoding. That's why you saw all of those ^@ characters.

Solutions

One solution that others have suggested is to save the UTF-16 files as UTF-8 and that totally works! It does have one big disadvantage though: if you have a lot of .reg files, or you want to re-export a key from the Registry Editor, you'll have to re-save it with the correct encoding every time.

Alternatively, you can tell Git what encoding you plan to use with the working-tree-encoding attribute. When this is specified, Git will convert a text file to UTF-8 as it is committed to the repository, and then convert it back to the original encoding as it gets checked out. That way, the file always has the original encoding when it appears in your working directory. If you're familiar with end-of-line normalization, the behavior is similar to that.

If you take this route, there are a few pitfalls to be aware of:

  1. The attribute is relatively new (March 2018), so if you're supporting wide Git implementations or versions, it could cause trouble.
  2. If you're going beyond small UTF-16 files, encoding conversion could slow things down or, depending on the encoding, not make the round-trip unscathed.

For these reasons, the documentation recommends to only use this attribute if the file cannot be stored usefully as UTF-8, but depending on your use case these pitfalls may not concern you. Finally, when using this attribute it's important to also specify what end-of-line characters are in use to avoid ambiguity. That's done with the eol attribute.

Putting it all together, I recommend you try creating a .gitattributes file in your repository's root, and including the following line:

*.reg working-tree-encoding=UTF-16LE-BOM eol=CRLF