Extended Colors with Git

It’s well-known that Git supports colors for many operations, such as diff, and that these colors are customizable. Examples online show how to modify ~/.gitconfig to set various fields for git functions, such as this for the “diff” command:

    [color "diff"]
        meta = yellow bold
        frag = magenta bold
        old = red bold
        new = green bold

All other examples that I saw online used the same color names, that is, the ANSI colors for terminals: black, red, green, yellow, blue, magenta, cyan, white.

What I wondered, after rewriting Glark so that extended colors could be used for highlighting matches, since terminals now support those colors, is whether Git supported extended colors. Digging around through the Git source code shows that a color, in addition to being one of the above color names, can also be a number between 0 and 255, per the ANSI escape codes.

The nit is that that’s not an RGB value; it’s a ANSI code that corresponds to a color, and for people accustomed to RGB, the ANSI code is dissimilar enough to be confusing.

An RGB value can be mapped to a ANSI code with a simple equation (this is from the Rainbow Ruby Gem):

def to_code red, green, blue 
  r, g, b = [ red, green, value ].map { |v| (6 * v / 256.0).to_i }
  16 + 36 * r + 6 * g + b

Each of the values for red, green and blue is scaled to between 0 and 5, then offset for the ANSI version of RGB.

This Ruby snippet dumps the list of colors as foregrounds:

(0 .. 255).each do |c|
  puts if c > 0 && (c % 10) == 0
  printf "\e[38;5;#{c}mabc %3d\e[0m  ", c

The colors, as foregrounds on white:


As foregrounds on black:


As backgrounds on white:


And as backgrounds on black:


Also note that the Git color fields are of the format “[attributes] foreground [background]”, where if a second color is given, then it is used as the background.

The same is true for ANSI codes, so that the second ANSI code specified will be used as the background.

Attributes are the following: bold, blink, ul (for underline), reverse, and dim. More than one can be used.

Not that I recommend it, but a valid configuration could thus be:

    [color "diff"]
        meta = bold 190 22
        frag = blink 189 89
        old = blink bold 160 143
        new = reverse bold blink ul 52 227

Which looks like the following:


Again, I don’t recommend it. I’ll post an update when I’ve settled on a color theme.