Git diff to show only lines that have been modified

When I do a git diff, it shows lines that have been added:

+ this line is added

lines that have been removed:

- this line is removed

but it also shows many lines which are not modified:

this line is not modified
this line is also not modified

This results in the actual git diff looking something like this:

+ this line is added
  this line is not modified
- this line is removed
  this line is not modified

Can I ask git to show only lines that have been modified and ignore all other code which has not been modified? I have written a method which will remove all the lines which don't have a "+" or "-" sign in front of them, but I am sure there must be a simpler way to do this.

In my git diff, I am only interested in seeing the lines that have been modified.


Solution 1:

What you want is a diff with 0 lines of context. You can generate this with:

git diff --unified=0

or

git diff -U0

You can also set this as a config option for that repository:

git config diff.context 0

To have it set globally, for any repository:

 git config --global diff.context 0

Solution 2:

Another hack (on un*x) to show just the lines beginning with + and -:

git diff -U0 | grep '^[+-]' | grep -Ev '^(--- a/|\+\+\+ b/)'

The code above does the following:

  • git diff -U0: choose 0 context lines
  • The first grep only includes all lines starting with + or -
  • The second grep excludes lines starting with --- a/ or +++ b/

Color

To show colored diff, try the following:

git diff -U0 --color | grep '^\e\[[^m]*m[-+]' | grep -Ev '(--- a/|\+\+\+ b/)'
  • The expression, ^\e\[[^m]*m[-+], looks for start of line (^), then the escape characer (\e) followed by [ which together start the escape sequence, then any character that is not an "m" (numbers, semicolons, or nothing), followed by an "m" which ends the escape sequence.
  • Note that all of the following are valid escape sequences: \e[0m (reset), \e[m (also reset), \e[1m (bold on), \e[31m (red), \e[32m (green), \e[9;31m (strike out + red), \e[31;9m (red + strike out), \e[1;4;9;31m (bold + underline + strike out + red). The default git colors use red and green, but they can be reconfigured.
  • --color is the same as --color=always.
  • The restriction on --- a/ or +++ b/ to appear at the start of the line has been removed to accommodate for the escape sequences and this could lead to an edge case.

Additional Notes:

  • The above solution needs to be modified if you use additional git diff options such as -R, --src-prefix, --dst-prefix, --no-prefix, etc.
  • The two greps can be combined into a single grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )', but I find the double grep version easier to understand.

Solution 3:

I think for simple cases the regex can be much shorter and easier to remember, with the caveat that this won't work if you have line changes where the line itself starts with + or -

$ git diff | grep '^[+|-][^+|-]'

The regex says the line should start with + or -, and the immediately following character should be neither of those. I got the same results whether I escaped the + or not here, btw...


Example:

$ cat testfile
A
B
C
D
E
F
G

Say I change C to X, E to Y, and G to Z.

$ git diff | grep '^[+|-][^+|-]'
-C
+X
-E
+Y
-G
+Z

Like I said above, though, this is just for most cases. If you pipe that output to a file dout, then try the same regex, it won't work.

$ git diff dout | grep '^[+|-][^+|-]'
$

Anyways, hope that helps in your case