检查是否已应用git apply

11

这个问题是关于 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失败,那么git apply abc.patch -R --check && git apply abc.patch将会被执行,它会检查补丁是否已经被应用过(git apply abc.patch -R --check),如果是这种情况,它会回显“already applied”。

但我不喜欢这种方式,难道在git的apply中没有类似的内置解决方案吗?

2个回答

7

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

例如:如果补丁文件说“删除这 50 行中的一行,剩下 49 行”,则有明确定义的结果:

  • 少于 49 行或多于 50 行,补丁文件将无法应用:无论是 get apply --check 还是 git 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 都成功,则需要增加补丁的上下文以消除歧义。

如果不是手动进行操作,甚至可以通过编程方式重复测试增加补丁上下文,直到达到预期效果。


6
简短的回答是不行,或者至少通常不行。
考虑一下:一个“补丁”是一组指令,告诉你“删除这一行”和“添加这些其他行”。假设文件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

换句话说,输入文件非常枯燥,至少在最后一部分是如此,因为它只不停地重复“这个文件很无聊”。
对文件的更改是删除其中一个无聊的行。背景是更多同样枯燥的行,然后是“文件结束”。
自从生成补丁以来,有人修改了文件的顶部,所以它不再只有10(或9)行枯燥的行,但它仍然以至少四行枯燥的行结尾。现在,该文件超过50行,大多数顶部行相对而言相当令人兴奋。
作为聪明的人,你能否判断是否已经应用了对此文件的补丁?我只会告诉你,可能已经应用了补丁,以及添加了许多令人兴奋的行的其他更改。
如果你无法判断,那么你为什么要相信Git可以呢?我不知道你怎么想,但我无法确定添加令人兴奋的行的更改是否也删除了最后一行枯燥的行。
(现在,在某些情况下,特别是如果你有那个“index 87cdbbd..3d8696b 100644”行,有一种方法可以确定,前提是你还有一个提交的文件版本,其哈希ID为“87cdbbd”,因为现在我们可以提取该特定版本的文件。但是你没有说你是否有索引行,如果有的话,是否还有一个具有匹配哈希ID的blob。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接