无需每次 运行 一个进程即可更快 '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 show' 的一些选项可以让我在其输出中分离出不同的修订版,或者将它们写入单独的文件等。
- 一些使用
Git
或其他 Perl 库直接访问各种修订版文件内容的方法(无需为每个单独的修订版创建新的子进程)
- 一些其他工具或库可以更直接或更轻松地完成我想要的工作。我的最终应用程序是有一个增强的 'blame' 工具,它显示文件的每个版本中的每一行,以及引入和删除它们的修订。
有什么建议吗?
我在 git 邮件列表上询问过,git cat-file --batch
就是您所需要的。它在标准输入上接受 REV:FILE
对,并以相同的顺序在标准输出上输出文件内容。每个文件都以 header 行为前缀,以字节为单位给出其长度。
我有一个本地存储库,我想查看一个文件的所有版本。我可以通过首先找到所有提交 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 show' 的一些选项可以让我在其输出中分离出不同的修订版,或者将它们写入单独的文件等。
- 一些使用
Git
或其他 Perl 库直接访问各种修订版文件内容的方法(无需为每个单独的修订版创建新的子进程) - 一些其他工具或库可以更直接或更轻松地完成我想要的工作。我的最终应用程序是有一个增强的 'blame' 工具,它显示文件的每个版本中的每一行,以及引入和删除它们的修订。
有什么建议吗?
我在 git 邮件列表上询问过,git cat-file --batch
就是您所需要的。它在标准输入上接受 REV:FILE
对,并以相同的顺序在标准输出上输出文件内容。每个文件都以 header 行为前缀,以字节为单位给出其长度。