【问题标题】:git add --interactive "Your edited hunk does not apply"git add --interactive "你编辑的块不适用"
【发布时间】:2011-03-17 03:57:27
【问题描述】:

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

【问题讨论】:

  • 这里要确保的一件好事是,您没有在文件中不存在的行的开头添加-;这是一个差异,它不能删除不存在的行。因此,如果 diff 中的一行以 + 开头,而您将其更改为 -,那么 git 会 WTF 吗?因为现在标记为删除的行一开始就不存在(而是该行被标记为添加,并且当标记为添加的行被标记为删除时,git无法删除文件中尚不存在的行) .
  • 还要检查行尾(LF,CRLF)在我的情况下它没有申请一个LF而不是CRLF!

标签: interactive patch git-add


【解决方案1】:

这和this git-add post一样吗?

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

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

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

既然你已经在你最喜欢的文本编辑器中打开了 diff(你确实配置了 Git 以使用你最喜欢的文本编辑器,对吗?),你可以做任何你想做的事情 - 只要你确保生成的 diff 干净地应用.

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

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

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

另见commit on git add -p

Ortomala Loknianswer指的是Joaquín Windmüller博文“Selectively select changes to commit with git (or Imma edit your hunk)

Git 不想计算行数,而是在应用所述已编辑的块之前合并重叠的块(当编辑一个块时)。
那是discussed mid-2018,可以避免这样的情况:

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

【讨论】:

  • 感谢您的链接,但我已经看过了。我没有添加/留下额外的一行。问题出在行号上,但我仍然不明白修复方法。
  • 我没有用空格替换已删除的“-” - 从而搞砸了缩进。谢谢!!
  • 请确保您没有误解空格部分。我认为所有未更改的行都应该只是一条带有黑色的线 - 而不仅仅是缩进字符......有一个小时的“编辑过的大块不适用”,直到我明白为什么:-/
  • @oligofren 我不确定我是否理解你:你必须做什么才能让你编辑的大块头应用?
  • @VonC:我首先认为我应该将- foo 更改为` `(只是一个空格,而不是“一个空格整行”)。我花了一段时间才明白它应该是 `foo`。
【解决方案2】:

当然我迟到了,但我还是想记录一下,这个问题was discussed last year on the git mailing list,从那以后看起来并没有太大变化。

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

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

just 来检查编辑过的补丁就可以了。但是那个 没有考虑到您编辑的补丁可能会失败 长期申请,取决于你是否接受 分割补丁的另一半。我们还不知道,因为 用户可能没有告诉我们(他们可能跳过了前半部分,并且 然后在编辑步骤后返回它)。

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

所以总的来说,我认为拆分和编辑同一个大块是天生的 危险并且会导致这些问题。而且因为 编辑提供了功能的超集,我认为你应该 只需编辑并允许应用大块的第一部分或 不取决于你的喜好。

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

【讨论】:

  • 谢谢,这确实比摆弄行号要容易得多。
  • 这是我的问题。需要我的大块头更小。在交互式中进行了拆分。拆分不是我想要的,所以我决定尝试手动编辑。不断收到错误。重新开始,第一次尝试。
  • 这是该主题中的最佳答案。不要拆分和编辑。只需编辑。
  • 在我的例子中,一个额外的问题来自 Windows 行尾,在 diff 文件中显示为 ^M。一旦我保存了带有 CR 结尾的文件,交互式编辑补丁就通过了!
  • 谢谢,这对我有用。我不得不处理一大块,所以我把它拆开,一切都坏了。保持它不分裂使一切正常。
【解决方案3】:

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

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

所以它改为:

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

【讨论】:

  • 经过一番挖掘,我发现这些行显示了“从文件范围”和“到文件范围”。我真的不明白将 1 更改为 2 背后的逻辑。我试过了,它有效,但我不明白为什么“源文件范围”会发生变化。原始文件是相同的,无论我是应用整个补丁,还是只应用编辑过的大块。您能否进一步澄清,或指出统一差异格式的下降参考。我一直没找到。
  • @Josh:stackoverflow.com/questions/2529441/… 可以提供帮助,即使我没有完全了解统一格式的帅哥。 @威廉+1
  • @Josh:在调查时,它看起来可能是一个错误。编辑大块后,git 会尝试通过检查 all 块是否适用(这可能过多)来验证补丁。不幸的是,在这种情况下,这意味着正在检查前一个块(您没有应用),并且存在一些重叠导致 git apply --check 失败。我不知道一个优雅的解决方案; git 在这里过于谨慎可能是在做正确的事情。
  • 请提供有关更改行号的更多信息?为什么我们必须这样做?如何?每个数字是什么意思?
  • @WilliamPursell 什么版本的 git?我已经切换到新计算机并运行 git v2.17.0,突然间我的补丁编辑不再有效。
【解决方案4】:

正确修改大块标头也很重要(例如@@ -1,6 +1,9 @@)。 Joaquin Windmuller 在他的blog post 之一中揭示了大块标题编辑的秘密。

编辑帅哥的秘密

编辑帅哥一开始可能会让人困惑,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(大块标题的最后一位)
  • 如果您删除以 - 开头的行,则在新的行数中加一(大块标题的最后一位)
  • 不要删除其他线(参考线)。

这应该允许您快速修改帅哥以选择零件 你想要的。

【讨论】:

  • 有没有办法自动编辑hunk header或者配置git来确定合适的行数?
  • 您可能可以编写自己喜欢的编辑器来自动执行此操作。也许已经有一些插件,但这取决于编辑器。
  • 我在 Windows 中使用 git 时遇到了这个问题。我发现您不必对标题进行任何行数或调整。如果 Vim 是活动编辑器,只需在您的 write/quit 之前的某个时间将行尾设置为 Unix,git 就会弄清楚。 :set ff=unix
【解决方案5】:

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

 first line
-second line
 third line

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

【讨论】:

  • 这对我来说不是很清楚,我以为 Git 是在告诉我将这一行设为一个空格。
【解决方案6】:

我最近通过阅读这个帖子发现了如何进行手动编辑。

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

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

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

+ Line to add
+ Line to add

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

【讨论】:

  • 感激不尽!我试图将+ 更改为' ' 至少一个小时。
  • 你知道,疯狂就是做同样的事情却期待不同的结果。在我发现我只需要删除之前,我已经对自己说了 20 分钟 :)
  • 这应该是答案。很好很简单,谢谢!
【解决方案7】:

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

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

【讨论】:

    【解决方案8】:

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

    【讨论】:

    • 这确实应该是答案。 git-cola 似乎可以在 Linux、Windows 和 MacOS 上运行。
    【解决方案9】:

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

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

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

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

    【讨论】:

    • 这对我有用。但我需要 notepad++ 的完整路径,这需要一段时间才能正确:git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"'(根据您 PC 上的 notepad++ 安装位置调整此路径)
    • 对我来说完全相同的问题。是记事本引起了问题。一旦我将默认编辑器切换到 Notepad++,一切又开始工作了。
    【解决方案10】:

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

    【讨论】:

      【解决方案11】:

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

      【讨论】:

        【解决方案12】:

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

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

        :set ff=unix
        

        【讨论】:

          【解决方案13】:

          一般来说,问题可能是补丁未正确完成,或者是我将在帖子底部描述的更具体的问题,

          如何在 VIM 中编辑

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

          1. 对于以“ ”空格开头的行,表示未更改:

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

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

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

          处理订单问题

          此外,您可能希望在行周围移动,使+ 行紧跟在- 行之后,否则添加的+ 行将移到未更改的行之后,如下例所示:

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

          -Line1
          -Line2
          +NewLine1
          +NewLine2
          

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

          -Line1
          Line2
          +NewLine1
          

          因为它将导致NewLine1Line2 之后结束! (除非这是您想要的),而是使用the VIM commands described here 移动线条

          保存

          完成后只需输入:wq 就可以了。

          错误的另一个原因

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

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

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

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

          【讨论】:

            猜你喜欢
            • 2014-05-10
            • 2020-10-22
            • 2012-03-19
            • 1970-01-01
            • 2017-06-14
            • 2017-06-17
            • 2013-07-23
            • 1970-01-01
            • 2013-01-27
            相关资源
            最近更新 更多