【问题标题】:How does Git calculate commits to fetchGit如何计算提交以获取
【发布时间】:2021-03-29 02:02:23
【问题描述】:

我知道git fetch 做了什么以及如何使用这个命令。

我对内部结构感兴趣:Git 如何确定要传输的确切提交?

例如下面的情况

本地仓库:

A - B - C - D master
     \  \- E - F feature1
      \- G feature2

原产地:

A - B - C - D - D1 - D2 master
     \  \- E - F - F1 - F2 feature1
      \- G - G1 feature2

git fetch 需要下载提交 D1、D2、F1、F2 和 G1。

天真地,我的 git 客户端可以将本地提交 SHA(A、B、C、D、E、F、G)列表发送到远程存储库。远程存储库会找到所有不在我列表中的 SHA(D1、D2、F1、F2、G1)并将它们发回给我。对于大型存储库,这将涉及发送大量数据并进行大量计算。发送到远程仓库的数据将与提交的总数成正比。

我确信使用了更聪明的方法。

仅发送每个分支(D、F、G)的尖端的 SHA 就足够了吗?跟踪远程 repo 的父母可以确定 repos 共享的提交并确定丢失的提交。发送到远程仓库的数据将与(未合并的)分支的总数成正比,这通常远低于提交的数量。

它是否适用于所有情况(后面的分支、前面的分支、重新定位的分支)?

还有其他想法吗?我期待一个基于图论的漂亮解决方案:-)

【问题讨论】:

标签: git git-fetch


【解决方案1】:

仅发送每个分支(D、F、G)的尖端的 SHA 就足够了吗?

通常,是的,但并非总是如此。在这种情况下,它可以完美运行:接收 Git 可以宣布它具有这三个哈希 ID,并且由于发送 Git 具有这些提交,发送 Git 可以从中推断,只要接收 Git 不是 shallow 存储库,接收 Git 具有那些提交和所有前辈

“不总是”的线索在上面的陈述中:如果接收Git是一个浅克隆,它可能在这里缺少一些祖先。如果接收 Git 中的 branch-tip-commits 用于发送者中不存在的提交,则它们的哈希 ID 不会向发送者传达任何信息。

对于这些情况,我们依靠“拥有”和“想要”。发送者将他的引用名称和哈希 ID 发送给接收者。接收者可以判断他是否有这些对象。如果不是,而接收者想要它们,他会发出信号,表示他“想要”它们。发送者需要为这些提交的父级提供额外的哈希 ID;接收者将指示他是否拥有它们。在所有情况下,拥有一些提交哈希 ID 表明一个具有所有祖先,除了浅存储库情况(这些使明显的优化变得一团糟,我还没有深入到 Git 源代码中查看是否有浅层克隆的更多特殊情况——接枝点在接收器中是已知的,但我在协议描述中看不到任何允许宣布它们的内容。

【讨论】:

  • 所以看起来这个过程更具交互性并且涉及消息交换(这也在 phd 链接的书中章节中指出)。老实说,我完全忘记了浅层存储库的情况,这显然使事情复杂化了很多。
猜你喜欢
  • 1970-01-01
  • 2012-11-14
  • 2013-08-18
  • 2021-07-20
  • 1970-01-01
  • 2011-01-02
  • 2021-12-11
  • 2012-07-24
  • 1970-01-01
相关资源
最近更新 更多