简体   繁体   English

如何从远程 git 存储库中以特定提交(通过哈希)获取单个文件?

[英]How can I fetch a single file at at a specific commit (by hash) from a remote git repository?

I'd like to fetch a file at a commit from a remote git repository without fetching all objects in the repository.我想在提交时从远程 git 存储库获取文件,而不获取存储库中的所有对象。 I know git archive doesn't work as it can only fetch the tip of a branch.我知道git archive不起作用,因为它只能获取分支的尖端。

With sparse-checkout and using protocol v2 (thanks @bk2204) I can create a work-tree with only the readme at a commit, but git transmits 10s of thousands of objects and 188mb.使用 sparse-checkout 和使用协议 v2(感谢@bk2204),我可以在提交时创建一个只有自述文件的工作树,但是 git 传输了成千上万个对象和 188mb。

mkdir linux
cd linux
git init
git config core.sparseCheckout true
git config protocol.version 2
git remote add origin git@github.com:torvalds/linux.git
echo "/README" > .git/info/sparse-checkout
git fetch --depth 1 origin ab02b61f24c76b1659086fcc8b00cbeeb6e95ac7
git checkout ab02b61f24c76b1659086fcc8b00cbeeb6e95ac7
remote: Enumerating objects: 71432, done.
remote: Counting objects: 100% (71432/71432), done.
remote: Compressing objects: 100% (66651/66651), done.
remote: Total 71432 (delta 5277), reused 25451 (delta 3920), pack-reused 0
Receiving objects: 100% (71432/71432), 188.85 MiB | 7.71 MiB/s, done.
Resolving deltas: 100% (5277/5277), done.

Ideally this operation should fetch 3 objects - the commit (the known sha) > the commit's tree > the file in the tree理想情况下,此操作应该获取 3 个对象 - 提交(已知的 sha)> 提交的树 > 树中的文件

$ git cat-file -p ab02b61f24c76b1659086fcc8b00cbeeb6e95ac7 | grep tree
tree f6760b0bf32bd3b9a760d6e895c7fb76cd9c2ef8
$ git cat-file -p f6760b0bf32bd3b9a760d6e895c7fb76cd9c2ef8 | grep README
100644 blob 669ac7c32292798644b21dbb5a0dc657125f444d    README
$ git cat-file -p 669ac7c32292798644b21dbb5a0dc657125f444d

In general, you cannot fetch individual objects without partial clone support.通常,如果没有部分克隆支持,您将无法获取单个对象。 The protocol doesn't allow it.协议不允许。 Sparse checkout doesn't prevent you from fetching all of the data, it just prevents you from checking it all out.稀疏结帐不会阻止您获取所有数据,它只会阻止您全部检查。

I'm not aware of any major Git hosting providers that have generally available partial clone support right now, although I suspect it will be coming soon.我不知道现在有任何主要的 Git 托管提供商提供普遍可用的部分克隆支持,尽管我怀疑它很快就会出现。 The feature is still relatively experimental.该功能仍然是相对实验性的。

However, if you're using a remote that supports protocol v2, you can fetch a specific commit, even if you normally wouldn't be able to without protocol v2.但是,如果您使用支持协议 v2 的遥控器,则可以获取特定提交,即使您通常在没有协议 v2 的情况下无法获取。 You can run git config protocol.version 2 and then you'll be able to fetch individual commits by hash.您可以运行git config protocol.version 2 ,然后您就可以通过哈希获取单个提交。 Doing that with a --depth 1 would be the best you could do in this particular case.在这种特殊情况下,使用--depth 1这样做将是您能做的最好的事情。

A hosting service is supposed to have APIs to download a file of a revision or retrieve its content.托管服务应该具有用于​​下载修订文件或检索其内容的 API。 For example, Gitlab has GET /projects/:id/repository/files/:file_path/raw , and Github has GET /repos/:owner/:repo/contents/:path , and Gerrit has GET /projects/{project-name}/commits/{commit-id}/files/{file-id}/content .例如,Gitlab 有GET /projects/:id/repository/files/:file_path/raw ,Github 有GET /repos/:owner/:repo/contents/:path ,Gerrit 有GET /projects/{project-name }/commits/{commit-id}/files/{file-id}/content

For a simple self-hosting repository, to fetch a random commit or object by git fetch , you could set uploadpack.allowReachableSHA1InWant=true or uploadpack.allowAnySHA1InWant=true .对于简单的自托管存储库,要通过git fetch随机提交或对象,您可以设置uploadpack.allowReachableSHA1InWant=trueuploadpack.allowAnySHA1InWant=true In most cases, they are false(by default) for safety and performance.在大多数情况下,为了安全和性能,它们是假的(默认情况下)。 For a self-hosting Gerrit, it has similar configuration options.对于自托管 Gerrit,它具有类似的配置选项。 I have no idea about a self-hosting Gitlab.我不知道自托管 Gitlab。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM