git cherry-pick 实际上和 git show + git apply 一样吗?



难道是这样

git cherry-pick <rev>

其实

git show <rev> | git apply -3 -

???

由于运行任何一个都会给我带来完全相同的结果,并且如果我知道它们确实是等效的,我可以更好地了解使用 GIT 进行樱桃采摘的实际工作方式,因为它并不总是给我我期望的结果,但这可能是因为无法应用唯一的更改和樱桃采摘回退到三向合并(这就是-3在第二个命令上所做的),这将解释意外情况结果。

从技术上讲,git cherry-pick 的工作方式类似于 git 合并,其中,不是寻找"两个分支上存在的最佳修订版"来检查差异并合并它们,而是合并逻辑的"公共修订版"被迫成为您正在挑选的修订版的父级。

除了 Edmundo 的回答(这是正确的,我已经投了赞成票)之外,还有一堆其他琐碎的细节,包括关于二进制文件的临时评论(git show需要--binary才能生成二进制补丁),并且您可能还需要--full-index,在某些极少数情况下,缩写Index:行是不够的。1

此外,当然,git apply(带或不带-3)不介意脏索引和工作树,而git cherry-pick需要干净的索引和工作树,除非您添加-n。 而且,如果你省略-ngit cherry-pick会继续提交,git apply永远不会这样做。

尽管如此,是的,对于正常情况,这两者在功能上应该是等效的。


1若要实现此目的,Blob 哈希在缩写时必须是非唯一的。 这是在 Git 版本 1.7.2 中自动更正的,但如果使用core.abbrev或命令行标志强制使用特定的缩写长度,您仍然可以获得非唯一的哈希缩写。 添加--full-index可确保您获得独特的。

(如果您要长时间保存差异,将一堆对象添加到存储库,然后尝试git apply -3差异,那么以前明确的缩写Index:行现在可能会变得模棱两可。

注意:对于二进制文件,无论如何git apply都不起作用,在 Git 2.34(2021 年第 4 季度)之前不会:"git apply">(人)错误地计算了字节数,无法读取到二进制大块头的末尾。

参见 Jeff King (peff)的提交 46d723c(2021 年 8 月 9 日).
(由 Junio C Hamano --gitster-- 合并于 2021 年 8 月 30 日的提交 7e3b9d1)

apply:在解析二进制大块头时保持缓冲区/大小对同步

举报人:陈兴曼
署名:杰夫·金

我们通过使用以下代码循环访问缓冲区来解析二进制大块

llen = linelen(buffer, size);
...do something with the line...
buffer += llen;
size -= llen;

但是,在我们进入循环之前,有一个调用增加了"buffer",但忘记递减"size".
结果,我们的"size"偏离了该行的长度,随后对linelen()的调用可能会越过缓冲区的末尾寻找换行符。

修复很简单:我们只需要像在其他地方一样减小大小。

这个错误可以追溯到0660626("二进制差异:进一步更新.",2006-05-05,Git v1.4.1-rc1 - merge).
大概没有人注意到,因为它只有在补丁损坏时才触发,即便如此,我们也经常被运气"保存".
我们使用strbuf来存储传入的补丁,所以我们在那里过度分配, 另外,我们添加了一个 16 字节的 NUL 运行作为内存比较的 slop.
因此,如果这是意外发生的,常见的情况是,我们只是从 strbuf 的末尾读取一些未初始化的字节,然后产生预期的"此补丁已损坏"错误投诉。

但是,可以仔细构造一个从缓冲区末尾读取的情况.
包含的测试这样做.
当正常运行时,它将在此补丁之前和之后通过,但是使用像 ASan 这样的工具表明我们在此补丁之前获得越界读取,而不是之后。

相关内容

  • 没有找到相关文章

最新更新