我有一个巨大的git repo,最终想用bfg清理。
但首先,我想跟踪并删除HEAD
中的文件,git将其视为二进制文件...
所以,我正在寻找的是一个命令来查找HEAD中git视为二进制文件的所有文件。
这些没有帮助:
预先感谢您的帮助。
diff <(git grep -Ic '') <(git grep -c '') | grep '^>' | cut -d : -f 1 | cut -d ' ' -f 2-
打破它:
git grep -c ''
打印存储库中每个文件的名称和行数。添加-I
选项使命令忽略二进制文件。diff <(cmd1) <(cmd2)
使用过程替换为diff
提供命名管道,通过该管道发送cmd1
和cmd2
的输出。grep
和cut
命令用于从diff
的输出中提取文件名。基于@jangler(https://stackoverflow.com/a/30690662/808101)答案的简化解决方案
comm -13 <(git grep -Il '' | sort -u) <(git grep -al '' | sort -u)
说明:
git grep
-l
要求只打印匹配模式''
的文件名(应与每个文件的每一行匹配)
-I
此选项使命令忽略二进制文件
-a
此选项强制处理二进制文件,就像它们是文本一样sort -u
对grep的结果进行排序,因为comm
只处理已排序的文件comm -13
列出第二个列表唯一的文件(git grep
列表包含所有文件,包括二进制文件)以下是使用PowerShell的Windows的相同脚本:
$textFiles = git grep -Il .
$allFiles = git ls-files
foreach ($line in $allFiles){
if ($textFiles -notcontains $line) {
$line;
}
}
或者是简短的形式:
$textFiles = git grep -Il .
git ls-files | where { $textFiles -notcontains $_ }
这需要O(n^2)
来完成,这是使用哈希表的更快方法:
$files = @{}
git ls-files | foreach { $files[$_] = 1 }
git grep -Il . | foreach { $files[$_] = 0 }
$files.GetEnumerator() | where Value -EQ 1 | sort Name | select -ExpandProperty Name
这需要O(n)
完成。
grep -Fvxf <(git grep -Il '') <(git grep -al '')
说明:
git grep -Il ''
:列出git认为是文本的所有非空常规文件。另见:How to list all text (non-binary) files in a git repository?git grep -al ''
:列出所有非空的常规文件,包括二进制文件grep -Fvxf
:从文件2中选择未出现在文件1中的行,因此只选择Git认为是二进制的非空文件。见:How to remove the lines which appear on file B from another file A?还要考虑使用git add
添加但尚未提交的文件:
grep -Fvxf <(git grep --cached -Il '') <(git grep --cached -al '')
或者你可以用git ls-files
在How to determine if Git handles a file as binary or as text?上做一个for循环
使用this test repo在Git 2.16.1上测试。