如何列出git仓库中所有文本(非二进制)文件?

29
我有一个存储库,里面有很多自动生成的源代码文件,我已经在.gitattributes中将它们标记为“二进制”(因为并不是每个人都可以访问生成工具,所以这些文件被检入)。此外,该存储库中还有很多位于被忽略目录中的源文件(同样是生成构建过程的一部分),以及一些实际的二进制文件(例如小型资源文件,如图标)。
现在我想找到存储库中所有非自动生成和非被忽略的文件。我原本以为只需使用find和一堆排除语句就可以了,但现在我的find语句十分糟糕,并且仍然无法完全完成工作。git ls-files可以工作,但会显示所有二进制文件,需要我过滤掉。
所以,我想知道:是否有一个简单的命令可以列出每个已检入存储库的文件,并且 git 认为是“文本”文件?
5个回答

36
git grep --cached -Il ''

列出所有非空的普通文本文件(不包括符号链接):

  • -I:在二进制文件中不匹配模式
  • -l:仅显示匹配的文件名,不显示匹配的行
  • '':空字符串使git grep匹配任何非空文件
  • --cached:还要查找使用git add添加但尚未提交的文件(可选)

或者您可以在git ls-files的for循环中使用如何确定Git将文件处理为二进制还是文本?

TODO 空文件。

要查找所有二进制文件,请参见:在Git HEAD中查找所有二进制文件

使用Git 2.16.1测试了此测试存储库


3
用于通过管道传递给 xargs -0 的选项是 -z - raphinesse

4
一种巧妙的技巧是:列出所有包含回车符的非二进制文件。
$ git grep --cached -I -l -e $'\r'

对于我的情况,使用空字符串效果更好:

$ git grep --cached -I -l -e $''

这段内容摘自如何列出git中的二进制和非二进制文件?


2
$''中不需要$''更具可移植性。 - Ciro Santilli OurBigBook.com

3
你可以使用Git的eol属性来查找非二进制文件。
git ls-files --eol | grep 'i/lf'

这将列出所有使用“LF”行尾的已检入文件。

这有一个优点,即使用了git ls-files命令,因此可以轻松地将其导入到xargs中。它也是一个管道命令,因此可能更快(我没有进行基准测试)。

这可能是使用git grep方法的可行替代方案,因为它在一些人认为的二进制文件方面似乎更加可定制。

请注意,您可以在.gitattributes中指定git应该将哪些文件视为二进制文件。因此,如果您在.gitattributes中添加*.svg binary,则git grep方法将遵守此规则。但eol属性也会遵守,但不适用于在设置属性之前已经检入到索引中的旧文件。但您始终可以添加| grep -v 'attr/-text'来排除在.gitattributes中已被设置为二进制文件的文件。


1
标准的列出未被忽略文件的方法是:
git ls-files --exclude-standard --cached

但是,正如你所看到的,它列出了所有有版本的文件。

一个解决方法是在一个名为“exclude_binaries”的单独文件中定义一个排除模式,以匹配你所知道的所有二进制文件。

git ls-files --exclude-standard --cached \
--exclude-from=/path/to/`exclude_binaries`

那将是一个不那么复杂的find,但它不能提供完全自动化的列出非二进制文件的方式:您仍需在单独的模式文件中标识并列出它们。

0

使用 git ls-filesawk

git ls-files --eol | awk -F '\t' '{if ($0 !~ /^i\/-text/) print $2}'

注意:此解决方案也适用于返回非二进制、空文件。
说明:
  • --eol:显示文件的<eolinfo><eolattr>。参考:https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt---eol
  • awk -F '\t':通过制表符解析并分隔输入行。至少在 git 版本 2.37.2 中,git ls-files --eol 的输出格式显示 4 个“人类可读”列,但仅在第四列之前有制表符。因此,如果我们按制表符分隔,awk 将考虑两列。
  • (awk) if ($0 !~ /^i\/-text/):只有当该行不以 i/-text/ 开头时才匹配。这是我们测试知道该文件不是二进制文件的方法。
  • (awk) print $2:打印第二列,即文件的路径(由 OP 请求)。请注意,此解决方案也适用于包含空格的文件名。

致谢:我的回答是在 @CervEd 的回答基础上进行扩展的(https://dev59.com/YWMk5IYBdhLWcg3wywwU#67346778),同时也参考了 @Quential33 的另一篇回答(https://dev59.com/ym025IYBdhLWcg3wQDhb#66796286)。


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