无需每次 运行 一个进程即可更快 'git show' 的方法

Faster way to 'git show' without running a process each time

我有一个本地存储库,我想查看一个文件的所有版本。我可以通过首先找到所有提交 ID 来粗略地做到这一点:

% git log FILE | perl -nE '/\Acommit ([0-9a-f]+)\s*\z/ && say ' log >commits

然后获取每个 ID 的文件文本:

% for i in `cat commits`; do git show $i:FILE; done

为每个修订运行一个 'git' 进程,这比它需要的要慢。 (Git 很快,但还没有快到我想为文件的每个修订版创建一个子进程。快速基准测试显示 运行 每个修订版都有一个单独的 'git show' 进程通过每秒大约 50 次提交,我对该文件有超过 5000 次提交。)

幸运的是 'git show' 允许您一次查看多个修订版,例如

% git show REV1:FILE REV2:FILE

对所有修订只运行一个子流程。但是它将它们连接在一起而没有标记,因此程序很难确定一个结束和下一个开始的位置。虽然有一个--format选项,但它不适用于转储明文内容,似乎没有任何作用。

有没有什么方法可以获取文件的所有版本,而无需为每个修订创建一个子进程?我知道 Perl 的 Git 模块,但尽管它有一个 cat_blob 方法,但我到目前为止只有提交本身的 ID,而不是对应于提交中的一个文件的 ID(如果这样东西甚至存在)。

因此,似乎有三种可供选择的前进方式:

有什么建议吗?

我在 git 邮件列表上询问过,git cat-file --batch 就是您所需要的。它在标准输入上接受 REV:FILE 对,并以相同的顺序在标准输出上输出文件内容。每个文件都以 header 行为前缀,以字节为单位给出其长度。