tor*_*rek 24
到目前为止两个答案(在我写这篇文章的时候,现在还有更多)在他们所说的内容中是正确的,但是并没有真正回答"为什么"的问题.当然,"为什么"这个问题真的很难回答,除了Git的各个部分的作者(即便如此,如果两个频繁的Git贡献者给出了两个不同的答案呢?).
尽管如此,考虑到Git的"哲学",通常,各种传输协议通过命名引用来工作.如果它们提供SHA-1,则它是该引用的SHA-1 .对于人谁不已经有直接的(如命令行)访问存储库,没有1内置在命令允许一个指通过ID来提交.我能找到的最接近的原因,这和它实际上是一个很好的理由2 -is在此位的git upload-archive文件:
安全
为了保护已从历史记录中删除但尚未修剪的对象的隐私,git-upload-archive可以避免为存储库的refs无法访问的提交和树提供存档.但是,因为计算对象可达性在计算上是昂贵的,所以git-upload-archive实现了更严格但更容易检查的规则集......
然而,它继续说:
如果config选项
uploadArchive.allowUnreachable为true,则忽略这些规则,客户端可以使用任意sha1表达式.如果您不关心无法访问的对象的隐私,或者您的对象数据库已经公开可用于通过非smart-http访问,则此功能非常有用.
这是特别有趣的,因为首先git clone获取所有可到达的对象,之后您的本地克隆可以通过SHA-1 ID轻松检出提交(并根据需要创建指向该ID的本地分支名称,或者只留下您的克隆) "分离的HEAD"模式).
考虑到这两个交叉流,我认为在这一点上,"为什么"的真正答案是"没有人愿意添加它".:-)隐私的说法是有效的,但没有理由git clone不能检查出克隆后ID提交,只是因为它可以告诉检查出比其他一些分行master3用git clone -b ....允许的唯一缺点是Git无法检查(在克隆过程开始之前)是否会收到.它可以检查引用名称,因为它们是预先传输的(连同它们的分支提示或其他SHA-1值),因此很快终止并且不会创建副本:-b sha1sha1git clone -b nonexistentbranch ssh://...
fatal: Remote branch nonexistentbranch not found in upstream origin
fatal: The remote end hung up unexpectedly
Run Code Online (Sandbox Code Playgroud)
如果-b允许一个ID,你就会得到整个克隆,那么就必须告诉你:"哦天哪,对不起,不能查看那个ID,我会把你留在主人身上"或者其他什么.(或多或少现在发生了破坏的子模块.)
1虽然git upload-archive 现在执行这个"隐私"规则,但情况并非总是如此(它是在1.7.8.1版本中引入的); 和许多(大多数?)git-web服务器,包括与Git本身一起分发的服务器,允许通过任意ID进行查看.这可能是为什么allowUnreachable在添加upload-archive"only by ref name"代码后添加了几年(但请注意,1.7.8之后和2.0.0之前的Git版本无法放松规则).因此,虽然"安全"理念是有效的,但有一段时间(1.7.8.1之前)没有强制执行.
2有许多方法可以从Git存储库中"泄露"表面上的私有数据.一个新文件,Documentation/transfer-data-leaks,即将出现在Git 2.11.1中,而Git 2.11.0增加了一些内部功能(参见commit 722ff7f87等),以立即删除被推送但未被接受的对象.这些对象最终会被垃圾收集,但会在一段时间内暴露出来.
3实际上,默认情况下git clone会对其认为与远程HEAD引用相关的分支进行本地签出.不过,通常情况就是master如此.
克隆回购是一种与结帐不同的操作.您没有"克隆特定提交".为方便起见,您可以同时克隆然后检出特定的预先存在的分支,因为这是大多数人想要的.如果这不符合您的需求(没有您想要的特定SHA的分支),只需使用或别名某种形式的
git clone -n <some repo> && cd <some repo> && git checkout SHA
Run Code Online (Sandbox Code Playgroud)
如果您的特定提交被分支引用,您可以执行以下操作:
git clone -b yourBranch /url/of/the/repo
Run Code Online (Sandbox Code Playgroud)
克隆的存储库将直接位于该分支引用的提交处。
小智 5
正如其他答案所说,这通常不是什么大问题,但他们没有说明为什么你不能克隆特定的提交。答案是安全。
如果你不小心推送了机密信息,然后强制推送固定的历史记录,那么带有机密信息的提交仍然会存储在服务器上,直到服务器的 Git 垃圾收集器发现不再需要它为止。如果哈希值是已知的(例如,它可能在日志中可用),则恶意用户可能会请求不应该推送的特定提交,即使您能够验证当您强制推送固定历史记录时,没有人会这样做。已经获取了那些提交。
确保只能从引用克隆可以确保只有“可到达”的提交才会发送到客户端。