git add -p(交互式修补程序)和编辑模式给出“ XX行处的修补程序损坏”错误

时间:2018-08-14 15:52:02

标签: git edit git-patch

我将自己的更改添加到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

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

1 个答案:

答案 0 :(得分:3)

[注意:评论变成了答案-上面的部分是您所需要的,其余的只是说明而已]

补丁块所做的唯一更改是添加了这一行。如果删除添加的行,则修补程序将成为不更改文件而更改文件的指令,这不是很明智。这里的错误消息有点愚蠢,但是您需要做的只是“跳过这一步”。

很多细节,只有有意思时才阅读

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

git show HEAD:README.txt

查看。在内部,此文件以特殊的仅Git格式存储(zlib压缩,甚至可能进一步压缩)-非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带有补丁程序(一组块,每个块均表示要添加和/或删除一些行),如果应用了补丁,则将更改索引版本以匹配工作树版本。如果Git遵循补丁程序中的所有说明,那将更改文件的索引副本以匹配工作树副本,就像git add一样。

但是现在Git让您经历了那个补丁,一次只能补丁一次,并且:

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

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

请注意,git add -p有一个同伴:运行git reset -p README.txt告诉Git,它应该比较HEAD:README.txt:README.txt(HEAD和索引版本),并准备一个补丁如果跟在字母后面,则将更改索引副本,以使其再次与HEAD副本匹配。然后,Git会执行与git add -p相同的过程。


最后,让我们快速看一下git status。这做了很多有用的事情,但是其中一个告诉您关于为提交而进行的更改没有为提交而进行的更改的步骤实际上包括运行两个{{ 1}}命令。第一个是:

  • git diff与索引有什么区别?

对于此处完全相同的每个文件,Git对此都保持沉默。但是,如果HEADHEAD:README.txt不同,则Git会告诉您:README.txt中存在准备提交的东西

列出所有这些文件后,Git运行第二个差异,这次找出:

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

在这里,任何不同的文件,Git都会告诉您没有上演提交的东西。那是因为您可以在该文件上运行README.txt,然后将其复制到索引中。

如果您现在要运行git add,那么Git将从现在索引中的任何内容进行 new 提交,因此{{1} } -vs-index会告诉您:在新提交中,这些文件将不同于当前提交中的文件。同时,索引- vs-work-tree会告诉您:这些文件可能可能不同,但是除非您git commit将它们保持不变。

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

关于新文件/未跟踪文件的事实就是为什么每个文件最多有三个副本的原因。如果创建一个新文件,则根本不在HEAD提交中。在您git add将文件复制到索引中之前,它也不会被跟踪。因此,您仅在工作树中开始一个副本。然后在索引和工作树中有两个。然后,您进行一次 new 提交,该提交变为当前的(HEAD提交,然后只有该新文件的三个副本。