首页 > 解决方案 > 是否可以从远程指定的提交中下载单个文件?

问题描述

我正在尝试从远程的特定提交中签出特定文件。

请注意,提交不在本地仓库中,只是远程仓库的一部分。

  1. 我不想从 GitHub/bitbucket 界面下载原始文件。因为我的遥控器不在类似的平台上。

  2. 我不想在 git checkout 之后执行 git fetch,因为执行 git fetch 会下载一堆我不想要的其他项目。我只对来自特定提交的特定文件感兴趣。

标签: git

解决方案


编辑:来自评论:

我需要从分布在十几个分支的数百个提交中检查相同的文件。

为此,您将需要其他仓库管理员的合作。

在 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 旨在避免的,但使用你所拥有的,你可以使用 eggit 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 inlogrev-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,Gitfast-export可能会为您完成所有工作,让管理员做

git fast-export --branches -- path/to/file | zstd >my-stuff.zst

它甚至可能比包文件更紧凑(因为它不必保留 id)并将其发送给您。


推荐阅读