1

I'm now a little lost on the meanings of various colors in the default color scheme of git-diff in the console. I can't seem to find any documentation on them. I'm using xfce4-terminal in Manjaro/XFCE.

It looks like the default color scheme for git-diff is "zebra". I have eight import statements shown in my diff represented in seven different colors. That seems a little crazy to me.

enter image description here

Thank you.

2
  • Is this really the "default color scheme"? I've always seen red or green but not any other color..
    – Gaël J
    Commented Sep 13, 2021 at 17:16
  • 1
    Git's original system is just two (well, three) colors: default for unchanged, red for deleted, green for added. Since then, people have gotten a bit crazy with move detection: --color-moved turns on zebra mode. You do, however, have to turn on --color-moved to get it. Use --no-color-moved to turn it off entirely, or don't use the config item diff.colorMoved to turn it on. See also git-scm.com/docs/git-diff and git-scm.com/docs/git-config (and techopedia.com/definition/17646/angry-fruit-salad).
    – torek
    Commented Sep 13, 2021 at 23:04

1 Answer 1

7

TL;DR

You probably have diff.colorMoved set in your Git configuration (run git config --get diff.colorMoved; to see who's setting it, use git config --list --show-origin). The default if this mode is requested is indeed zebra, which apparently calls to your mind the same thing it does to mine: Angry Fruit Salad.

Long

Back in the Dim Time, there was no color. We were grateful for the Glass TTY that replaced our old printers. Plain diff was invented and it had three things it mentioned:

  • added lines, signified by a;
  • deleted lines, signified by d; and
  • changed lines, signified by c.

For instance:

$ cat old
$ cat old
line one
line two
line three
line four
line five
$ cat new
line one
inserted
line two
line four
line 5
$ diff old new
1a2
> inserted
3d3
< line three
5c5
< line five
---
> line 5

Later, context diff was invented as a more useful way to show this:

$ diff -c old new
*** old 2021-09-13 16:11:48.145950000 -0700
--- new 2021-09-13 16:11:56.597068000 -0700
***************
*** 1,5 ****
  line one
  line two
- line three
  line four
! line five
--- 1,5 ----
  line one
+ inserted
  line two
  line four
! line 5

The marker letters a, d, and c are replaced with front-of-line markers +, -, and ! respectively.

Of course, "changed" just means "deleted and added". In unified mode, plain diff uses these instead, so there's no ! any more:

$ diff -u old new
--- old 2021-09-13 16:11:48.145950000 -0700
+++ new 2021-09-13 16:11:56.597068000 -0700
@@ -1,5 +1,5 @@
 line one
+inserted
 line two
-line three
 line four
-line five
+line 5

I'll skip over the precise difference between "context" and "unified" diff since it's not that interesting, but both provide context. "Unified" usually makes the output smaller and easier for humans to read, at the cost of making it slightly harder to machine-parse.

Colo(u)r and Git

Eventually, our black-and-white displays gave way to color, windowing, and all the other fanciness. Naturally, someone added colors to diff output: red for removed text, and green for added text, quite commonly. This was no doubt chosen because the most common form of color-blindness is red-green. So, along comes git diff, which uses these colors to ditch the left column ("gutter") insertion to get rid of the spaces and + and - markers ... oh, wait, it doesn't:

$ git diff old new
diff --git a/old b/new
index 9864d22..8e331db 100644
--- a/old
+++ b/new
@@ -1,5 +1,5 @@
 line one
+inserted
 line two
-line three
 line four
-line five
+line 5

This fixes the color blindness issue, right? 🤔🙄

(It doesn't show here on StackOverflow in plain text, but the @@ hunk header is in cyan, the +inserted line in green, and so on.)

People were not satisfied with this, and it's true that the human visual system is pretty good at spotting certain color differences (modulo common color-blindness issues: it affects roughly 8% of men and .5% of women; see https://www.colourblindawareness.org/colour-blindness/ for instance; many don't even know they have it!). So people developed even more filters and modes. Some web sites (notably GitHub) take the basic red/green and mark it up a bit to show the individual changed characters within a line, which can be quite useful sometimes.

Git has acquired the ability to post-detect moved lines.1 To help distinguished a moved line from a deleted-and-added line, Git can color these lines differently.

The switches that enable "moved line" detection are diff.colorMoved in your .git/config or $HOME/.gitconfig or other Git configuration file, as manipulated by git config, and the command-line --color-moved option. These take an optional value, which is the name of the color scheme to use.

If you enable color-moved in your config, you can disable it for one git diff invocation with --no-color-moved. If you have not enabled it in your config, you can test it out for each git diff invocation with --color-moved or --color-moved=mode. There are numerous mode values; see the git diff documentation for details.

See the git config documentation for information on running git config, including how to figure out where some system-provided configuration might be coming from (--list --show-origin).


1There are diff engines that will detect this during the diffing, but Git still primarily uses ones that don't (although git blame is different here). Instead, Git post-processes the diff output in various attempts to make it match up more with human expectations, e.g., synchronizing more on blank lines than on close braces or whatever. This includes the current moved-line detection, which looks only in each "diff hunk".

2
  • Indeed. I don't know how that ended-up in my config. Thanks. Commented Sep 14, 2021 at 20:48
  • @DustinOprea: Thanks for the typo-fix. (I even ran it to make sure I didn't misspell it, which I have a habit of doing, but then somehow got an s tacked on anyway!)
    – torek
    Commented Sep 14, 2021 at 22:46

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