5

I'm trying to split changes into several commits, but I'm facing an issue when manually editing a hunk.

Original hunk:

@@ -116,8 +116,8 @@
        context
        context
-           remove 1
-           remove 2
-           remove 3
+           add 1
+           add 2
+           add 3
        context
        context
        context

I want only the change that happened to 'remove 1' and 'remove 2' to be staged. In other words, I need 'remove 3' to be excluded from the commit.

I tried this:

@@ -116,4 +116,4 @@
            context
            context
-           remove 1
-           remove 2
+           add 1
+           add 2

But it keeps outputting patch doesn't apply. I only removed the last context lines and 'remove 3' and 'add 3' lines. I edited the hunk range and subtracted the 4 excluded lines (3 are context 1 are changes, 1 removed and 1 added)

I used 2 different editors, 'nano' and 'sublime text' and both have the same result. I made sure there are no empty lines that aren't commented out.

What am I doing wrong?

Alex Ferg
  • 801
  • 1
  • 9
  • 17
  • why does the original patch say `@@ -116,8 +116,8 @@` but the rewritten one say `@@ -116,4 +116,4 @@`? – Mike 'Pomax' Kamermans Mar 18 '15 at 19:32
  • Because I removed 4 lines, 3 of them are the last 3 context lines, and one are the modified line that I don't want to include. – Alex Ferg Mar 18 '15 at 19:34
  • Okay, so does the patch apply if you only take out that `remove 3`/`add 3` (without additional edits) and the make the change information `@@ -116,7 +116,7 @@`? – Mike 'Pomax' Kamermans Mar 18 '15 at 19:37
  • No, and it shouldn't. Because this way I totally removed the line, even the context one. I can find a work around (like removing the added line and changing the removed line to context) but I need to understand why this happens. – Alex Ferg Mar 18 '15 at 19:41

2 Answers2

0

What am I doing wrong?

Well, you're hand-editing a patch file, which seems like an odd thing to be doing...

From what I can tell, git requires the trailing context in the patch. For example, if I start with a file that looks like this:

the
quick
brown
fox
jumped
over
the
lazy
dog

And I have a patch like this:

diff --git a/file1 b/file1
index 4a3cebe..30f5937 100644
--- a/file1
+++ b/file1
@@ -1,9 +1,9 @@
 the
 quick
 brown
-fox
-jumped
-over
+ostrich
+shouted
+at
 the
 lazy
 dog

That applies without a problem:

$ git apply mypatch

If I remove the trailing context in that patch (and update the line numbers), giving me this:

diff --git a/file1 b/file1
index 4a3cebe..30f5937 100644
--- a/file1
+++ b/file1
@@ -1,6 +1,6 @@
 the
 quick
 brown
-fox
-jumped
-over
+ostrich
+shouted
+at

Then git will refuse to apply the patch:

$ git apply diff
error: patch failed: file1:1
error: file1: patch does not apply

It I add even a single line of trailing context it will work:

diff --git a/file1 b/file1
index 4a3cebe..30f5937 100644
--- a/file1
+++ b/file1
@@ -1,7 +1,7 @@
 the
 quick
 brown
-fox
-jumped
-over
+ostrich
+shouted
+at
 the
larsks
  • 277,717
  • 41
  • 399
  • 399
  • 2
    I wasn't editing a patch manually, I was interactively staging content from a file. I guess there must be a trailing context line. – Alex Ferg Mar 18 '15 at 20:43
  • Hey, recent -1 voter! If you happen to drop by here, I'm curious if you have any suggestions on how I can improve this answer? – larsks Aug 12 '22 at 16:36
0

When git applies a patch, it looks at both leading and trailing context lines. When there is no leading context line in a hunk, the hunk must apply at the beginning of the pre-image (the version of the file before the change). Similarly, no trailing context means that the hunk is anchored at the end.

Since you've removed the trailing context lines (and the hunk is not supposed to be achored at the end), the patch won't apply.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378