views:

30

answers:

2

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]dit 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
third change
fourth change

New file:

Change supporting feature 1
first change
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.

Thanks for the help.

Josh

A: 

Is this like in this git-add post?

Manually editing the hunk is immensely powerful, but also a bit complicated if you've never done it before.
The most important thing to keep in mind: The diff is always indented with one character in addition to whatever other indentation is there.
The character can either be:

  • a space (indicates an unchanged line),
  • a - indicating that the line was removed,
  • or a + indicating that the line was added.

Nothing else. It must be either a space, a - or a +. Anything else, and you'll get errors
(there's no character for a changed line, since those are handled by removing the old line, and adding the changed one as new).

Since you've got the diff open in your favorite text editor (you did configure Git to use your favorite text editor, right?), you can do whatever you want - as long as you make sure the resulting diff applies cleanly.

And therein lies the trick. If you've never done this before, Git will tell you "Your edited hunk does not apply. Edit again?" so often, you'll start to hate yourself for your inability to figure this out, even though it seems so easy (or Git because it can't figure out what you want).

One thing that tripped me up quite often was that I forgot the one character indent.
I'd mark a line with a - to be removed, but in most text editors that inserts a -, it doesn't overwrite the space that was there before. This means you're adding an additional space to the whole line, which in turn means the diff algorithm can't find/match the line in the original file, which in turn means Git will yell at you.

The other thing is that the diff still has to make sense. "Sense" means that it can be applied cleanly. Exactly how you create a sensible diff seems to be a bit of an dark art (at least to me right now), but you should always keep in mind how the original file looked like, and then plan your -s and +s accordingly. If you edit your hunks often enough you'll eventually get the hang of it.

VonC
Thanks for the link, but I had already seen this. I was not adding/leaving an additional line. The problem was in the line numbers, but I still don't understand the fix.
Josh
+2  A: 

For this particular example, you need to tweak the line numbers in the hunk. Change the line:

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

so that it instead reads:

@@ -2,7 +2,8 @@
William Pursell
After some digging, I found that those lines are showing the "from-file range" and "to-file range". I don't really understand the logic behind changing the 1 to a 2. I tried it, and it works, but I don't understand why the "from-file range" changes. The original file is the same, whether I'm applying the whole patch, or just the edited hunk. Can you clarify further, or point me to a descent reference on the unified diff format. I've been unsuccessful in finding one.
Josh
@Josh: http://stackoverflow.com/questions/2529441/how-to-work-with-diff-representation-in-git can help, even if I don't get entirely the Unified format hunks. @William +1
VonC
@Josh: In looking into it it looks like it may be a bug. After you edit the hunk, git attempts to verify the patch by checking that *all* hunks will apply (this may be excessive). Unfortunately, in this case, that means the previous hunk (which you are not applying) is being checked, and there is some overlap which causes git apply --check to fail. I don't know an elegant solution; git may be doing the right thing by being overly cautious here.
William Pursell