git - 为什么没有特定于 Git 克隆的提交选项?

标签 git git-clone

鉴于 recent question on SO ,我想知道为什么 git clone 中没有选项这样新创建的分支的 HEAD 指针将指向指定的提交?在上面的问题中,OP 试图提供有关他的用户应该克隆的特定提交的说明。

请注意,这个问题不是关于 How To Clone To A Particular Version 的使用重置;但关于为什么不存在

最佳答案

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

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

SECURITY

In order to protect the privacy of objects that have been removed from history but may not yet have been pruned, git-upload-archive avoids serving archives for commits and trees that are not reachable from the repository's refs. However, because calculating object reachability is computationally expensive, git-upload-archive implements a stricter but easier-to-check set of rules ...

然而,它接着说:

If the config option uploadArchive.allowUnreachable is true, these rules are ignored, and clients may use arbitrary sha1 expressions. This is useful if you do not care about the privacy of unreachable objects, or if your object database is already publicly available for access via non-smart-http.

这特别有趣,因为 git clone首先获取所有可访问的对象,之后您的本地克隆可以通过 SHA-1 ID 简单地检查提交(并根据需要创建指向该 ID 的本地分支名称,或者只是让您的克隆处于“分离头”模式).

鉴于这两个交叉流,我认为在这一点上“为什么”的真正答案是“没有人关心添加它”。 :-) 隐私论点是有效的,但没有理由 git clone克隆后无法通过 ID 检查提交,就像它可以被告知检查除 master 以外的某个分支一样3 git clone -b ... .允许 -b <em>sha1</em> 的唯一缺点是 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,你会得到整个克隆,然后它必须告诉你:“哦,天哪,抱歉,不能检查那个 ID,我会让你留在 master 上”或其他什么。 (这或多或少是现在子模块损坏时发生的情况。)


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 存储库中“泄露”表面上的私有(private)数据。一个新文件,Documentation/transfer-data-leaks , 即将出现在 Git 2.11.1 中,而 Git 2.11.0 添加了一些内部功能(请参阅 commit 722ff7f87 等)以立即删除推送但未接受的对象。此类对象最终会被垃圾回收,但会在这段时间内暴露它们。

3实际上,默认情况下git clone对它认为与远程的 HEAD 相关的分支进行本地 checkout 引用。通常是 master不过,无论如何。

关于git - 为什么没有特定于 Git 克隆的提交选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26135216/

相关文章:

git - 如何将提交推送到由气隙分隔的远程 Git 存储库?

c# - 是否可以从 CakeBuild 创建和 checkout 新的 git 分支?

git - 分支策略 - 维护多个版本

git - 如何知道 Git 标签是否已被移动?

ftp 服务器上的 Git 存储库

git clone 以 Broken Pipe 结束

git:如何在没有以前版本的情况下撤消我最后的 "git push -f"?

git - 将 git 从本地机器克隆到我的服务器?

git - 如何解决 "Port number ended with ' y'"的 url 错误?

Git 部分克隆 : how to disable dynamic object fetching?