git 添加 -p(交互式补丁)和编辑模式给出 "corrupt patch at line XX" 错误

git add -p (interactive patch) and edit mode gives a "corrupt patch at line XX" error

我正在使用 git add -p 将我的更改添加到提交中,现在我想使用手动大块编辑模式。

我就是这么帅:

# Manual hunk edit mode -- see bottom for a quick guide
@@ -46,6 +46,7 @@ function signIn(email, password) {
             }
         })
         .catch((error) => {
+            console.log(error);
             ToastAndroid.show(translations.translations.error_occurred, ToastAndroid.SHORT);
             that.setState({isLoading: false});
         });
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.

如果我完全删除添加的行(console.log)然后保存并退出编辑器,我会得到这个错误:

error: corrupt patch at line 12

我完全不知道自己做错了什么。

[注意:评论变成答案-上面的部分就是你需要的,剩下的只是解释]

patch hunk 所做的唯一更改是添加了这一行。如果把添加的那行去掉,patch就变成了改文件的指令,不改文件,不是很明智。这里的错误消息有点傻,但您需要的操作只是 "skip this one".

很多细节,如果感兴趣请阅读

请注意,在您进行下一次提交的任何时候,每个文件都有三个我称之为 活动副本 的副本。好吧,更准确地说,有 多达 三个这样的副本。第一个是您之前提交的任何内容,或者在您 运行 git checkout 时获得的提交中的内容。此副本存储在提交中,基本上是只读的:您不能更改它,因为它是该特定提交的一部分。但是您可以随时 访问 它。例如,给定一个 README.txt 文件,你可以 运行:

git show HEAD:README.txt

查看。在内部,这个文件以一种特殊的 Git-only 格式存储(zlib-deflated,甚至可能进一步压缩)——非 Git 程序通常无法读取该文件的副本。

在您的工作树中也有同一个文件的副本,您可以在其中进行处理。该副本以其普通计算机格式存储,以便您阅读。你的编辑器——atom 或 emacs 或 sublime 或 vim 或任何你使用的编辑器——都可以读写文件。你的编译器,如果你编译程序,可以读写它,等等。您不需要对该文件做任何特殊的事情,因为它就像任何其他文件一样。奇怪的是,Git 几乎不关心 README.txt-Git 的这个副本必须放手,因为 任何东西都可以改变!

但是 README.txt 也有 第三个 副本,这就是 Git 所称的 index,或暂存区,或缓存。 (Git 使用哪个名称取决于您正在查看哪个 Git 文档。)您可以通过 git show :README.txt 查看的第三个副本位于特殊的 Git-仅格式,但与 提交 中的副本不同,您可以 覆盖此副本。通常 方式 覆盖这个文件是使用 git add,它只是 将工作树文件复制到索引 .

因此,索引 :README.txt 开始于 匹配 HEAD:README.txt 文件。如果更改工作树副本,HEAD 和索引版本仍然匹配。如果然后 git add README.txt,那会覆盖工作树副本中的索引副本,现在 HEAD:README.txtREADME.txt 不再匹配,但是 :README.txt 匹配 匹配 README.txt.

这就是 git add -p 出现的地方:如果某些文件的 index 副本和 work-tree 副本是不同的是,你可以让 Git 想出一个补丁——一组大块头,每个都说要添加 and/or 删除一些或多行——如果应用,将会 改变 与工作树版本匹配的索引版本。如果 Git 遵循补丁中的所有说明,那将更改文件的索引副本以匹配工作树副本,就像 git add 所做的那样。

但现在 Git 让 完成那个补丁,一次一个补丁,并且:

  • 告诉Git按原样应用;或
  • 告诉Git完全跳过它;甚至
  • fiddle 以及更改说明,以便 部分 应用补丁。

当您选择应用特定的补丁程序时(可能在编辑它之后),Git 提取文件的索引版本,应用那组指令,然后继续查看下一个.如果您跳过它,Git 将继续进行下一个。

注意 git add -p 有一个同伴:运行ning git reset -p README.txt 告诉 Git 它应该比较 HEAD:README.txt:README.txt (HEAD 和索引版本),并准备一个补丁,如果紧跟字母,更改索引副本,使其再次匹配 HEAD 副本。然后 Git 经历与 git add -p.

相同的过程

最后,让我们快速浏览一下git status。这做了很多有用的事情,但是它告诉你关于 changes staged for commitchanges not staged for commit 的那个由 运行ning 本质上是两个 git diff 命令。第一个是:

  • HEAD 与指数有何不同?

对于此处完全相同的每个文件,Git只是对此保持沉默。但是,如果 HEAD:README.txt:README.txt 不同,Git 会告诉您 README.txt.[=45 中为提交 准备了一些东西=]

列出所有这些文件后,Git 运行第二次比较,这次是为了找出:

  • 索引与工作树有何不同?

在这里,任何不同、Git 的文件都会告诉您有一些东西没有为提交 暂存。那是因为您可以 可以 运行 git add 在该文件上,将其复制到索引中。

如果你现在 运行 git commit,Git 将使 new 提交来自 无论是什么现在在索引中 ,所以 HEAD-vs-index 告诉你:这些文件 不同,在这个新提交中,从 current commit. 同时 index-vs-work-tree 告诉你:这些文件 could 会有所不同,但不会,除非你 git add 他们。

这第二个差异也是发现任何 未跟踪 文件的步骤。一个未跟踪的文件,很简单,是一个位于工作树中但不在索引中的文件。如果这样的文件被 忽略 ,Git 闭嘴。如果未跟踪的文件 而不是 被忽略,Git 会告诉您它未被跟踪。请注意,根据定义,索引中 的文件会被跟踪,因此 Git 甚至从不检查忽略指令。

这个关于新文件/未跟踪文件的事实是每个文件有 多达 三个副本的原因。如果您创建一个新文件,它根本不在 HEAD 提交中。在您 git add 将文件复制到索引之前,它也是未跟踪的。因此,您从一份副本开始,仅在工作树中;那么你有两个,在索引和工作树中。然后你做了一个 new 提交, 成为 当前 (HEAD) 提交,然后才有那个新的三个副本文件。