如何移除已应用的git补丁?

85

我有一个 Git 仓库,在测试环境中应用了许多补丁。

git apply --stat --check --ignore-whitespace /home/kent/Desktop/patches/test.patch --exclude .gitignore

git am -s --ignore-whitespace /home/kent/Desktop/patches/test.patch --exclude .gitignore --exclude .gitignore

目前,如果我需要移除一个补丁并应用一个新的补丁,我会克隆现有内容,重新应用所有测试补丁,然后再次推送。这个过程有点繁琐,而且有时会导致错误,我也会错过一两个补丁。

我想知道是否有一种方法可以移除一个补丁并应用一个新的补丁。

另外,如果每次提交到补丁中都可以添加一种方法,那么我可以使用:

git revert <<commit id>>

以上方法并非始终适用于我。


6
如果您使用 git diff --patch 命令,那么 git apply -R <patch> 命令无法起作用吗? - Ash
1
@ash,看起来对我有效。谢谢。 - coldy
好的,我已经申请为答案,并可以在今晚更新/详细说明。 - Ash
如果您对 Git 不是很熟悉,那么更详细地解释一下会更好,这样我就可以更深入地理解答案了。 - coldy
2个回答

169

简述

您可以使用以下命令还原一个补丁:

$ git apply -R <patch>

您可以通过以下方式之一生成补丁:

这将从差异中生成补丁

$ git diff --patch > 0001-some-modifications.patch

如果您只想为最新的提交生成补丁:

$ git show --patch HEAD^ > 0001-some-modifications.patch

您可以从 HEAD 生成前 3 个提交的补丁:

$ git show --patch HEAD~3 > 0001-some-modifications.patch

您可以通过以下方式应用补丁:

$ git apply -- 0001-some-modifications.patch

您可以使用以下命令还原补丁:

$ git apply -R <patch>
当您生成补丁时,它只是带有元数据的差异; 文件、行号的添加/删除; 大致如下:
commit 9dad147cbf16befecdef2e812c1249499bdef5ac
Author: My Name <email@example.org>
Date:   Mon Dec 21 20:46:01 2015 +0000

    Example commit message.

diff --git a/src/example.md b/src/example.md
new file mode 100644
index 0000000..ab73512
--- /dev/null
+++ b/src/example.md
@@ -0,0 +1,3 @@
+# Example document
+
+ Hello World
所以当你使用git apply时,你实际上是按照树的方式应用编辑。当你运行git apply -R时,git会简单地对补丁执行相反的操作。

2
使用 HEAD~3 为我创建一个来自单个提交的补丁。 - Miha_x64
HEAD~3 指的是 HEAD 引用的前三个提交。它类似于一个解析为提交的表达式。 - undefined

3
我在Windows上使用git,它的工作方式与Linux有些不同。具体来说,我发现当我运行以下命令时:
git apply -R C:\downloads\mypatch.patch

这可能是在错误的目录中运行。我不得不将它复制到我正在应用补丁的本地目录中。我还遇到了一些错误,例如:
error: product/build.gradle: No such file or directory
error: main/generator/generator.js: No such file or directory

这些文件非常奇怪,因为这些文件在我补丁中指定的目录中。我找到的唯一解决办法是手动修改补丁。我不得不在目录和文件名前添加./。所以我把它改成了这样:
Index: build_scripts/product/build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- build_scripts/product/build.gradle  (revision 537fbcc1ebdf65652896eaaf2a315cc44a24ba6c)
+++ build_scripts/product/build.gradle  (date 1594123740523)
@@ -304,7 +304,7 @@
       from("$repoRootDir/src/main/nodejs/utils/") {
         include "common_*.js"
       }

转换为:

Index: ./build_scripts/product/build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- ./build_scripts/product/build.gradle    (revision 537fbcc1ebdf65652896eaaf2a315cc44a24ba6c)
+++ ./build_scripts/product/build.gradle    (date 1594123740523)
@@ -304,7 +304,7 @@
       from("$repoRootDir/src/main/nodejs/utils/") {
         include "common_*.js"
       }

唯一的变化是在3个不同的"build_scripts/product/build.gradle"字符串之前添加了"./"。
另外,另一个好的提示是git apply命令可以使用"-v"参数来提供更多详细信息,这样你可以看到它首先检查补丁是否安全可应用,然后再应用补丁。

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