根据recent question on SO,我想知道为什么git clone
中没有选项,以便新创建的分支的HEAD
指针指向指定的提交?在上面的问题中,OP正在尝试提供有关其用户应克隆的特定提交的说明。
请注意,此问题与使用reset
的{{3}}无关。但关于为什么不存在?
答案 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;没有人愿意添加它"。 :-)隐私参数是有效的,但是没有理由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克隆,确保只有“可达”的提交才会发送给客户端。