我知道Git会自动检测一个文件是二进制文件还是文本文件,如果需要的话,可以使用.gitattributes
来手动设置。但是,是否也有办法询问Git如何处理文件呢?
假设我有一个Git仓库,里面有两个文件:一个包含纯文本的ascii.dat
文件和一个包含随机二进制内容的binary.dat
文件。Git将第一个.dat
文件作为文本文件处理,将第二个文件作为二进制文件处理。现在我想编写一个Git web前端,它有一个文本文件查看器和一个二进制文件查看器(例如显示十六进制转储)当然,我可以实现自己的文本/二进制检查,但如果查看器依赖于Git如何处理这些文件的信息,那么它会更有用。
那么我怎样才能问Git它是把一个文件当作文本文件还是二进制文件呢?
9条答案
按热度按时间tv6aics11#
builtin_diff()
1调用diff_filespec_is_binary()
,diff_filespec_is_binary()
调用buffer_is_binary()
,buffer_is_binary()
检查前8000个字节(或整个长度,如果更短)中是否出现零字节(NUL“字符”)。我没有看到这个“它是二进制的吗?”测试在任何命令中显式地暴露。
git merge-file
直接使用buffer_is_binary()
,因此您可以使用它:当给定一个二进制文件时,它似乎会产生类似
error: Cannot merge binary files: file-to-test
的错误消息,并产生255的退出状态。不过,我不确定我是否愿意依赖这种行为。也许
git diff --numstat
更可靠:对于二进制文件,
--numstat
的输出应该以-
TAB-
TAB开头,所以我们只对此进行测试。1
builtin_diff()
有像Binary files %s and %s differ
这样的字符串,应该很熟悉。cbeh67ev2#
将返回被git解释为文本文件的文件名。
这里的诀窍在于这两个git grep parameters:
-I
:与二进制文件中的模式不匹配。-e .
:正则表达式匹配文件中的任何字符您可以使用通配符,例如
5f0d552i3#
我不喜欢这个答案,但是你可以解析git-diff-tree的输出,看看它是否是二进制的。
而不是:
哦,顺便说一句,4 b825 d...是一个魔法SHA,它代表空树(它 * 是 * 空树的SHA,但是git特别注意这个魔法)。
of1yzvn44#
来源:https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt---eolhttps://github.com/git/git/commit/a7630bd4274a0dff7cff8b92de3d3f064e321359
哦对了设置
.gitattributes
文本属性时要小心,例如*.abc text
。因为在这种情况下,* 所有 * 包含*.abc
的文件都将被规范化,即使它们是二进制文件(在二进制文件中找到的内部CRLF将被规范化为LF)。这与自动行为不同。wgmfuz8q5#
使用
git check-attr --all
。无论文件是否已暂存/提交,此操作都有效。
在git版本2.30.2上测试。
假设您在
.gitattributes
中有这个。有这样的输出。
对于普通文件,没有输出。
qjp7pelc6#
@bonh在评论中给出了工作答案
git差异--编号统计信息4 b825 dc 642 cb 6 eb 9a 060 e54 bf 8d 69288 fbe 4904标题--|grep“^-”|截止值f3
它显示了所有被git解释为二进制文件的文件。
n3ipq98p7#
冒着因为代码质量差而被打耳光的风险,我列出了一个C实用程序is_binary,它是围绕Git源代码中原始的buffer_is_binary()例程构建的。关于如何构建和运行,请参阅内部注解。
wgx48brx8#
那么我怎样才能问Git它是把一个文件当作文本文件还是二进制文件呢?
不仅
git check-attr --all
是一个不错的选择,而且在Git 2.40(Q1 2023)中,"git check-attr
"(man)学会了使用一个可选的树形结构来读取.gitattributes
文件。这意味着,如果Git将文件视为文本或二进制文件,则可以对任何提交执行Git,而不仅仅是当前的HEAD!
参见commit 47cfc9b、commit c847e8c(2023年1月14日)和Karthik Nayak (
KarthikNayak
)。(由Junio C Hamano --
gitster
--合并至commit 577bff3,2023年1月23日)attr
:添加标记--source
以使用tree-ish签署人:卡蒂克·纳亚克
签署人:图恩·克拉斯
合著人:www.example.comtoon@iotcl.com
.gitattributes
文件的内容可能会随着时间的推移而变化,但是"git check-attr
"(man)总是在工作树和/或索引中检查它们的属性。有选择地允许用户根据路径检查从提交而不是HEAD中获取的属性可能是有益的。
添加一个新的标记
--source
,它允许用户根据提交检查属性(实际上任何树型都可以)。当用户使用这个标志时,我们将遍历
.gitattributes
文件的堆栈,但不是检查当前工作的树和/或索引,而是检查所提供的树型对象中的blob。这允许该命令也可以在空存储库中使用。
因为我们使用了一个类似树的对象,所以用户可以传递"--source HEAD:subdirectory",所有的属性都会被查找,就好像subdirectory是仓库的根目录一样。
我们不能简单地使用没有
--source
标志的<rev>:<path>
语法,类似于在git show
(man)中使用它的方式,因为--
之前的任何非标志参数都被视为属性,而--
之后的任何参数都被视为路径名。更改涉及创建新函数
read_attr_from_blob
,该函数在给定路径的情况下,针对提供的源读取路径的blob,并逐行解析属性。此函数插入到
read_attr()
函数中,我们在其中遍历属性文件堆栈。git check-attr
现在在其手册页中包括:'git check-attr' [--source <tree-ish>] [-a | --all | <attr>...] [--] <pathname>...
x1米20英寸1x
git check-attr
现在在其手册页中包括:--source=<tree-ish>
根据指定的树形结构检查属性。
通常通过命名与之关联的提交、分支或标记来指定源代码树。
w9apscun9#
您可以使用命令行工具“file”实用程序,在Windows上它包含在git安装包中,通常位于C:\Program Files\git\usr\bin文件夹中
查看更多Get encoding of a file in Windows