【发布时间】:2022-11-06 18:25:31
【问题描述】:
我们收到了一个修改了大约 17000 个文件的大补丁。它的大小是5.2G。使用git apply -3 应用补丁时,12 小时后仍未完成。
我们将补丁拆分为每个文件的较小补丁,并一个一个地应用它们,这样至少我们可以看到进度。
再一次,它卡在了其中一个文件补丁上,仍然有 111M 大。它修改 HTML 文件。
我们将这个文件补丁分成每个块的更小的补丁,得到大约 57000 个块补丁。每个块补丁大约需要 2-3 秒,因此比应用文件补丁需要更多时间。我会尝试将它分成更多的块。
有什么方法可以有效地应用这么大的补丁吗?谢谢。
更新:
正如@ti7 建议的那样,我尝试了patch,它解决了这个问题。
就我而言,我们有两种大补丁。
一种是添加/删除大型二进制文件,二进制文件的内容作为文本包含在补丁中。其中一个二进制文件为 188M,删除它的补丁大小为 374M。
另一种是修改大文本,有数百万的删除和插入。其中一个文本文件是 70M 之前和 162M 之后。补丁大小为 181M,有 2388623 个插入和 426959 个删除。
经过一些测试,我认为这里的“大”描述了插入和删除的数量。
对于二进制补丁,
- git apply -3, 7 秒
- git 应用,6 秒
- 补丁,5 秒
对于文本补丁,
- git apply -3,卡住,10 分钟后未完成
- git apply,卡住,10 分钟后未完成
- 补丁,3 秒
二进制文件只有 1 次插入和/或 1 次删除。 git apply 或 patch 可以在几秒钟内完成。都是可以接受的。
文本有太多的插入和删除。显然,patch 在这种情况下要好得多。我在patch 上阅读了一些帖子,并了解到patch 的某些版本无法用于添加/删除/重命名文件。幸运的是,我机器上的patch 运行良好。
因此,我们将一体化补丁拆分为每个文件的较小补丁。我们首先尝试timeout 10s git apply -3 file_patch。如果无法在 10 秒内完成,请尝试 timeout 10s patch -p1 < file_patch。
最后,用了大约 1 个半小时的时间,将 17000 个补丁全部打上。这比应用多合一补丁并卡住 12 小时而无所事事要好得多。
我也试过patch -p1 < all_in_one_patch。只用了1m27s。所以我认为我们可以进一步改进我们的补丁流程。
【问题讨论】:
-
我从未使用过大于数十兆字节的 git 存储库。我的意思是整个回购,包括从项目开始的所有历史。我什至无法想象 5.2 GB 的变更集。有人提交了一些大型二进制文件吗?
-
@Code-Apprentice 就我而言,大型二进制文件不是问题。一个二进制文件只有一个块。它会很快失败或成功。问题是补丁文件太多,一些文本文件有太多块。
-
您也许可以使用
patch而不是git apply,然后添加并提交 -
作为背景知识,
git apply在开始写出修改后的文件之前尝试将整个补丁应用到内存中。目的是在补丁中途失败的情况下,它不会留下部分修改的工作树。 -
@ti7 我试过
patch。它非常迅速地应用了 111M 文件补丁,仅需 2 秒。请您将其写为答案,以便我接受吗?