编辑:来自 cmets:
我需要从分布在十几个分支的数百个提交中检查同一个文件。
为此,您将需要其他仓库管理员的合作。
在 Git 中,历史是通过给它一个引用名(分支、标签等)和通过共享文件系统或托管服务器的某种访问来发布的。
不值得给出自己的引用名的东西要么是已发布历史的一部分(确实有自己的引用名),要么不是。
如果是这样,Git 将确保您获得一个完整的、内部一致的包,让您及时了解您要求的已发布历史记录。 Git 专注于使特定操作尽可能快速和高效。
如果不是,那么托管 repo 没有发布它,并且 (a) 你通常根本无法获得它,并且 (b) 你通常甚至不知道如何请求它,它的对象 id .
要找到对象的 id,您必须通过历史记录检查快照,...这意味着您必须拥有快照...看到了吗?
Git 不喜欢支付两次间接费用,它被构建为 vcs。您正在尝试像共享文件系统一样使用它。文件系统的构建是为了高效地频繁且重复地为同一个客户端提供单个对象。 dvcs 的构建是为了高效地服务于多个完整的修订,间隔相对较长,每个客户端一次。这是工程权衡的领域:你不可能在这两个方面都非常高效,而且你在其中一个方面做得越好,重新调整工具和做另一件事就越困难。
话虽如此:如果您可以让其他 repo 管理员为您做一些自定义工作,这并不难:
git rev-list --branches --objects -- path/to/file | git pack-objects pack
将打包该文件的所有分支版本的历史记录:引入新版本的提交、显示它们去向的树及其内容,并将其放入名为pack-<hashcode>.{idx,pack} 的两个文件中。将该包放在任何 repo 的 objects/pack 目录中,您就可以:您拥有处理该文件所需的一切。
这样的切片历史相对难以处理,而按需填充缺失位的开销正是 Git 旨在避免的,但使用你所拥有的东西,你可以使用例如git verify-pack -v 显示包的确切内容,git cat-file -p 打印单个对象。该包中的提交是引入新版本的提交,您可以通过将 :path/to/file 附加到其提交 ID 来引用其中一个文件。
因此,当您运行验证包以查看您所拥有的内容时,您会得到关于其内容和结构的太多信息的转储。为了使它对您的目的有用,您可以只刮掉提交 ID,并按日期顺序列出它们,使用
# this is the pack I made for testing
git verify-pack -v .git/objects/pack/pack-8d3bb7bca6a4cdc086778ad55c79f45e672ae7e5.idx \
| awk '$2=="commit"{print $1}' \
| git rev-list --stdin --date-order --no-walk
sub in log for rev-list 查看日志消息,或者您可以显示您获取的 blob,例如git show <commit-hash>:path/to/file。要按时间顺序显示斑点,您可以
git git verify-pack -v .git/objects/pack/pack-8d3bb7bca6a4cdc086778ad55c79f45e672ae7e5.idx \
| awk '$2=="commit"{print $1}' \
| git rev-list --stdin --date-order --no-walk --pretty=%h:path/to/file \
| git cat-file --batch
这将以可扫描的形式转储内容。
。 . .实际上,如果一个多合一的历史转储就可以了,并且您只需要匹配的内容和顺序,而不是生成的提交 ID,Git's fast-export 可能会为您完成所有工作,有管理员做的
git fast-export --branches -- path/to/file | zstd >my-stuff.zst
它甚至可能比包文件更紧凑(因为它不必保留 id)并将其发送给您。