git add --interactive "Your edited hunk does not apply"

Viewed 39953

I'm trying to use git add --interactive to selectively add some changes to my index, but I continually receive the "Your edited hunk does not apply. Edit again..." message. I get this message even if I choose the e option, and immediately save/close my editor. In other words, without editing the hunk at all, the patch doesn't apply.

Here's the exact example I'm using (I'm trying to put together a small demo):

Original file:

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

New file:

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

I'm trying to show how to use git add --interactive to only add the "bug fix 1" line to the index. Running interactive add on the file, I choose the patch mode. It presents me with

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

I respond with split, followed by "no" to apply the first hunk. The second hunk, I try to edit. I originally tried deleting the bottom line - that didn't work. Leaving the hunk alone completely doesn't work either, and I can't figure out why.

13 Answers

Of course I'm late to this but nevertheless wanted to mention for the record that this issue was discussed last year on the git mailing list and it looks like not much has changed since.

This particular issue stems from splitting and attempting to edit the same hunk. The analysis, as originally posted by Jeff King, of the underlying problem essentially is:

Hm. OK, I see. The "does this diff apply" check feeds both parts of the split patch to git-apply. But of course the second part will never correctly apply, because its context overlaps with the first part, but doesn't take it into account.

Doing the check with just the edited patch would work. But that doesn't take into account that your edited patch will potentially fail to apply in the long run, depending on whether or not you accept the other half of the split patch. And we can't know that yet, because the user may not have told us (they could have skipped the first half, and then come back to it later after the edit step).

Jeff concludes his post with a very pragmatic workaround that always succeeds, and is thus highly recommended:

So in general, I think splitting and editing the same hunk is inherently dangerous and is going to lead to these sorts of problems. And because editing provides a superset of the functionality, I think you should just edit and either allow the first part of the hunk to be applied or not depending on your preference.

By only choosing to edit a hunk not previously split, you will not have to deal with the line numbers.

It's important to also correctly modify the hunk header (e.g. @@ -1,6 +1,9 @@). Joaquin Windmuller reveal the secret of hunk header editing in one of his blog post.

The secrets of editing hunks

Editing the hunks can be confusing at first, the instructions that git gives you help but are not enough to get started.

# —||

# 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.

The secret sauce is…counting lines:

  • If you remove a line that starts with + then subtract one to the new line count (last digit of the hunk’s header).
  • If you remove a line that starts with - then add one to the new line count (last digit of the hunk’s header).
  • Don’t remove the other lines (reference lines).

This should allow you to quickly modify the hunks to select the parts you want.

You can manually edit the line numbers, that's definitely useful in some cases. However, you probably could have avoided this particular problem by NOT first splitting the hunk.

If you see that you'll probably need to edit something later in the hunk that Git has automatically chosen, it's best to just edit the whole hunk rather than splitting, staging half, and then editing the other half. Git will do a better job figuring that out.

One reason for weird "Your edited hunk does not apply" messages (likely accompanied with something like "error: patch fragment without header at line...") might be your editor if it's configured to strip trailing whitespace. This would obviously cause major problems as patches encode empty lines as lines with one space any hunk containing empty lines would fail to apply if saved with such an editor. So in effect any hunk containing any unchanged empty lines would fail to apply after editing with if stripping trailing whitespace is on.

I used to have this problem. If doing an interactive add in windows, using VIM, you don't have to tweak the hunk header (the stuff between the @@'s), all you have to do is set the file line endings to Unix (LF).

In the VIM editor, simply do the following command sometime before your write/quit:

:set ff=unix

FYI, I was getting a slightly interrelated error... when I add patched following the suggested instruction above... It was showing no error, however. I was getting it repeatedly asking me to stage the same hunk... I noticed I was running an older version of Vim 7.4... I upgraded vim and it's working as expected now. Hopefully this will help someone..

The issue might be in general that the patch wasn't done correctly or a more specific issue that I will describe in the bottom of the post,

How to Edit in VIM

The way you should do it if vim is the editor, is by placing the cursor over the first character in the line, and do the following (assuming you are in command mode which is the default or after pressing esc) based on the current character and what you want to do:

  1. For a line that starts with a ' ' space which means unchanged:

    • If you want to DELETE it then type r-
  2. For a line that starts with a '-' which means it will be removed (or replaced):

    • If you do NOT want to delete it then type r (that's r and then space)
    • Be careful with the order of the lines, see below
  3. For a line that was stars with a '+' which means it will be add (or replace the '-' line before):

    • If you do NOT want to add it then type dd

Handling the line order issue

Also you would probably want to move around lines so that the + line is right after the - line otherwise the + added line will be moved after the unchanged lines, as in this example:

Say you have the following patch before editing:

-Line1
-Line2
+NewLine1
+NewLine2

And you want to only stage the first line, the DO NOT do the following:

-Line1
Line2
+NewLine1

as it will cause NewLine1 to end up AFTER Line2! (unless this is what you want), instead move around the lines using the VIM commands described here

Saving

Once you are done just type :wq and you should be fine.

Another cause of the error

You can also get this error message (even if you did everything correctly) if while going through the patches git add the changes were also modified externally.

(For example you used another terminal or GUI to stage changes.)

This causes the line numbers to fail when actually trying to apply the changes.

In this case you should rather quit first (by using 'q' etc.) and then restart.

Related