gitgit-diff

git-diff console default colors meanings


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.


Solution

  • 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:

    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".