I'm trying to use git's --ignore-matching-lines, but running into some weird behavior. Here's the output of a plain git diff:
$ git diff test.txt
diff --git a/test.txt b/test.txt
index 602c47d1cb..82655814c5 100644
--- a/test.txt
b/test.txt
@@ -1,5 1,7 @@
-Hello world
Hello whitespace world
Lots of blank lines
Goodbye world
However, if I run
$ git diff --ignore-matching-lines='^$' test.txt
I get no output
Why is this ignoring the change that adds the word whitespace?
CodePudding user response:
This could be caused by how '$' itself is interpreted, as detailed in "How does git diff --ignore-matching-lines work", by Sjoerd Langkemper (also a Stack Overflow user):
Git runs each regex over each line.
These lines end in a newline, so our regex is actually checked against:His bill will hold more than his belican,\nWhere
\nstands for a newline character.When we have a change that adds an empty line, the regex is ran against a single byte string consisting of
\n.
How do we match that?It’s easier to use something like
--ignore-blank-linesto ignore blank lines.
(Check, by the way, if git diff --ignore-blank-line is a good option in your particular case)
However, this does not work well together with other regular expressions that we want to ignore.
If we want to ignore a change that performs both an uninteresting belly-related change and adds an uninteresting empty line, our regular expressions we give to-Ineed to match both for the change to be hidden.
So we need a regular expression that matches an empty line, and--ignore-blank-linesand other white space related options don’t change that.An empty line cannot be matched with
^$.
^matches both the beginning of the line and the beginning of the buffer.- Similarly,
$matches both the end of the line as the end of the buffer.All changed lines end in a newline, just before the end of the buffer.
This means that^$matches every changed line.
The newline at the end starts a new line, and is immediately followed by the end of the buffer.… his belican,\n ↑ ^ matches because \n starts a new line $ matches because the buffer ends here
That would explain why a --ignore-matching-lines='^$' is ignoring the change that adds the word whitespace: it is ignoring all the lines!
To match more precisely, we can use
\`to match the start of the buffer, and\'to match the end of the buffer.
An empty line can thus be matched with:\`\n\'Where
\nis an actual newline, notbackslash-n.
This needs much escaping to enter correctly in a shell:git diff -I $'\\`\n\\\'' …
