5

Just create an folder containing an empty test.txt file, add and commit it. Then add the following:

new line keep

new line skip

new line bad

new line keep 2

Now assume, I only want to keep the first and the last line. According to this answer, I should be able to split the single hunk using git add -i -p test.txt and the s option, but this does not work (and the option is not displayed). Do I miss anything?
The diff looks ok:

enter image description here


Problem with edit in VI: What is wrong? I modified successfully enter image description here

Then I want to quit but enter image description here

Christoph
  • 6,841
  • 4
  • 37
  • 89

2 Answers2

8

This is very easy to do in git gui. Select the file in the staging window. Highlight the line(s) you want then right-click in text area and select "Stage Line For Commit"

For the command line: Select e to manually split hunk. This will bring up a text editor. Change the + to a #for any lines you don't want to stage.

+ new line keep
+
#new line skip
#
#new line bad
#
+new line keep 2
EncryptedWatermelon
  • 4,788
  • 1
  • 12
  • 28
4

(This is more a very long comment that needs formatting, than an answer. See EncryptedWatermelon's answer for the direct answer.)

The "split" option to git add -p only handles the case where a diff hunk has two fused sub-changes:

@@ ...
 context
+new1
 context
 context
+new2
 context

for instance can be split, but:

@@ ...
 context
+new1
+new2
 context

cannot be split: it's a single change, not two changes whose contexts adjoined (or overlapped) and hence were fused into one hunk.

To get git add -p to apply such a patch, you must turn the patch into instructions to add (and/or delete) only certain lines within the patch. As the meta-instructions say, this involves deleting (or commenting out) added lines that you don't want added after all, and replacing the minus sign on lines you don't want deleted. That is:

@@ ...
 context-above
+new1
-old
+new2
 context-below

should become:

@@ ...
 context-above
+new1
 old
 context-below

The result is, as you can see by reading it, a set of instructions that say: In the original file, find the lines reading context-above, then old, then context-below as the context. In that region, insert the new line new1.

Several recent versions of Git have problems following correct patch instructions in git add -p. If you hit these particular Git versions, your options are to downgrade Git to one that does not have the bug, upgrade Git to one that has the bug fixed, or—my personal favorite—don't bother with this silly "hack up the patch to make a new patch" approach: just copy the file outside the VCS.

The version control system is a tool-set. If none of its hammers and saws work on your problem, there's no reason to abuse a screwdriver as a chisel. Just take the file over to the other work-table, where there's a handy jigsaw or router that makes the job easy, and use that.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks for the explanations. May I ask you for a favor? I had a question [here](https://stackoverflow.com/q/47307978/5784831) some time ago and I would be still interested in an "answer for the beginner". Git reference is great but in many cases the beginner is lost in the details. Am am fine with the one or two most important use cases... – Christoph Nov 07 '19 at 07:48
  • Unfortunately, these details really matter a lot. You need to know them to use the Git tool-set effectively. I'll take a stab at it, though. – torek Nov 07 '19 at 08:22