Devin Rich builds his own dynamic OUYA API server, and you will be able to edit existing game data and add new ones with it.
While building that, some changes to the 1200+ OUYA game data files were necessary, and I got those changes as one big commit. It added missing uuid for all developers, but also trimmed some text fields here and there.
I love to have sensible and clean commits that do one thing, and so I wanted to have one commit that fixed the UUIDs, and one for the rest. Using git add -p is the normal way to go when splitting up commits into several managable ones, but this was not possible with over 900 changed files.
grepdiff to the rescue
After some searching I found grepdiff, which is part of patchutils.
It allows me to find all changes that match a given regex in a patch file. In the end it shows you the files that contained the match - but it is also able to create a new patch with only the matching lines in it! The magic parameter for this is --output-matching=hunk.
Example
A simple file:
$ cat gamelist best=Bloo Kid 2 second=Babylonian Twins third=SNES9x
Now we change second and third place:
$ git diff diff --git gamelist gamelist index b0aeab0..548adad 100644 --- gamelist +++ gamelist @@ -1,3 +1,3 @@ -best=Bloo Kid 2 +best=Hidden in plain sight second=Babylonian Twins -third=SNES9x +third=Bomb Squad
My goal is now to only add the change to the "best" line to the git staging area. We do not want a unified diff here as shown above, because that gives us both changes in one hunk. Instead I use 0 lines of context:
$ git diff -U0 diff --git gamelist gamelist index b0aeab0..548adad 100644 --- gamelist +++ gamelist @@ -1 +1 @@ -best=Bloo Kid 2 +best=Hidden in plain sight @@ -3 +3 @@ second=Babylonian Twins -third=SNES9x +third=Bomb Squad
Now grepdiff can be used to get only those hunks that contain
best
:
$ git diff -U0 | grepdiff best --output-matching=hunk diff --git gamelist gamelist index b0aeab0..548adad 100644 --- gamelist +++ gamelist @@ -1 +1 @@ -best=Bloo Kid 2 +best=Hidden in plain sight
This patch file can now be piped into git apply to stage it:
$ git diff -U0\ | grepdiff best --output-matching=hunk\ | git apply --cached --unidiff-zero -p0 $ git diff --cached diff --git gamelist gamelist index b0aeab0..02e36aa 100644 --- gamelist +++ gamelist @@ -1,3 +1,3 @@ -best=Bloo Kid 2 +best=Hidden in plain sight second=Babylonian Twins third=SNES9x $ git diff diff --git gamelist gamelist index 02e36aa..548adad 100644 --- gamelist +++ gamelist @@ -1,3 +1,3 @@ best=Hidden in plain sight second=Babylonian Twins -third=SNES9x +third=Bomb Squad
-p0 is necessary because I use the diff.noprefix config option that omits the leading a/ and b/ in the filenames in diffs.
--unidiff-zero is needed because we used zero lines of context.