【问题标题】:How do I download a specific git commit from a repository?如何从存储库下载特定的 git 提交?
【发布时间】:2010-09-13 03:31:09
【问题描述】:

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

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

和提交哈希:

ee9c5cfad29c8a13199962614b9b16f1c4137ac9

如何使用 git 下载这个提交(我不想要整个 repo,只需要一个提交补丁)?我已经阅读了 git-pull 和 git-cherry-pick 的手册页,并且没有运气地摆弄这些命令。

克隆存储库确实不是一种选择,因为某些内核存储库非常大并且下载速度很慢(数小时)。

【问题讨论】:

  • 出于多种原因(速度/效率和脚本是主要的),我想从命令行执行此操作。
  • 提交本质上是一个差异。您要查看差异还是查看树?
  • @Daenyth:这实际上不是真的。在 git 中,提交反映了一个完整的树,而不仅仅是与父级的差异。
  • @poke:实际上,据我了解,提交对象确实引用了差异——但它也引用了应用差异后的树对象。我对 git 内部知识的了解并不完美,所以我不确定。无论如何,这个问题仍然需要 OP 回答。
  • @Daenyth:git 不存储差异(同样,它不使用 delta storage),只存储结果树的快照。当您请求两次提交之间的更改时,会即时计算差异。

标签: git


【解决方案1】:

这似乎是不可能的。根据 kernel.org 上的 discussion,该协议将只允许获取命名的 refs。如果您不想从 git 网站下载快照,则必须克隆整个 repo。

(您不妨阅读git-fetchgit-ls-remote 的手册。)

【讨论】:

    【解决方案2】:

    在一般情况下,您可以使用--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
    

    这将为您提供该时间点的回购状态。请注意,您不会获得整个 repo,因此您实际上无法使用已下载的内容与上游 repo 进行交互。

    但是,远程使用git archive 必须在服务器端启用,并且它不在 Linux 内核的 Git 服务器上。但是,您可以使用http://git.kernel.org/?p=&lt;path to repo&gt;;a=snapshot;h=&lt;commit id&gt;;sf=tgz 形式的 URL 获取副本。因此,对于您的 repo,您​​可以使用 wget 或 curl 来获取使用该 URL 的文件。

    【讨论】:

    • 不幸的是,这种方法不可靠/可编写脚本(如果有的话,一些 git repos 也不容易找到 Web 界面)。
    • 它应该可以工作,除了网络内容是动态生成的。 curl http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=snapshot;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9;sf=tgz 的结果是&lt;body&gt;Generating...&lt;/body&gt;
    • @Will:您必须在脚本或诸如此类的东西中处理该响应,或者只需将链接粘贴到浏览器中。它是迟钝的,但 Git 没有提供一种简单的方法来获取一个提交。
    【解决方案3】:

    我知道当你有一个 repo 的克隆(或类似的 repo)时这会起作用..

    git fetch git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
    git cherry-pick ee9c5cfad29c8a13199962614b9b16f1c4137ac9
    

    Fetch 下载远程引用(但不是整个 repo,我不认为),以便您可以使用其他命令引用它们。然后你挑选那个提交,它会尝试将差异应用到你的本地树。

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

    【讨论】:

    • 只有当你挑选的提交是 repo 的 HEAD 的祖先时,它才会起作用。
    • 我刚刚尝试过 --- git fetch 尝试下载所有内容。
    【解决方案4】:
    git show COMMITID
    

    但是您必须克隆存储库。没办法,我想。但是您可以使用 --depth 参数进行浅层克隆。

    另外,找到了一篇很好的 SO 帖子,更深入地介绍了这个主题Browse and display files in a git repo without cloning

    【讨论】:

      【解决方案5】:

      正如@Josh Lee 中正确说明的那样,简短的回答是不可能

      然而对于 非现实生活的情况,当您是大型 repo 的所有者并且需要在新位置进行一些提交并节省一些带宽/时间来获取时,您可以创建命名 ref(分支或标记)在特定提交时使用 Web 界面,然后克隆它,例如。如果你用temp/1 分支标记你的提交:

      git clone --branch=temp/1 --depth=1 http://example.com/your-repo

      这似乎是获取某些提交的最便宜的方式(就下载大小而言),前提是您拥有“创建参考”远程存储库的访问权限

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          我也有同样的需要。 我需要下载需要应用到另一个分支的特定提交的补丁。

          我用过:git format-patch sha-id

          只需指定比所需提交稍早的sha-id。 它将给出与所有提交对应的.patch 文件。

          【讨论】:

            【解决方案8】:

            在这种情况下,如果你想要的只是差异,你可以从这个 url 的内核 repo 的 web 前端下载它:

            http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commitdiff_plain;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9
            

            您可以使用 url 来获取其他提交。

            【讨论】:

              【解决方案9】:

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

              git show ee9c5cfad29c8a13199962614b9b16f1c4137ac9 > myCommittedCode.txt
              

              【讨论】:

              • 这个问题有点含糊,但是“下载提交”通常是关于下载提交中的文件(git show 不会这样做,如果它只给你一个文件)。跨度>
              • 我不得不对此投反对票,因为这个答案显然是错误的。 @toolforger - OP 用明文说“他还没有本地代码”,所以它并不模棱两可
              猜你喜欢
              • 1970-01-01
              • 2011-05-21
              • 2017-06-30
              • 2015-07-18
              • 1970-01-01
              • 1970-01-01
              • 2012-06-10
              • 2014-01-14
              • 2010-12-09
              相关资源
              最近更新 更多