如何在Git中获取存储库中所有Blob的列表

9

如何列出Git仓库中所有文件的所有版本?

(例如,列出曾经包含某个字符串的所有文件)

这个列表可以用来查看文件。


这可能是解决方案 git rev-list --all | xargs -l1 git diff-tree -r -c -M -C --no-commit-id | awk '{print $3}' - Hugo
@Hugo:是的,那样会得到一个 blobs 的列表。不过你还需要做更多的工作 - 你需要同时记住文件名字段,这样当你使用 git-show 查看一个 blob 时,就能将其与名称匹配起来。而且你已经丢失了一些关键信息:blob 所属的提交。 - Cascabel
@Hugo:另一个想法-由于您正在使用diff-tree,因此您只能看到修改后的blob,因此如果您在其中进行grep,您实际上正在接近“git log -S”的功能。 - Cascabel
4个回答

16

这是我获取存储库中所有blob的SHA和文件名列表的方法:

$ git rev-list --objects --all | git cat-file --batch-check='%(objectname) %(objecttype) %(rest)' | grep '^[^ ]* blob' | cut -d" " -f1,3-

注:

  1. 格式化字符串中的 %(rest) 原子会将对象 SHA 后的输入行剩余部分附加到输出结果。在这种情况下,这个剩余部分恰好是路径名(用于树和 blob 对象)。

  2. grep 模式旨在仅匹配实际的 blob 对象,而不是只是在其路径名中包含字符串 blob 的树对象。


3
首先,通过列出blob的方式几乎没有机会来完成这个任务。Blob只是原始数据,它并不知道它所属的文件。真正的答案有点取决于你想要实现什么。例如,您需要搜索那些甚至从提交历史中无法访问的提交中的blob吗?如果不需要,以下是一些想法。
也许git-log的pickaxe搜索可以满足您的需求:
-S 查找引入或删除实例的差异。请注意,这与字符串仅出现在diff输出中不同;有关更多详细信息,请参见gitdiffcore(7)中的pickaxe条目。
根据您的最终目标,这可能比您提出的建议要好得多-您将实际上看到如何添加或删除该字符串。当然,如果您愿意,您可以使用获得的信息来cat整个文件。
或者,也许你想要用git-log列出修订版本,并在它提供的树(提交)上使用git-grep?

3
如果你正在使用git cat-file --batch-all-objects --batch-check,如J. Doe答案所建议并在此展示,请确保使用Git 2.34(2021年第四季度)。
"git cat-file --batch" (man) 带有--batch-all-objects选项将遍历存储库中找到的所有对象,但它曾经使用替换机制翻译这些对象名称,这违背了枚举存储库中所有对象的目的。

这已在Git 2.34(2021年第四季度)中得到纠正。

请参见提交bf97289提交818e393提交5c5b29b提交c3660cf提交e879295(由Jeff King (peff)于2021年10月5日进行)。 (由Junio C Hamano -- gitster --提交092228e中合并,于2021年10月18日)

cat-file:使用--batch-all-objects禁用refs/replace

签名作者: Jeff King

在枚举对象数据库中的所有对象时,不考虑refs/replace是没有意义的。
此选项的目的是以低级别枚举数据库中的所有对象。
根据定义,我们已经显示替换对象的内容(在其真实oid下),在另一个oid下显示这些内容几乎肯定会违反用户尝试的操作。

和:

cat-file:对--batch-all-objects使用packed_object_info()

签名作者: Jeff King

当 "cat-file --batch-all-objects" 遍历每个对象时,它知道在哪里找到每个对象。
但当我们查找对象的详细信息时,我们根本不使用该信息。

此补丁教导它在遍历包中的对象时使用包/偏移对。
这会产生可衡量的速度改进(在完全打包的 linux.git 克隆上进行计时)


2

根据手册,我理解以下内容列出了所有对象及其信息

git cat-file --batch-all-objects --batch-check

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