Problem with diff-split-hunk (vc-mode)

Hello there good people!

Maybe someone here can help me figure it out this behavior.

If I visit a git controlled file, and add a few new lines.

C-x v = will take me to the vc-diff buffer. Let’s say I want to split my hunk into 2. I can navigate to the line where it is and use C-c C-s (diff-split-hunk) to split it.

From there, I can always kill (k) the first one and C-x v v add a message and C-c C-c to apply/commit. But the contrary is never true. I mean, if I kill the second split, something is broken and my patch fails to apply.

Do I need to fix something with diff markings? Do I have to add some blank new lines? Does anybody have a cool workaround to this?

It seems such a killer built-in feature not to use it.

PS.: My memory might be failing, maybe it is the first one that always applies and the second one never, but this is it.

1 Like

Not much help here, I don’t think I’ve seen this problem. Maybe I’m always choosing the “correct” hunk to commit (?)… usually I do this when I want to keep part of the diff and revert the rest, but, like I said, I don’t do that very often. You’ll have to post back here if you find a solution. Now I’m tempted to go try it out on a junk repo…

And so I did. I created a new directory, added file.txt and filled it with the text of the cpio man page. Added several additional lines of text in different places, ran C-x v = on the file, then C-c Cs on an arbitrary line, used k to kill the other hunks, then used C-x v v to commit the remaining one. It always worked regardless of which hunk I chose to keep and commit. Maybe its something else in your work flow? I did not try having multiple hunks, splitting one of them, removing the part I didn’t want to keep and then committing all the remaining hunks.

1 Like

Nice!

I explored a little more about it and made a small study case.

The silly user (this guy here), has to be a bit smarter where the split occurs.

Lets assume this file:

aaaaaaaaa
aaaaaaaa
aaaaaaaa
aaaaaaaa
bbbbbbb
bbbbbbb
bbbbbb
bbbbbb
aaaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaa

Commit this, now modify this file to this:

aaaaaaaaa
aaaaaaaa
aaaaaaaa
aaaaaaaa
bbbbbbb (modified)
bbbbbbb (modified)
bbbbbb
bbbbbb
aaaaaaaa
aaaaaaaaa
aaaaaaaa












added
added

This is the diff:

 text.md | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/text.md b/text.md
index 1836903..a87959f 100644
--- a/text.md
+++ b/text.md
@@ -2,12 +2,24 @@ aaaaaaaaa
 aaaaaaaa
 aaaaaaaa
 aaaaaaaa
-bbbbbbb
-bbbbbbb
+bbbbbbb (modified)
+bbbbbbb (modified)
 bbbbbb
 bbbbbb
-aaaaaaa
-aaaaaaa
 aaaaaaaa
 aaaaaaaaa
 aaaaaaaa
+
+
+
+
+
+
+
+
+
+
+
+
+added
+added
\ No newline at end of file

This is a valid split:

 text.md | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/text.md b/text.md
index 1836903..a87959f 100644
--- a/text.md
+++ b/text.md
@@ -2,6 +2,6 @@ aaaaaaaaa
 aaaaaaaa
 aaaaaaaa
 aaaaaaaa
-bbbbbbb
-bbbbbbb
+bbbbbbb (modified)
+bbbbbbb (modified)
 bbbbbb
@@ -8,6 +8,18 @@
 bbbbbb
-aaaaaaa
-aaaaaaa
 aaaaaaaa
 aaaaaaaaa
 aaaaaaaa
+
+
+
+
+
+
+
+
+
+
+
+
+added
+added
\ No newline at end of file

This is not:

 text.md | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/text.md b/text.md
index 1836903..a87959f 100644
--- a/text.md
+++ b/text.md
@@ -2,5 +2,5 @@ aaaaaaaaa
 aaaaaaaa
 aaaaaaaa
 aaaaaaaa
-bbbbbbb
-bbbbbbb
+bbbbbbb (modified)
+bbbbbbb (modified)
@@ -7,7 +7,19 @@
 bbbbbb
 bbbbbb
-aaaaaaa
-aaaaaaa
 aaaaaaaa
 aaaaaaaaa
 aaaaaaaa
+
+
+
+
+
+
+
+
+
+
+
+
+added
+added
\ No newline at end of file

If we try to split this with lazygit (or magit). You can see it alters the diff a bit differently.

It keeps a copy of the last line content and properly adjusts the “set of changes” (the @@ header), for this specific case.

I’ll try to pay more attention to other edge splits I make in the future, but this is one case where “it is not just split”, you have to know where to split, and make proper edits to the “set of changes” if vc-mode haven’t read your mind and done it right for you.

1 Like