【问题标题】:git push and unreferenced objectsgit push 和未引用的对象
【发布时间】:2021-05-05 08:43:48
【问题描述】:

如果不运行git prunegit gcgit push 会上传任何未引用的对象吗? 想象一下这些提交历史:

A

在提交 C 中添加了一个新文件,并从提交 D 中删除了该文件。现在 git rebase --onto B D 将导致:

A

并且该文件仍在 .git/objects 中,因为它被两个分离的提交 C 和 D 引用。现在在这两个事件中会发生什么:

  1. git push <remote> <branch> 现在将远程包含已删除,因为文件对象仍然存在?

  2. 将请求拉到远程分支的主要上游。如果 1 的答案是肯定的,如果 C 和 D 从未与上游合并,该文件是否会合并到上游?

编辑:这个问题补充了这里讨论的案例Removing unreferenced objects from remote

【问题讨论】:

  • “将 git push 上传任何未引用的对象”不。但是你的问题接着暗示 Git 处理文件。它没有。它处理提交。如果您的文件处于已推送的提交中,则您的 rebase 不会删除它。
  • 当然,与我分叉的上游合并是否相同,因为分离的提交从未与我分叉的上游合并?
  • 如果我正确理解您的评论:是的,它是一样的。不会传输未引用的对象。

标签: git git-rebase git-push git-gc


【解决方案1】:

当您推送一个分支时,只有当前在该分支上的提交(即可以从分支提示访问)被传输到远程。

【讨论】:

    【解决方案2】:

    一般来说,git push不会推送任何未引用的对象。

    可能有特定的情况/优化可能会这样做,因为从来没有任何明确的承诺。但实际上并没有。

    请注意,在您的 rebase 之后,本地 存储库有一个新的(不同的哈希 ID)提交 E'

              C--D--E   [reflog / ORIG_HEAD access only]
             /
    ...--A--B
             \
              E'  <-- somebranch (HEAD)
    

    当您对其他 Git 运行 git push &lt;othergit&gt; somebranch 时,其他 Git 会将其分支提示提交哈希 ID 呈现给您的 Git,而您的 Git 会将提交 E' 的哈希 ID 呈现给它们。他们显然没有E',因为你只是自己做的,所以他们说他们想要它(或没有它),你的Git向他们展示B;如果他们没有那个,他们也会接受那个提交,如果需要的话,A 也会接受,依此类推。

    在某些时候,您的 Git 达到了他们确实拥有的某个提交,或者用完了要发送的提交哈希 ID。您的两个 Git 现在就要发送的内容达成一致,并且 - 作为这些协商的结果 - 您的 Git 知道他们已经拥有哪些 commits,并从中知道哪些 tree 和 blob 对象 他们也有(暗示他们有,例如,提交A,因此也有所有早期的提交)。

    你的 Git 现在——通常是1——准备一个所谓的瘦包。这是您看到“计数对象”和“压缩对象”内容的地方。精简包仅包含重建您发送的提交所需的那些对象:例如,在我们的特定示例中,提交E'B。这包括他们没有的树和 blob 对象——提交 A 的存在并不暗示这些对象——但不包括他们确实拥有的树和 blob 对象。

    这就是使包成为“瘦”包的原因:允许瘦包对丢失的对象进行增量压缩。假设提交 A 有一些文件由 10 兆字节的 blob 对象表示,而提交 B 和/或 E' 有一些文件不是 100% 相同,但共享该 10 兆字节对象的 99%。精简包的新对象可以进行增量压缩,即从对象 _____ 中取出 9.9 MB(用哈希 ID 填空)并添加剩余的 100 kB。普通包必须包含这个“基础对象”,而瘦包则不需要。

    接收 Git 必须:

    • 取来的薄包
    • 检查传入的提交,并决定是否接受它们
    • 如果它们被接受,则“修复”薄包装或将对象转换为松散(未包装)的对象。

    接收 Git 现在拥有新提交所需的所有对象,可以是松散对象,也可以是新的固定、不再精简的包。假设是后者,这个不再精简的包存储在该存储库中,因此新对象(如果需要,可能还包括从其他包中检索到的一些对象)现在都在该存储库中,在这个现在常规的包中。

    (在某些时候,重新包装包装会变得有利可图。这部分变得相当复杂。)


    1这取决于您的 Git 和他们的 Git 之间用于通信的协议。另一种选择是一次上传每个对象,这在通过网络发送的字节数方面往往非常浪费,因此人们现在通常不使用旧协议。

    【讨论】:

      猜你喜欢
      • 2015-12-08
      • 2017-09-21
      • 2019-02-12
      • 1970-01-01
      • 2019-08-08
      • 2021-04-13
      • 1970-01-01
      • 2013-07-29
      • 2018-05-26
      相关资源
      最近更新 更多