Git 查找历史记录中的所有二进制文件

问题描述 投票:0回答:3

很抱歉,如果这与上一个问题重复,但我找不到我要找的东西。我正在将一个大型 cvs 代码集(20 多个具有 15 年历史的存储库 - 10-15 GB 大小)转换为 git。大部分大小是由于过去与代码一起提交的二进制文件造成的。虽然某些二进制文件是可以完全删除的文件,但最好保留其中的许多文件及其历史记录。但是,我们不希望存储库膨胀。

我们目前计划使用 git-fat 来存储二进制文件,但我正在编写一个脚本来自动转换文件。我的第一步是尝试识别存储库中的所有二进制文件(包括已删除的文件)。有什么简单的方法可以实现这一点吗?谢谢你的帮助

编辑

我实际上认为我找到了一个合理的方法,我只是跑步

git log --numstat <first commit hash> HEAD

这会打印出所有文件的列表,前面有两列,第一列包含文件的更改数量(我不确定它是以字节还是行为单位)。但对于二进制文件来说,重要的部分是“-”。通过选择带有此标签的行并“唯一”它们,我相信我可以获得二进制文件的完整列表。

这个策略有什么缺陷吗?

git binaryfiles
3个回答
14
投票

tldr;

git log --all --numstat \
    | grep '^-' \
    | cut -f3 \
    | sed -E 's|(.*)\{(.*) => (.*)\}(.*)|\1\2\4\n\1\3\4|g' \
    | sort -u

说明:

git-log
选项
--numstat

以十进制表示法显示添加和删除的行数和不带缩写的路径名,以使其更加机器友好。 对于二进制文件,输出两个 - 而不是 0 0

来源:https://git-scm.com/docs/git-log,重点是我的

这会产生如下所示的输出条目:

commit 0123456789012345678901234567890123456789
Author: Joe Example <[email protected]>
Date:   Thu Mar 9 15:33:29 2017 +0000

    edit Dockerfile, add assets/foobar.jpg

1   1   Dockerfile
-   -   assets/foobar.jpg

grep '^-'
匹配带有前导连字符的行,
cut -f3
打印第三个制表符分隔字段,

sed -E 's|(.*)\{(.*) => (.*)\}(.*)|\1\2\4\n\1\3\4|g'

检测已移动/重命名的文件并打印源和目标;例如,它会改变这个:

path/to/{foo => bar}/my-document.pdf

对此:

path/to/foo/my-document.pdf
path/to/bar/my-document.pdf

最后,

sort -u
将对路径列表进行累积、排序和统一

编辑:这个答案假设存在支持扩展正则表达式和捕获组的

sed
;例如,https://www.gnu.org/software/sed/ .


2
投票

这里是 git-fat 的贡献者之一。

如果您主要关心文件的大小,而不是具体类型,那么 git-fat 有一个

find
命令,它允许您查找 git 存储库中超过给定大小的所有文件。

我目前为 cyaninc 的 分支做出贡献,但两个版本(Jed 和 Cyan)都有 find 命令。

另请查看自述文件中的追溯导入部分。两个版本也都支持。


1
投票

一种解决方案是迭代所有修订版,获取每个修订版的所有文件,获取每个文件的内容,然后获取每个文件的类型,所以...

以下是获取所有修订列表的方法:

$ git rev-list HEAD
32a9b9158d73dc80b355993a5a5f8fc49ae25334
9946574838bf5f984f5f4a19b2fc524f0a60378c
3f82a5dcecde0028da21fb266c1bbd7e9ec762ec
...

以下是获取修订版本中所有文件列表的方法:

$ git ls-tree -r 32a9b9158d73dc80b355993a5a5f8fc49ae25334
100644 blob dcf290b1a99a8d2535b8aa8f85702cd1b7fac6e8    .gitignore
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    README

您可以通过使用

提供每个修订版中每个文件的 blob 来获取每个文件的内容
git show:
$ git show dcf290b1a99a8d2535b8aa8f85702cd1b7fac6e8
.gitignore

*.pyc
rm_pyc.sh
aima/**/*.pyc
.idea

要测试文件是否是二进制文件,您可以使用 /bin/file:

git show dcf290b1a99a8d2535b8aa8f85702cd1b7fac6e8 > file
/bin/file file
file: ASCII text
© www.soinside.com 2019 - 2024. All rights reserved.