9

这个问题是关于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),如果是这种情况,它会回显“已经应用”

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

4

2 回答 2

4

简短的回答是否定的,或者至少一般情况下不会。

考虑一下:补丁是一组说明“删除此行”和“添加这些其他行”的说明。假设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)行枯燥的行,但它仍然以至少 4 行枯燥的行结束。该文件现在有超过 50 行长,其中大多数顶级文件相当令人兴奋,至少相对而言。

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

如果你不能说,为什么你会相信 Git 可以呢?我不了解你,但不知道添加激动人心的台词的更改是否也删除了最后的乏味台词。

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

于 2018-01-09T15:50:31.773 回答
2

实际上,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 --check两者git apply --reverse --check都成功,则需要增加补丁的上下文以消除歧义。

您甚至可以以编程方式测试重复增加补丁的上下文,直到它按预期工作,如果您不是手动进行的话。

于 2021-03-22T23:44:05.957 回答