Git 对于 *.reg 文件显示“二进制文件 a... 和 b... 不同”

问题描述 投票:0回答:5

有没有办法强制 Git 将

.reg
文件视为文本?我正在使用 Git 来跟踪我的 Windows 注册表调整,Windows 对这些文件使用
.reg

更新1:我让它运行差异(谢谢,安德鲁)。然而,现在看起来像下面这样。这是编码问题吗?

index 0080fe3..fc51807 100644
--- a/Install On Rebuild/4. Registry Tweaks.reg
+++ b/Install On Rebuild/4. Registry Tweaks.reg
@@ -1,49 +1,48 @@
-<FF><FE>W^@i^@n^@d^@o^@w^@s^@ ^@R^@e^@g^@i^@s^@t^@r^@y^@ ^@E^@d^@i^@t^@o^@r^@
-^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;^@;
-^@^M^@
...

有什么想法吗?

更新2:感谢所有提供帮助的人:这就是我最后所做的:创建文件

.gitattributes
,内容为
*.reg text diff
,然后我将文件转换为UTF-8,因为UTF-16对于差异很奇怪。我没有使用任何外来字符,所以 UTF-8 对我有用。

windows git registry
5个回答
12
投票

要告诉 git 显式比较文件类型,请将以下内容放入存储库根目录中的

.gitattributes
文件中:

*.reg diff

4
投票

快速解答

正如其他人指出的那样,此问题是由编码混淆引起的。您有两个选择:

  • 通过相应地重新保存将文件编码更改为 UTF-8。

  • 创建一个

    .gitattributes
    文件,并包含以下内容:

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

原因

默认情况下,从 Windows 注册表编辑器导出的注册表以特定的 UTF-16 编码保存。 在底层,Git 仅支持 UTF-8 及其超集,因此当 Git 看到 UTF-16 编码文件时,它会看到许多意外的非字符字节并将其解释为二进制文件。

通过设置

*.reg diff
属性来要求 Git 将文件视为文本是行不通的,因为 Git 仍然认为错误的编码。这就是为什么你看到所有这些
^@
字符。

解决方案

其他人建议的一种解决方案是将 UTF-16 文件另存为 UTF-8,这完全有效!但它确实有一个很大的缺点:如果您有很多 .reg 文件,或者您想从注册表编辑器重新导出密钥,则每次都必须使用正确的编码重新保存它。

或者,您可以通过

working-tree-encoding
属性告诉 Git 您计划使用哪种编码。指定此选项后,Git 会将文本文件在提交到存储库时将其转换为 UTF-8,然后在签出时将其转换回原始编码。这样,当文件出现在工作目录中时,它始终具有原始编码。如果您熟悉行尾标准化,其行为与此类似。

如果您选择这条路线,需要注意一些陷阱:

  1. 该属性相对较新(2018 年 3 月),因此如果您支持广泛的 Git 实现或版本,它可能会导致麻烦。
  2. 如果您要处理的不仅仅是小型 UTF-16 文件,编码转换可能会减慢速度,或者根据编码的不同,可能无法使往返过程毫发无伤。

出于这些原因,文档建议仅当文件无法有效地存储为 UTF-8 时才使用此属性,但根据您的使用情况,这些陷阱可能与您无关。 最后,在使用此属性时,还必须指定使用哪些行尾字符以避免歧义。这是通过

eol
属性完成的。

将它们放在一起,我建议您尝试在存储库的根目录中创建一个

.gitattributes
文件,并包含以下行:

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


4
投票

Git 将您的注册表导出文件视为二进制文件,因为它们具有 NUL。没有好的方法来区分或合并general二进制文件。一个字节的更改可以更改文件其余部分的解释。

处理二进制文件有两种通用方法:

  1. 接受它们是二元的。差异不会有任何意义,所以不要要求它们。永远不要合并它们,这意味着只允许在一个分支上进行更改。在这种情况下,可以通过将每个调整(或一组相关调整放在单独的文件中)来简化此操作,这样一个文件中发生差异的可能性就会减少。

  2. 将更改存储为文本,然后转换/反转换为这些二进制形式。

即使这些“文本”文件,UTF-16 编码也包含 NUL。然而似乎没有非 ASCII 位。你能将它们转换为 ASCII(或 UTF-8,如果没有扩展字符,则为 ASCII)吗?


2
投票

通过在记事本中打开每个 .reg 文件并将其另存为 Encoding UTF-8,将 .reg 文件从 utf16 转换为 utf8。


2
投票

创建一个 utf16toascii.py:

#!/usr/bin/env python3
import sys
data = open(sys.argv[-1]).read()
ascii = data.decode('utf-16').encode('ascii', 'replace')
sys.stdout.write(ascii)

然后在 bash 中执行:

$ echo "*.reg diff=utf16strings" >> .gitattributes
$ git config --global diff.utf16strings.textconv /path/to/utf16toascii.py

您可以比较注册表文件、Xcode .strings 文件或任何其他 utf-16 文件。

© www.soinside.com 2019 - 2024. All rights reserved.