git add --interactive"你编辑的hunk不适用"

Jos*_*osh 80 patch interactive git-add

我正试图git add --interactive有选择地为我的索引添加一些更改,但我不断收到"你编辑的hunk不适用.再次编辑..."消息.即使我选择了e选项,我也会收到此消息,并立即保存/关闭我的编辑器.换句话说,根本不编辑hunk,补丁不适用.

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

原始档案:

first change
second change off branch
third change off branch
second change
third change
fourth change
Run Code Online (Sandbox Code Playgroud)

新文件:

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
Run Code Online (Sandbox Code Playgroud)

我试图展示如何使用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
Run Code Online (Sandbox Code Playgroud)

我回答分裂,接着是"否"来应用第一个大块头.第二个大块头,我尝试编辑.我最初尝试删除底线 - 这不起作用.彻底抛弃大块头也不起作用,我无法弄清楚原因.

Von*_*onC 100

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

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

  • 空格(表示不变的线),
  • a -表示该线被移除,
  • +表示已添加该行.

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

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

这就是诀窍.如果您以前从未这样做过,Git会告诉您"您编辑的大块不适用.再次编辑?" 通常情况下,你会开始讨厌自己无法解决这个问题,即使它看起来很容易(或Git,因为它无法弄清楚你想要什么).

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

另一件事是差异仍然有意义."Sense"意味着它可以干净利用.究竟你如何创建一个明智的差异似乎是一个黑暗的艺术(至少现在对我来说),但你应该始终记住原始文件的样子,然后相应地计划你的-s和+ s.如果你经常编辑自己的帅哥,你最终会掌握它.

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

  • 我没有用空格替换删除的' - ',从而搞砸了缩进.谢谢!! (9认同)
  • 感谢您的链接,但我已经看过了.我没有添加/留下额外的一行.问题在于行号,但我仍然不理解修复. (5认同)

Nie*_*ser 44

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

这个特殊问题源于分裂尝试编辑同一个大块.最初由杰夫金发布的分析基本问题主要是:

嗯.好的我明白了."这个差异应用"检查将分割补丁的两个部分都提供给git-apply.但当然第二部分永远不会正确应用,因为它的上下文与第一部分重叠,但不考虑它.

使用编辑过的补丁进行检查就可以了.但是,这并没有考虑到您编辑的补丁可能无法长期应用,具体取决于您是否接受拆分补丁的另一半.我们还不知道,因为用户可能没有告诉我们(他们可能已经跳过了上半部分,然后在编辑步骤后再回到它).

杰夫以非常实用的解决方案总结他的帖子,总是成功,因此强烈推荐:

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

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

  • 谢谢,这确实比摆弄线号更容易. (6认同)
  • 这是该主题中的最佳答案。请勿拆分和编辑。只需编辑即可。 (5认同)
  • 这是我的问题。需要我的大块头变小。在交互式中执行拆分。拆分不是我想要的,所以我决定尝试手动编辑。一直收到错误。重新开始,第一次尝试。 (3认同)

Wil*_*ell 37

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

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

所以它改为:

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

  • 经过一番挖掘后,我发现这些行显示"从文件范围"和"到文件范围".我真的不明白将1更改为2背后的逻辑.我尝试了它,但它有效,但我不明白为什么"源文件范围"会发生变化.原始文件是相同的,无论我是应用整个补丁,还是只是编辑的大块.你能进一步澄清,还是指出统一差异格式的下降参考.我找不到一个是不成功的. (14认同)
  • 有关更改行号的更多信息,请?为什么我们要这样做?如何?每个数字是什么意思? (14认同)
  • @Josh:http://stackoverflow.com/questions/2529441/how-to-work-with-diff-representation-in-git可以提供帮助,即使我没有完全获得统一格式.@William +1 (8认同)
  • @Josh:在调查它看起来可能是一个错误.编辑hunk后,git会通过检查*all*hunks是否适用来尝试验证补丁(这可能过多).不幸的是,在这种情况下,这意味着正在检查前一个hunk(您没有应用),并且存在一些重叠导致git apply --check失败.我不知道一个优雅的解决方案; git可能在这里过于谨慎做正确的事情. (5认同)
  • @WilliamPursell 什么版本的 git?我已经切换到一台新计算机并运行 git v2.17.0,突然间我的补丁编辑不再有效。 (4认同)
  • 这个答案如何帮助_理解_问题和解决方案?可悲的是,人们将这样的帖子标记为“已接受的答案”,只是因为它解决了他们当前的问题,但绝对没有解释任何内容,而忽略了更好的答案,这些答案不仅解决了问题,而且还解释了问题。 (3认同)
  • 不过,看起来现代版本的git可以正确处理此问题。 (2认同)

Ros*_*one 14

如果您不想删除暂存以进行删除的行,请参阅

 first line
-second line
 third line
Run Code Online (Sandbox Code Playgroud)

如果你想保留第二行,请确保-用空格替换,而不是删除整行(因为你要删除一行).Git将使用该行作为上下文.


Sed*_*rik 12

我最近想通过阅读这个线程如何进行手动编辑.

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

+ Line to add
+ Line to add
+ Line I dont want to include
+ Line I dont want to include
Run Code Online (Sandbox Code Playgroud)

诀窍是删除我不想完全使得生成的差异看起来像这样的两行.

+ Line to add
+ Line to add
Run Code Online (Sandbox Code Playgroud)

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

  • 我不能感谢你!我试图将 `+` 更改为 `' '` 至少一个小时。 (2认同)

Ort*_*kni 12

正确修改hunk标头(例如@@ -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.
Run Code Online (Sandbox Code Playgroud)

秘诀是...计数线:

  • 如果删除以+开头的行,则将一行减去新的行计数(hunk标题的最后一位).
  • 如果删除以 - 开头的行,则在新行计数(hunk标题的最后一位)中添加一行.
  • 不要删除其他线(参考线).

这应该允许您快速修改帅哥以选择您想要的部分.

  • 有没有办法自动编辑 hunk header 或配置 git 来确定适当的行数? (2认同)
  • 我在 Windows 中使用 git 时遇到了这个问题。我发现您不必对标题进行任何行计数或调整。如果 Vim 是活动编辑器,只需在写入/退出之前将行结尾设置为 Unix,git 就会弄清楚。:设置 ff=unix (2认同)

小智 7

您可以手动编辑行号,这在某些情况下非常有用.但是,您可能已经避免了这个特殊问题,而不是首先拆分大块.

如果你看到你可能需要稍后在Git自动选择的大块中编辑某些东西,最好只编辑整个大块而不是分割,分段一半,然后编辑另一半.Git会做得更好.


Jay*_*esh 6

我来到这个问题寻找相同问题的解决方案,并且无法弄清楚如何更改块中的行号(如上所述)以获得git接受它在我的情况下.我找到了一个更好的方法来使用git gui它.在那里,您可以选择要分级的差异中的线条,然后右键单击并选择"从提交中分割线条".我记得git-cola也有同样的功能.


KLe*_*ee1 5

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

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

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

git config --global core.editor "notepad++"
Run Code Online (Sandbox Code Playgroud)


Tim*_*imo 5

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