检查 git apply 是否已经应用

check if git apply was already applied

这个问题是关于git apply

有没有办法区分:失败是因为...

  1. ...补丁 已经 应用
  2. ...源代码真的不同

我工作的目录不是 git 目录,因此我不能使用 git log 或其他目录。

我知道 -R(反向)选项,因此我当前的解决方法是:

git apply abc.patch || git apply abc.patch -R --check && echo already applied

这种方式 git apply abc.patch -R --check && git apply abc.patch 只会在 git apply abc.patch 失败时执行,然后检查它是否因为已经应用补丁 (git apply abc.patch -R --check) 而失败,如果是这样的话,它呼应 "already applied"

但我不喜欢它,git 的应用程序中没有类似内置解决方案的东西吗?

简短的回答是否定的,或者至少不是普遍如此。

考虑:补丁 是一组说明 "remove this line" 和 "add these other lines" 的说明。假设 file 的补丁完整地读取:

diff --git a/file b/file
index 87cdbbd..3d8696b 100644
--- a/file
+++ b/file
@@ -7,4 +7,3 @@ this file is dull
 this file is dull
 this file is dull
 this file is dull
-this file is dull

换句话说,输入文件非常乏味,至少在最后,它一直在重复 "this file is dull"。

对文件的 更改 是为了删除那些沉闷的行之一。 context 更多,同样沉闷的线条,其次是 "end of file".

自补丁生成后,有人修改了文件的top,使其不再只有10(或9)行沉闷的行,但它仍然以至少4行结尾沉闷的线条。该文件现在超过 50 行,其中大部分最上面的行相当令人兴奋,至少相对而言。

聪明人能不能判断一下这个文件的补丁有没有打过?我要告诉你的是补丁 可能已经应用也可能没有应用 ,以及在文件顶部添加许多令人兴奋的行的其他更改。

如果你不能说,为什么你会相信 Git 可以?我不了解你,但 无法判断添加令人兴奋的台词的更改是否也删除了最后的沉闷台词。

(现在,在某些情况下——尤其是如果你有那条 index 87cdbbd..3d8696b 100644 行——一种判断方式,提供 您还拥有哈希 ID 为 87cdbbd 的文件的已提交版本,因为现在我们可以提取文件的特定 版本 。但是您没有说您是否有索引行,如果有,您是否还有一个具有匹配哈希 ID 的 blob。)

实际上,git apply --reverse --check 是您正在寻找的“内置于 git”的解决方案。对于其他答案中描述的许多相同行的情况,您需要做的就是确保您的补丁文件具有 more/enough 上下文来消除歧义(例如 git diff -U60)。

示例:如果补丁说“删除这 50 条相同的行中的一条,留下 49 条”,则结果明确:

  • 如果少于 49 行或多于 50 行,则补丁不适用:get apply --checkgit apply --reverse --check 都会失败。
  • 正好有 49 行,补丁已经应用:git apply --check 将失败,git apply --reverse --check 将成功。
  • 恰好有 50 行未应用补丁:git apply --check 会成功,git apply --reverse --check 会失败。
  • 如果get apply --checkgit apply --reverse --check都成功了,您需要增加补丁的上下文来消除歧义。

如果您不是手动操作,您甚至可以通过编程方式反复测试补丁的上下文,直到它按预期工作。