git add --interactive“您编辑的大块头不适用”


86

我试图用来git add --interactive有选择地向索引添加一些更改,但是我不断收到“您编辑的块不适用。请再次编辑...”消息。即使选择e选项,我也会收到此消息,并立即保存/关闭编辑器。换句话说,完全不编辑块,补丁将不适用。

这是我正在使用的确切示例(我正在尝试编写一个小型演示):

原始文件:

first change
second change off branch
third change off branch
second change
third change
fourth change

新文件:

Change supporting feature 1
first change
second change off branch
third change off branch
second change
third change
fourth change
bug fix 1
change supporting feature 1

我试图显示如何git add --interactive仅将“错误修复1”行添加到索引。在文件上运行交互式添加,我选择补丁模式。它给我带来了

diff --git a/newfile b/newfile
index 6d501a3..8b81ae9 100644
--- a/newfile
+++ b/newfile
@@ -1,6 +1,9 @@
+Change supporting feature 1
 first change
 second change off branch
 third change off branch
 second change
 third change
 fourth change
+bug fix 1
+change supporting feature 1

我用split响应,然后单击“ no”以应用第一个块。第二个大块头,我尝试编辑。我最初尝试删除底线-没用。完全放弃大块头也不起作用,我也不知道为什么。


确保此处的一件好事是-,不要在文件开头不存在的行的开头添加;这是一个差异,它不能删除尚不存在的行。因此,如果diff中的一行以开头+并且您将其更改为-git,就会变成WTF?因为现在不存在标记为删除的行开头(而是将该行标记为添加,并且当标记为添加的行被标记为删除时,git无法删除文件中尚未存在的行) 。
leeand00 '16

1
在我的情况下,还要检查行尾(LF,CRLF),它不是为CRLF而不是一个LF!
阿尔贝托·里维利

Answers:


37

对于此特定示例,您需要调整大块中的行号。更改行:

@@ -1,6 +2,8 @@

因此它改为:

@@ -2,7 +2,8 @@

16
经过一番挖掘,我发现这些行显示了“从文件范围”和“到文件范围”。我真的不了解将1更改为2的逻辑。我尝试了一下,它确实起作用了,但是我不理解为什么“从文件范围”更改。不管我是应用整个补丁还是只是编辑的块,原始文件都是相同的。您能否进一步说明,还是让我参考统一差异格式的下降参考。我一直没有找到一个。
乔什(Josh)

9
@Josh:stackoverflow.com/questions/2529441/…可以提供帮助,即使我不完全了解统一格式的功能。@威廉+1
VonC 2010年

5
@Josh:调查它似乎是一个错误。在编辑了大块之后,git尝试通过检查所有大块是否都适用来验证补丁(这可能过多)。不幸的是,在这种情况下,这意味着正在检查先前的块(您未应用的块),并且存在一些重叠,导致git apply --check失败。我不知道一个优雅的解决方案。git可能在这里过分谨慎,所以做对了。
威廉·珀塞尔

22
有关更改行号的更多信息,请?为什么我们必须这样做?如何?每个数字是什么意思?
比尔

4
@WilliamPursell什么版本的git?我已经切换到新计算机并运行git v2.17.0,突然间我的补丁编辑不再有效。
丹尼斯

105

这是在git-add帖子中吗?

手动编辑大块头功能非常强大,但是如果您以前从未做过,则还有些复杂。
要记住的最重要的一点:diff总是以一个字符缩进,此外还有其他缩进。
字符可以是:

  • 一个空格(表示一行不变),
  • -指示线除去,
  • +表明该行已添加。

没有其他的。它必须是空格,-或+。否则,您将收到错误
(更改的行没有字符,因为这些错误是通过删除旧行并将更改后的行添加为新行来处理的)。

由于您已在自己喜欢的文本编辑器中打开了差异(您已将Git配置为使用自己喜欢的文本编辑器,对吗?),您可以做任何您想做的事情-只要确保所产生的差异完全适用。

诀窍就在其中。如果您以前从未做过,Git会告诉您“您编辑的大块头不适用。再次编辑?” 很多时候,您会因为无法解决这个问题而开始讨厌自己,即使它看起来如此简单(或Git,因为它无法弄清您想要的是什么)。

经常使我绊倒的一件事是我忘记了一个字符的缩进。
我会用-标记要删除的行,但在大多数插入a的文本编辑器中-,它不会覆盖以前的空间。这意味着您要在整行中添加额外的空间,这又意味着diff算法无法找到/匹配原始文件中的行,这反过来又意味着Git会对您大喊大叫

另一件事是,差异仍然必须有意义。“感官”意味着可以干净地使用它。确切地讲,如何创建一个合理的差异似乎有些晦涩(至少现在对我而言),但是您应始终牢记原始文件的外观,然后相应地计划-s和+ s。如果您经常编辑自己的大块头,那么您最终将一窍不通。

另请参见对git add -p的提交

Ortomala Lokni答案参考JoaquínWindmüller博客文章“有选择地选择要使用git提交的更改(或Imma编辑您的大块头)

除了计算行数之外,Git想要做的是在应用所述已编辑的块之前合并重叠的块(当一个被编辑时)。
这是讨论中期-2018,并会避免类似的情况:

如果拆分大块,请编辑第一个大块,将尾随上下文行转换为删除,然后,如果尝试暂存第二个大块,它将失败。


5
感谢您的链接,但我已经看到了。我没有添加/离开其他行。问题出在行号上,但我仍然不知道解决方法。
乔什

9
我没有用空格替换已删除的'-'-从而导致缩进。谢谢!!
pedorro

只要确保您没有误解空白部分。我认为所有未更改的行都应该只是黑色的行-而不仅仅是缩进字符。。。一个小时的“编辑过的大块不适用”,直到我明白了为什么:-/
oligofren

@oligofren我不确定我是否了解您:为了使编辑后的大块适用于您,您做了什么?
VonC

1
@VonC:我首先想到应该更改- foo 为``(只是空白,而不是“空白整行”)。花了我一段时间才能理解它应该是foo。
oligofren '16

48

当然,我来晚了,但是有记录要提到的是,去年在git邮件列表上讨论了这个问题自那以后似乎没有太大变化。

此特定问题源于拆分尝试编辑相同的块。最初由Jeff King发表的对根本问题的分析基本上是:

嗯 好的我明白了。“此差异是否应用”检查将拆分补丁的两个部分馈送给git-apply。但是当然,第二部分永远不会正确应用,因为它的上下文与第一部分重叠,但是没有考虑到它。

仅使用已编辑的补丁进行检查即可。但这并没有考虑到您编辑的补丁从长远来看可能无法应用,这取决于您是否接受拆分补丁的另一半。而且我们还不知道这一点,因为用户可能没有告诉我们(他们可能跳过了前半部分,然后在编辑步骤之后又回到了前半部分)。

Jeff在他的文章结尾给出了一个非常务实的变通方法,该方法总是成功,因此强烈建议:

因此,总的来说,我认为拆分和编辑相同的块具有固有的危险性,并且会导致此类问题。并且由于编辑提供了功能的超集,我认为您应该只进行编辑,并允许根据您的喜好应用块的第一部分。

通过仅选择编辑以前未拆分的块,您将不必处理行号。


6
谢谢,这确实比摆弄行号容易得多。
michiakig

3
这是我的问题。需要我的大块头变小。进行了互动式拆分。分割不是我想要的,所以我决定尝试手动编辑。继续得到错误。重新开始,首先尝试。
凯尔(Kyle)

这是该线程中的最佳答案。不要拆分和编辑。只是编辑。
Dr_Zaszuś

就我而言,另一个问题来自^Mdiff文件中所示的Windows行尾。一旦我保存了带有CR结尾的文件,交互式编辑补丁就完成了!
6

谢谢,这对我有用。我不得不花很大的精力,所以我把它拆了,一切都坏了。保持未拆分状态可使一切正常运行。
Matthias Fischer

16

当您不想删除准备删除的行时,例如

 first line
-second line
 third line

在要保留第二行的位置,请确保-用空格替换,而不是删除整行(因为您将摆脱添加的行)。Git将使用该行作为上下文。


1
这对我来说还不清楚,我以为Git告诉我将线分隔成一个空格。
JackHasaKeyboard '16

15

重要的是还要正确修改块头(例如@@ -1,6 +1,9 @@)。Joaquin Windmuller在他的一篇博客文章中揭示了大头文件编辑的秘密。

编辑帅哥的秘密

首先,编辑大块头可能会造成混淆,git的说明可为您提供帮助,但不足以开始使用。

# —||

# To remove ‘-’ lines, make them ’ ’ lines (context).

# To remove ‘+’ lines, delete them.

# Lines starting with # will be removed.

#

# If the patch applies cleanly, the edited hunk will immediately be

# marked for staging. If it does not apply cleanly, you will be given

# an opportunity to edit again. If all lines of the hunk are removed,

# then the edit is aborted and the hunk is left unchanged.

秘诀是……计数线:

  • 如果删除以+开头的行,请在新行数(大块标题的最后一位)中减去1
  • 如果您删除以-开头的行,则在新行数(大块标题的最后一位)中添加一个
  • 不要删除其他行(参考行)。

这应该允许您快速修改块以选择所需的零件。


1
有没有一种方法可以自动编辑块头或配置git以确定适当的行数?
丹尼斯

您可能可以编写脚本来编写自己喜欢的编辑器以使其自动化。也许已经有了一些插件,但这取决于编辑器。
Ortomala Lokni,

13

我最近从阅读此线程中了解了如何进行手动编辑。

我使用的技巧是,如果我有一个类似的差异:

+ Line to add
+ Line to add
+ Line I dont want to include
+ Line I dont want to include

诀窍是完全删除我不需要的两行,使结果差异看起来像:

+ Line to add
+ Line to add

虽然这对于大多数人来说很可能显而易见,但直到今天才对我来说,我认为我应该分享自己的经验。请告诉我这种方法是否有危险。


2
我感激不尽!我试图改变+' '至少一个小时。
soumer

您知道,疯狂在做着同样的事情,并且期望得到不同的结果。我一直在对自己说20分钟,然后才发现我只需要删除:)
solidak '18

7

您可以手动编辑行号,这在某些情况下绝对有用。但是,通过不首先拆分块,您可能可以避免此特定问题。

如果您发现稍后可能需要编辑Git自动选择的块中的某些内容,那么最好只编辑整个块,而不是拆分,分段一半然后再编辑另一半。弄清楚这一点,Git会做得更好。


6

我来到了这个问题,寻求解决相同问题的方法,却想不出如何更改大块中的行号(如上面的建议),让git在我的情况下接受它。我发现了一种更好的方法git gui。在那里,您可以选择要暂存的差异中的行,然后右键单击并选择“提交阶段的行”。我记得git-cola也具有相同的功能。


这确实应该是答案。 git-cola似乎可以在Linux,Windows和MacOS上使用。
leeand00

5

出现此错误时,我遇到的另一个问题是保存编辑文件时,行尾已更改。

我使用Windows,并使用记事本进行编辑(仅使用Windows行尾保存)。我的代码是用Notepad ++编写的,我将其设置为具有Unix / Linux样式行的结尾。

当我更改设置以将Notepad ++作为默认的git编辑器时,我能够对大块文件进行编辑。

git config --global core.editor "notepad++"

1
这对我有用。但是我需要到notepad ++的完整路径,并且花了一些时间才能正确:(git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"' 根据您PC上安装notepad ++的位置进行调整)
Annabel

1
对我来说完全一样的问题。正是记事本引起了问题。将默认编辑器切换到Notepad ++之后,所有内容再次开始工作。
约翰尼·奥希卡

4

如果将其配置为剥离尾随空白,则可能是您的编辑器出现奇怪的“您编辑的大块不适用”消息的原因(可能伴随着类似“错误:补丁片段在行中没有标题...”)。显然,这将引起严重的问题,因为修补程序将空行编码为具有一个空格的行,如果使用这种编辑器进行保存,则包含空行的任何块都将无法应用。因此,实际上,如果打开了尾随空白,则包含任何未更改的空行的块均将在编辑后无法应用。


0

仅供参考,我收到一个稍微相关的错误...按照上面建议的说明添加补丁时...但是它没有显示错误。我反复得到它,要求我进行同样的操作。我注意到我运行的是Vim 7.4的旧版本。希望这会帮助某人..

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.