覆盖git对二进制文件的选择,将其转换为文本

75

我看到有几个问题问如何让 git 将文本文件视为二进制文件,但还没有看到相反的问题:

我该如何改变 git 将文本文件视为二进制文件的选择?我有一个文本文件,在一些配置字符串中使用 EOT 和 ETX 分隔配置参数的不同部分。

例如,源代码包含像这样的行:

INPUT 'ScrollRemote[EOT]no[ETX]NumDown[EOT]0[ETX]CalcWidth[EOT]no[ETX]MaxWidth[EOT]80[ETX]FetchOnReposToEnd[EOT]yes[ETX].....'

我希望这个文件被视为文本,而不是二进制文件,以便我可以查看行更改的差异。


2
Git应该可以很好地处理这个问题。大多数Git的基础操作并不关心“文本”和“二进制”之间的区别,因为它们都被视为字节序列。你实际上遇到了什么问题? - Greg Hewgill
6
如果我没记错的话,对于二进制文件的更改会导致整个新副本被存储,而对于文本文件的更改则会以差异方式存储。这个特定的文件是一个文本文件(源代码),其中有像上面一行的几行内容。将其视为二进制文件会使我失去查看源代码差异的能力... - RonaldB
2
Git存储算法并不关心文件是被视为“文本”还是“二进制”,它只是在仓库中存储字节。欲知详情,请查看我的答案。 - Greg Hewgill
3个回答

89
Git仓库内部实际存储文件的方式与其在显示时如何被处理无关。 因此,当git diff程序被要求比较两个文件时,它首先从存储库中获取两个完整的文件,然后对它们运行差异算法。 通常,git diff会查找文件中的非打印字符,并且如果文件看起来可能是二进制文件,则拒绝显示差异。这样做的理由是二进制文件差异不太可能被人类读取,如果显示出来很可能会搞乱你的终端。但是,您可以使用--text选项指示git diff始终将文件视为文本。您可以针对一个diff命令指定此选项:
git diff --text HEAD HEAD^ file.txt

您可以通过设置包含以下内容的.gitattributes文件来使Git始终使用此选项:

file.txt diff

这里的diff属性表示:
当设置了diff属性的路径被处理时,它们会被视为文本,即使它们包含通常不会出现在文本文件中的字节值,如NUL。

12
这对合并操作无效。设置“merge”属性似乎也不起作用。 - Lars Brinkhoff

6

请查看Git属性 -- 他们可以通过指定某个文件扩展名被视为文本来帮助您。


所以,如果我正确理解了属性,我可以使用它来定义如何显示二进制文件的两个版本之间的差异。Git仍然会像处理二进制文件一样对待每个版本,并将它们完整地存储,对吗? - RonaldB
Git属性的完整文档在此处: | https://git-scm.com/docs/gitattributes - romaroma
1
Git总是将每个文件视为二进制文件并将它们完整地存储--它没有像其他版本控制系统那样的特殊文本文件模式。它处理二进制文件和文本文件的差异只在使用顶层“瓷器”命令git showgit diff时才会出现--对于文本文件,它会找出行结束符并根据行显示差异。但在内部,每个文件都被存储为整个二进制文件,并与存储库中的其他数据进行精心压缩,以最小化跨修订版本的浪费空间。 - Slipp D. Thompson
@SlippD.Thompson 尽管存储本身可能会将它们视为相同,但在存储之前进行自动换行转换等功能在两者之间并不相同,对吗? - endolith

3
如果您尝试比较或合并文本文件,而git说它们是二进制文件,则它们可能只是具有不同的编码(例如UTF-8和ANSI)。请参见我在此帖子上提供的答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接