94

我正在尝试使用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仅将“bug fix 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”应用第一个大块。第二个大块头,我尝试编辑。我最初尝试删除底线 - 那没有用。完全离开大块头也不行,我不知道为什么。

4

13 回答 13

116

这就像在这个 git-add 帖子中一样吗?

手动编辑大块头非常强大,但如果您以前从未这样做过,也会有点复杂。
要记住的最重要的事情:除了任何其他缩进之外,差异总是缩进一个字符。
角色可以是:

  • 一个空格(表示未更改的行),
  • a-表示该行已被删除,
  • 或 a+表示已添加该行。

没有其他的。它必须是空格、- 或 +。其他任何事情,您都会得到错误
(更改的行没有字符,因为这些是通过删除旧行并将更改的行添加为新行来处理的)。

因为你已经在你最喜欢的文本编辑器中打开了 diff(你确实配置了 Git 以使用你最喜欢的文本编辑器,对吗?),你可以做任何你想做的事情——只要你确保得到的 diff 干净地应用。

这就是诀窍。如果您以前从未这样做过,Git 会告诉您“您编辑的大块不适用。再次编辑?” 很多时候,你会开始讨厌自己,因为你无法弄清楚这一点,即使它看起来很容易(或者 Git,因为它无法弄清楚你想要什么)。

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

另一件事是差异仍然必须有意义。“感”意味着可以干净利落地应用。确切地说,如何创建合理的差异似乎是一种黑暗艺术(至少现在对我而言),但您应该始终记住原始文件的外观,然后相应地计划您的 -s 和 +s。如果你经常编辑你的帅哥,你最终会掌握它的窍门。

另请参阅git add -p 上的此提交

Ortomala Lokni回答是指Joaquín Windmüller博客文章“ Selectively select changes to commit with git (or Imma edit your hunk)

Git 想做的不是计算行数,而是在应用所述已编辑的块之前合并重叠的块(当编辑一个块时)。
这是在 2018 年年中讨论的,并且会避免出现以下情况:

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

于 2010-07-16T20:39:19.090 回答
54

当然,我迟到了,但仍然想记录一下,去年在 git 邮件列表上讨论了这个问题,看起来从那以后没有太大变化。

这个特殊的问题源于分裂试图编辑同一个大块。正如 Jeff King 最初发布的那样,对潜在问题的分析基本上是:

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

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

Jeff 以一个非常实用的解决方法结束了他的帖子,该解决方法总是成功的,因此强烈推荐:

所以总的来说,我认为拆分和编辑同一个大块本质上是危险的,并且会导致这些问题。而且由于编辑提供了功能的超集,我认为您应该只进行编辑,并根据您的喜好允许应用或不应用大块的第一部分。

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

于 2010-12-21T14:45:43.660 回答
37

对于这个特定的示例,您需要调整大块中的行号。换行:

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

所以它改为:

@@ -2,7 +2,8 @@
于 2010-07-17T08:44:58.963 回答
22

正确修改大块标题(例如@@ -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
  • 如果删除以 - 开头的行,则将一个添加到新行数(大块标题的最后一位)
  • 不要删除其他线(参考线)。

这应该允许您快速修改大块以选择您想要的部分。

于 2018-01-24T16:58:14.907 回答
19

当您不想删除暂存待删除的行时,如

 first line
-second line
 third line

在要保留第二行的地方,请确保将 替换-为空格,而不是删除整行(就像删除添加的行一样)。Git 将使用该行作为上下文。

于 2013-03-24T22:18:15.017 回答
17

我最近从阅读这个线程中弄清楚了如何进行手动编辑。

我使用的技巧是,如果我有这样的差异:

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

诀窍是完全删除我不想要的两行,使生成的差异看起来像:

+ Line to add
+ Line to add

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

于 2011-04-07T08:06:36.020 回答
7

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

如果您发现稍后可能需要在 Git 自动选择的块中编辑某些内容,最好只编辑整个块,而不是拆分、暂存一半,然后再编辑另一半。Git 会更好地解决这个问题。

于 2012-03-20T18:05:24.717 回答
6

我来这个问题是为了寻找相同问题的解决方案,但无法弄清楚如何更改大块中的行号(如上所述)以让 git 在我的情况下接受它。我发现了一个更好的方法来做到这一点git gui。在那里,您可以选择差异中要暂存的行,然后右键单击并选择“从提交中暂存行”。我记得git-cola也有同样的功能。

于 2011-10-06T08:14:31.727 回答
5

当我收到此错误时,我遇到的另一个问题是保存编辑文件时行尾发生了变化。

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

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

git config --global core.editor "notepad++"
于 2012-11-12T21:03:18.430 回答
5

奇怪的“您编辑的大块不适用”消息的一个原因(可能伴随着诸如“错误:补丁片段没有行头的补丁片段......”)可能是您的编辑器,如果它被配置为去除尾随空格。这显然会导致重大问题,因为补丁将空行编码为带有一个空格的行,如果使用这样的编辑器保存,任何包含空行的大块都将无法应用。因此,实际上,任何包含任何未更改的空行的块在编辑后都将无法应用,如果剥离尾随空格处于打开状态。

于 2018-06-20T14:33:38.527 回答
0

仅供参考,我遇到了一个稍微相关的错误......当我按照上面建议的说明添加补丁时......它没有显示任何错误。我一再要求我上演同一个大块……我注意到我正在运行旧版本的 Vim 7.4……我升级了 vim,它现在按预期工作。希望这会帮助某人..

于 2018-12-26T16:51:27.350 回答
0

我曾经有这个问题。如果在 Windows 中使用 VIM 进行交互式添加,则不必调整块头(@@ 之间的东西),您所要做的就是将文件行结尾设置为 Unix (LF)。

在 VIM 编辑器中,只需在写入/退出之前的某个时间执行以下命令:

:set ff=unix
于 2021-02-05T19:48:51.183 回答
0

问题通常可能是补丁未正确完成或更具体的问题,我将在帖子底部描述,

如何在 VIM 中编辑

如果vim是编辑器,您应该这样做的方式是将光标放在该行中的第一个字符上,然后esc根据当前字符和内容执行以下操作(假设您处于默认的命令模式或按下 之后)你想做:

  1. 对于以 ' ' 空格开头的行,表示不变:

    • 如果你想删除它然后输入r-
  2. 对于以 ' ' 开头的行,-这意味着它将被删除(或替换):

    • 如果您不想删除它,请输入r (即 r 然后空格)
    • 注意行的顺序,见下文
  3. 对于带有 ' +' 的星号行,这意味着它将被添加(或替换-之前的 ' ' 行):

    • 如果您不想添加它,请输入dd

处理线订单问题

此外,您可能希望围绕行移动,以便该+行正好在该-行之后,否则+添加的行将在未更改的行之后移动,如下例所示:

假设您在编辑之前有以下补丁:

-Line1
-Line2
+NewLine1
+NewLine2

并且您只想暂存第一行,请勿执行以下操作:

-Line1
Line2
+NewLine1

因为它会导致NewLine1AFTER 结束Line2(除非这是您想要的),而是使用此处描述的 VIM 命令移动行

保存

完成后,只需键入即可:wq

错误的另一个原因

git add如果在检查补丁时更改也被外部修改,您也可能会收到此错误消息(即使您做的一切都正确) 。

(例如,您使用另一个终端或 GUI 来进行更改。)

这会导致行号在实际尝试应用更改时失败。

在这种情况下,您应该先退出(通过使用 ' q' 等)然后重新启动。

于 2021-10-21T21:11:00.710 回答