为什么没有Git克隆特定提交选项?

时间:2014-10-01 06:18:06

标签: git git-clone

根据recent question on SO,我想知道为什么git clone中没有选项,以便新创建的分支的HEAD指针指向指定的提交?在上面的问题中,OP正在尝试提供有关其用户应克隆的特定提交的说明。

请注意,此问题与使用reset的{​​{3}}无关。但关于为什么不存在

4 个答案:

答案 0 :(得分:22)

到目前为止,两个答案(在我写这篇文章的时候,现在还有更多)在他们所说的内容中是正确的,但并没有真正回答“为什么"题。当然,"为什么"问题真的很难回答,除了Git的各个部分的作者(即便如此,如果两个频繁的Git贡献者给出了两个不同的答案呢?)。

仍然,考虑到Git"哲学"通常,各种传输协议通过命名引用来工作。如果他们提供SHA-1,那么它就是该引用的SHA-1 。对于尚未对存储库进行直接(例如,命令行)访问的人,内置命令的 1 都不允许按ID引用提交。我能找到最接近原因的东西 - 这实际上是一个很好的理由 2 - 这是the git upload-archive documentation中的这一点:

  

安全

     

为了保护已删除的对象的隐私   历史但可能尚未修剪过,git-upload-archive避免了   提供无法访问的提交和树木的档案   存储库的参考。但是,因为计算对象可达性是   计算上很昂贵,git-upload-archive实现了更严格的但是   更容易检查的规则集......

然而,它继续说:

  

如果配置选项uploadArchive.allowUnreachable为真,则这些   规则被忽略,客户端可以使用任意sha1表达式。这个   如果您不关心无法访问的对象的隐私,则非常有用   或者您的对象数据库是否已公开可供访问   非智能-HTTP。

这是特别有趣的,因为git clone首先获取所有可到达的对象,之后您的本地克隆可以通过SHA-1 ID轻松检出提交(并创建指向该ID的本地分支名称,如果希望,或者只是将你的克隆留在"分离的HEAD"模式)。

考虑到这两个交叉流,我认为真正的答案为什么&#34;,此时,#34;没有人愿意添加它&#34;。 :-)隐私参数是有效的,但是没有理由git clone在克隆后无法通过ID检出提交,就像可以告诉我检查除master之外的某个分支一样< sup> 3 与git clone -b ...。允许-b sha1的唯一缺点是Git无法检查(在克隆过程开始之前)是否会收到 sha1 。它可以检查引用名称,因为它们是预先传输的(连同它们的分支提示或其他SHA-1值),因此git clone -b nonexistentbranch ssh://...很快终止并且不会创建副本:

fatal: Remote branch nonexistentbranch not found in upstream origin
fatal: The remote end hung up unexpectedly

如果-b允许使用ID,那么您将获得整个克隆,然后它必须告诉您:&#34;哦天哪,对不起,无法查看该ID,我会把你留在主人身上而不是#34;管他呢。 (或多或少现在发生了破坏的子模块。)


1 虽然git upload-archive 现在强制实施此&#34;隐私&#34;规则,情况并非总是如此(它是在1.7.8.1版本中引入的);和许多(大多数?)git-web服务器,包括与Git本身一起分发的服务器,允许通过任意ID进行查看。这可能是allowUnreachable在&#34之后几年被添加到upload-archive的原因;仅仅是参考名称&#34;代码已添加(但请注意,1.7.8之后和2.0.0之前的Git版本无法放松规则)。因此,虽然&#34;安全&#34;这个想法是有效的,有一段时间(1.7.8.1之前)没有强制执行。

2 有许多方法可以泄漏&#34;表面上是Git存储库中的私有数据。新文件Documentation/transfer-data-leaks即将出现在Git 2.11.1中,而Git 2.11.0添加了一些内部功能(请参阅commit 722ff7f87等)以立即删除已推送但未被接受的对象。这些对象最终会被垃圾收集,但会在一段时间内暴露出来。

3 实际上,默认情况下,git clone会对其认为与远程HEAD引用相关的分支进行本地签出。不过,通常情况下都是master

答案 1 :(得分:8)

克隆回购是一种与结账不同的操作。你没有克隆一个特定的提交&#34;。为方便起见,您可以同时克隆然后检出特定的预先存在的分支,因为这是大多数人想要的。如果这不符合您的需求(没有您想要的特定SHA的分支),只需使用或别名某种形式的

git clone -n <some repo> && cd <some repo> && git checkout SHA

答案 2 :(得分:4)

如果您的特定提交由分支引用,您可以执行:

git clone -b yourBranch /url/of/the/repo

克隆的repo将直接位于该分支引用的提交中。

答案 3 :(得分:4)

正如其他答案所说,这通常不是什么问题,但他们没有说明为什么你不能克隆特定的提交。答案是安全。

如果您不小心推送机密信息,然后强行推送固定的历史记录,那么机密信息的提交仍将存储在服务器上,直到服务器的Git垃圾收集器发现不再需要它为止。如果哈希是已知的(例如可能在日志中可用),则恶意用户可能会请求不应该被推送的特定提交,即使您能够在强制推送已修复的历史记录时验证尚未获得这些提交。

确保只能从refs克隆,确保只有“可达”的提交才会发送给客户端。