如何测试git对象的文件类型(ascii、二进制等)?

如何测试git对象的文件类型(ascii、二进制等)?,git,Git,我想从一个baregit存储库中找到给定git分支中所有ascii/text文件,并将它们的总大小相加 由于这是一个裸的repo,因此它没有工作树,只需签出分支并直接测试文件的解决方案就无法工作。这些存储库可能有数百个,总计数百GB,并且对于本任务而言,它们是只读的。这意味着创建工作树不是一个选项,而存储库的大小意味着为每个存储库创建一个副本,并在副本中创建一个工作树是不切实际的 我可以在裸git存储库中列出属于特定分支的所有对象,如下所示: git ls-tree -r master --lo

我想从一个baregit存储库中找到给定git分支中所有ascii/text文件,并将它们的总大小相加

由于这是一个裸的repo,因此它没有工作树,只需签出分支并直接测试文件的解决方案就无法工作。这些存储库可能有数百个,总计数百GB,并且对于本任务而言,它们是只读的。这意味着创建工作树不是一个选项,而存储库的大小意味着为每个存储库创建一个副本,并在副本中创建一个工作树是不切实际的

我可以在裸git存储库中列出属于特定分支的所有对象,如下所示:

git ls-tree -r master --long
这给了我对象哈希:

100644 blob 486a23256c437b811b5647e40517a35964f60dc6      42    file1.txt
100644 blob f7b528c3a1412c12213e56394b679397bd4ecaa7     131    file2.xml
100644 blob 773c90bbb7ab5552d47ce2fb153fc9d18ed0d386    5617    file3.jpg
100644 blob 420cb792e80a97c89db9c9d7339b4fb9a680aa43   13130    file3.zip

在上面的例子中,我只想得到前两个纯文本对象,但我不知道如何测试对象本身的文件类型。

Git本身不区分文本文件和二进制文件。许多前端瓷器工具都有,但内部没有区别。找出哪个是哪个的最好方法是使用一个非基于git的工具,
file
。要获取要发送到
文件的内容
,可以使用
git show
。例如,如果运行
git show 486a23256c437b811b5647e40517a35964f60dc6 | file-
,可能会得到
/dev/stdin:ASCII text
。如果运行git show f7b528c3a1412c12213e56394b679397bd4ecaa7 | file-,可能会得到
/dev/stdin:XML 1.0文档文本

一般来说,
file
试图使任何看起来像纯文本的东西在输出中的某个地方都有
text
这个词,而任何看起来不像文本的东西都没有。更具体地说,
文件的
man
页面显示:

打印的类型通常包含以下内容之一:文本(该文件仅包含打印字符和一些常用控制字符,在ASCII终端上读取可能是安全的)、可执行文件(该文件包含以某种UNIX内核或其他内核可以理解的形式编译程序的结果)或表示任何其他内容的数据(数据通常是“二进制”或不可打印的)。例外情况是已知包含二进制数据的已知文件格式(核心文件、tar存档)


因此,如果您通过管道将
git show
的输出通过
file
,然后在输出中查找
text
,您应该能够确定它是文本还是二进制。

值得注意的是,
file
认为的内容可能与git的猜测不匹配,如果您使用
.gittributes
来告诉git的比特有些文件名或glob模式特别是文本或二进制的,这也不能解释这一点。如果Git有一个管道命令来查询Git对文件类型的猜测(在
Git cat file-p
中的la
--path
--textconv
),可能会更好。如果有这样的事情,我不知道,但我希望有。请参阅Josh Lee的评论和我的回复:
git ls文件--stage
可能很有用;对于裸存储库,您需要
git将树
读入索引(或临时索引,如果您想避免干扰主索引)@DanielH我试着将
git show
管道连接到
文件
,但无法计算
文件
如何从stdin读取-我只需要一个破折号!谢谢。我会测试这个解决方案,并将它与@torek建议的临时树进行比较。是的,添加连字符是让程序从标准目录读取的标准方法;不是如果repo是非裸的,那么这就是
git-ls文件--eol
@JoshLee:如果这在裸存储库(确实有索引!)中起作用的话……而且:它有点起作用!
git-read-tree
,然后是
git-ls文件--eol
。注意:如果您使用索引跟踪部署(
git--worktree=…例如,在post-receive钩子中签出
)您可能想为此使用临时索引。@torek如果我理解正确,
git read tree
会创建一个临时/缓存索引?我正在尝试找出它的存储或写入位置。您似乎可以使用
git read tree--empty
清除它,我只是好奇第一个目录中的信息存储在哪里place@daveruinseverything:“索引是
.git/index
,或者,在一个简单的repo中,只是
index
。您可以使用环境变量
git\u index\u file
设置一个备用文件。如果您使用
git worktree add
创建额外的工作树,它们每个都有自己的
index
(以及其他文件)在
.git/worktrees/
中的目录中,
.git/index
中的目录只是主存储库及其工作树(如果有)的可分辨、主、默认索引。