我该如何从存储库中下载特定的git提交?

22

我没有本地代码副本/等等,我只想下载一个特定的git提交,以便查看它。 我有git存储库的url:

git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git

和提交哈希:

ee9c5cfad29c8a13199962614b9b16f1c4137ac9

我如何使用git仅下载这个提交(我不想下载整个仓库,只需要一个提交的补丁)?我已经阅读了git-pull和git-cherry-pick的手册,并尝试使用命令操作,但没有成功。

克隆整个仓库并不是一个选择,因为一些内核仓库非常大而且下载速度很慢(需要数小时)。


你尝试过通过网页浏览这个仓库吗? - bstpierre
1
我想通过命令行完成它,原因有很多(速度/效率和脚本编写是主要原因之一)。 - bigredbob
3
提交(commit)本质上是一个差异(diff)。你想查看差异还是查看树(tree)? - Daenyth
3
在 Git 中,提交记录反映的是整个文件树,而不仅仅是与父提交之间的差异。 - poke
1
@poke:实际上,据我所知,提交对象确实是指向差异 -- 但它也指向应用差异后的树对象。不过,我的 Git 内部知识并不完美,所以我不确定。无论如何,这个问题仍然值得 OP 回答。 - Daenyth
4
git不存储差异(它也不使用"delta storage"),只存储最终树的快照。当你请求两个提交之间的更改时,差异会即时计算出来。 - André Caron
9个回答

24

这似乎是不可能的。根据kernel.org上的讨论,协议只允许获取命名引用。如果您不想从git网站下载快照,则必须克隆整个存储库。

(您可能需要阅读git-fetchgit-ls-remote的手册。)


13

通常情况下,你可以使用--remote参数和git archive命令来实现此操作,具体方法如下:

$ git archive -o repo.tar --remote=<repo url> <commit id>

在你的例子中,你会使用:

$ git archive -o repo.tar --remote=git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git ee9c5cfad29c8a13199962614b9b16f1c4137ac9

这将给你该时间点的仓库状态。请注意,你无法获取整个仓库,因此不能使用所下载的内容与上游仓库进行交互。

然而,远程使用git archive需要在服务器端启用,并且Linux内核Git服务器上没有启用该功能。不过,你可以通过以下形式的URL复制它:http://git.kernel.org/?p=<path to repo>;a=snapshot;h=<commit id>;sf=tgz。因此,对于你的仓库,你可以使用wget或curl使用该URL获取文件。


2
不幸的是,这种方法不可靠/可脚本化(而且有些git仓库根本没有易于找到的Web界面)。 - bigredbob
1
它应该正常工作,除了网页内容是动态生成的。curl http://git.kernel.org/?p = linux / kernel / git / davem / net-2.6.git; a = snapshot; h = ee9c5cfad29c8a13199962614b9b16f1c4137ac9; sf = tgz 的结果是 <body> 生成中... </body> - wlangstroth
1
@Will:你需要在脚本或其他文件中处理该响应,或者直接将链接粘贴到浏览器中。虽然它很难理解,但Git并没有提供一种简单的方法来获取一个提交。 - mipadi

2
我知道当你有一个仓库的克隆副本(或类似的仓库)时,这个方法是可以奏效的。
git fetch git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
git cherry-pick ee9c5cfad29c8a13199962614b9b16f1c4137ac9

Fetch命令可以下载远程引用(但不是整个仓库,我想),这样您就可以使用其他命令来引用它们。然后,您可以挑选其中一个提交记录,并尝试将差异应用于本地树。

我没有在没有本地git仓库的情况下尝试过,但我已经在不是彼此分叉的仓库上尝试过。你可能会遇到合并冲突,但你可以手动清理它们。


只有在您挑选的提交是存储库 HEAD 的祖先时,才能起作用。 - Collin Anderson
我刚试过了,git fetch 尝试下载所有内容。 - David Given

1

1
如@Josh Lee的回答所述,简短的答案是不可能
然而,在非现实生活的情况下,当您是大型存储库的所有者并且需要在新位置进行某些提交并保存一些带宽/时间以获取,您可以使用Web界面在特定提交处创建命名引用(分支或标记),然后克隆它,例如,如果您将提交标记为temp/1分支: git clone --branch=temp/1 --depth=1 http://example.com/your-repo 这似乎是获取某些提交的最便宜的方法(从下载大小方面考虑),前提是您具有远程存储库的"创建引用"访问权限。

0
今天我遇到了这个问题,并找到了一种下载特定提交存档的方法。如果您访问git.kernel.org上的存储库,则底部有一个克隆部分。底部的URL是Google Git镜像。您可以从此处下载特定提交的存档。

0

我有同样的需求。 我需要下载一个特定提交的补丁,然后将其应用到另一个分支上。

我使用了:git format-patch sha-id

只需指定比所需提交旧的sha-id即可。 它会生成与所有提交对应的.patch文件。


-1

有一种方法可以做到这一点:

git show ee9c5cfad29c8a13199962614b9b16f1c4137ac9 > myCommittedCode.txt

1
这个问题有点含糊不清,但是“下载提交”通常是指下载提交中的文件(如果git show只给你一个单独的文件,则不会执行此操作)。 - toolforger
我必须点踩这个回答,因为它显然是错误的。 @toolforger - OP明确表示“他还没有本地代码”,因此并不含糊。 - maoizm

-1
在这种情况下,如果你只想要差异,你可以从内核仓库的Web前端下载它,URL如下:
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commitdiff_plain;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9

你可以通过修改URL来获取其他提交记录。


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