10

Normally diff and git diff show both the original and the modified line with - and + respectively. Is there any way, I can filter only to see the modified line? This would reduce the number of lines to read by a factor of 2 instantly.

I was assuming

git diff test.yml | grep '^+' | less -R

and

git diff test.yml | egrep '^+' | less -R

to have the same result. ie they would show any new additions in a file. However egrep shows me the entire file. Why is that so?

With the above method anyways, I lose the color. Is there any way to retain the color?

1
  • So you don't care whether it's a new line or a replaced line?
    – Philippos
    Sep 14 '17 at 11:40
9

You can use --word-diff to condense the + and - lines together with the changes highlighted using red/green text and stop using grep all together.

enter image description here

You can combine this with -U0 to remove all context around the diffs if you really want to condense it down further.

enter image description here

This approch is better than using grep as you don't lose output, you can tell when a line was added or simply changed and you don't completely lose removals while still condensing the output down into something that is easy to read.

The answer to the question regarding egrep is already answered by @Stephen Kitt here

3
  • word-diff and U# is indeed cool ! It immediately reduces the length of the diff by a factor of 2 making it read quicker. If you cite the answers form @Stephen Kitt with respect to egrep, I will mark it as accepted. Sep 14 '17 at 14:05
  • Your syntax highlighting is really impressive, but next time please use copy-paste...
    – peterh
    Sep 15 '17 at 19:20
  • Problem with copy paste in this example is it loses all of the syntax highlighting which is important to show the actual diff - otherwise it makes no sense. Sep 15 '17 at 22:34
3

egrep uses extended regular expressions, so

egrep ^+

matches one or more beginnings of lines (+ is a special character here). To match the “+” character you need to escape it:

egrep ^\+

To see colours, you need to force git to output them; by default it disables them when piping:

git diff --color

To filter this you need to take the escape codes used for colours into account:

git diff --color ... | egrep '^.[[[:digit:]]+m\+' | less -R
0
2

While using grep works, you can use a flag to achieve similar and possibly a more succinct result.


git diff

You can adjust the amount of context git diff provides with the -U flag. From man git-diff:

   -U<n>, --unified=<n>
       Generate diffs with <n> lines of context instead of the usual three. Implies -p.

git diff -U0 will produce minimal/simple output with no context for each change.


diff

The same flag applies to diff:

   -u  -U NUM  --unified[=NUM]
          Output NUM (default 3) lines of unified context.

Example (diff -U0 would work the same way):

$ diff -U0 <(echo -e "abc123\ndef345") <(echo -e "abc123\nghi678")
--- /dev/fd/63  2017-09-14 09:18:01.000000000 -0400
+++ /dev/fd/62  2017-09-14 09:18:01.000000000 -0400
@@ -2 +2 @@
-def345
+ghi678
1

However egrep shows me the entire file. Why is that so?

Because egrep uses extended regular expressions, so egrep ^+ matches the beginning of each line one or more times (i.e. it matches all lines). Use egrep ^\+ to match only lines starting with +.

With the above method anyways, I lose the color. Is there any way to retain the color?

Yes, add option --color=always:

git diff --color=always | less -R
1

Can also be done with grep alone.

$ grep -xvFf filea.txt fileb.txt

This takes the lines from one file and looks for them in the other, printing out only ones which don't match exactly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.