
I mistakenly replace all and save lines in my documents that are all tracked by Git. I have done some work before and forgot to commit as a checkpoint before doing that, so reverting is not desirable as it would revert all of my work. I would like to revert only the replace all operation using help from Git.
I know all the lines that I need to revert because they all have the same new line. From GUI tools like SourceTree I can click Discard Hunk one by one, but there are many such location that I would like to discard. All the places I would like to revert has new line that says
m_Sprite: {fileID: 21300164, guid: 791de2a5646d94a15a09bb1d7e79a0e6, type: 3}
But old line is not necessary the same. (In fact there are 2 kinds of old lines that I changed into this same new ones) Are there any scripted way to match the pattern of changed lines so I can selectively revert them all? Thank you.
Using git add -p interactively to add everything except the hunk I don't want going forward is very tedious, since it ask you one by one but there are so many works to add and at the same time the hunks I don't want are mixed in almost every file. (So I must be very careful on every question git asks) The same goes for git checkout -p to remove the hunks I don't want going backward.
Ok, I managed to fix the problem using a patch.
First, I commit this messed up state as a checkpoint. Then I can produce a patch of this state (the one with replaced lines I want to revert plus all the work I don't want to lose) and the previous commit (the one with correct lines remembered) using
git diff --binary HEAD^ HEAD > ~/Desktop/patch.diff
Note that the previous commit comes first in the command.
With the patch saved somewhere, I reset hard into the previous commit and git clean -f. Now, if I git apply patch.diff I would arrive at the same point (but still keeping head on a previous commit) The idea is to directly edit the patch surgically before applying.
The patch is composed of hunks, so to disable a certain hunk I don't want the approach is to replace the + lines with the same thing as the preceeding - ones. I can use regex searching in VSCode to search multi-lines with \n (Don't forget to escape the + character as \+ so it does not count as regex) and replace them all.
This way is better than removing the hunks, since there's no chance to corrupt the format of a patch. The patch does not know if it is changing into the same line, doing nothing.

After editing the patch and apply, I got all the changes minus the hunks that we edit earlier. And so it equals the action of "reverting all the hunks I don't want".
Analogous to this answer (adding lines versus reverting lines), you could use grepdiff from patchutils.
Check the matches first:
git diff -U0 | grepdiff 'schemaVersion' --output-matching=hunk
Then use apply --reverse to undo the matching changes.
git diff -U0 | grepdiff 'schemaVersion' --output-matching=hunk | git apply --reverse --unidiff-zero
The same logic can be used with git apply --cached to stage matching lines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With