Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine color with conditional newlines in git log output

Tags:

git

git-log

When I invoke the following command:

git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%-b"

I get output that looks like this:

enter image description here

I would like the commit bodies to be dimmed, so I tried inserting the instruction %C(dim) at the end of my format string. However, there does not seem to be an insertion location that achieves my goal:

  • Inserting %C(dim) after the newlines and before the (conditional newline-chomping) %-b command correctly applies the dimming effect, but breaks conditional newline-chomping:

    git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%C(dim)%-b"
    

    enter image description here

  • Inserting %C(dim) before both the newlines and the (conditional newline-chomping) %-b command correctly retains conditional newline-chomping, but fails to apply the dimming effect (i.e. no change from original output):

    git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%C(dim)%n%n%-b"
    

    enter image description here

Additionally, I cannot move the 'chomp' operator - to the color command, since that always appears to "evaluate" to a non-empty string (and therefore, newlines are not chomped).

Is there a way to achieve my goal?

like image 510
stkent Avatar asked Jul 27 '17 16:07

stkent


People also ask

How do I add color to my git log?

Want to add some color to your Git log? Check out this git log configuration that gives you one commit per line, a commit graph, abbreviated commit ID’s, relative dates, & commit author all bundled up in color coordinated text. Navigate to your git initialized directory (that includes previous commits) and use this command:

How to colorize the output of git diff?

To colorize the output of git diff you can add a color.diff section to ~/.gitconfig. For example: Here 154 and 196 are ANSI 256-color codes. For more details see man git config.

How to decorate%D in the format string of git log?

As of git 1.8.3 (May 24, 2013), you can use %C (auto) to decorate %d in the format string of git log. From the release notes: * "git log --format" specifier learned %C (auto) token that tells Git to use color when interpolating %d (decoration), %h (short commit object name), etc. for terminal output.)

How can I change the output of git log?

But, you can alter this output by passing many different parameters to git log. The advanced features of git log can be split into two categories: formatting how each commit is displayed, and filtering which commits are included in the output.


1 Answers

The final solution (without any known quirks) is at the bottom of this answer.

A workaround is to put a custom placeholder for the newlines in the format string (without using the %-b magic) and then postprocess the output with sed. In the example below the placeholder is the CHOMPABLENEWLINES string (of course you can replace it with any text of your choice, just make sure that it can't appear in your commit messages):

git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%C(dim)CHOMPABLENEWLINES%b"|sed -e 's/CHOMPABLENEWLINES$//; s/CHOMPABLENEWLINES/\n\n/; $ s/$/\n/'

Colored output of git log with sed postprocessing

Note that this approach also fixes the problem that the effect of the %C directive extends only till the end of the current line (at least in git 2.7.4). As a result, in case of a multi-line body the color is applied only to its first line. Compare:

# Only the first line of a multiline message body is colored
git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%Cred%b"

Colored output of git log without sed postprocessing

# Entire multiline message body is colored (though a byproduct of this
# is that the color setting persists beyond the current
# command - note the red prompt following the output)
git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%CredCHOMPABLENEWLINES%b"|sed -e 's/CHOMPABLENEWLINES$//; s/CHOMPABLENEWLINES/\n\n/; $ s/$/\n/'

Colored output of git log with sed postprocessing

The undesirable side effect of persisted color setting can be counteracted by ending the format string with a %C(reset) directive. Then we also need a custom marker for the end of the %b placeholder, since the visual end of line is no longer an actual end of line from sed's point of view. In the example below the string ENDOFBODY is used as such a marker (and of course you must select it so that it doesn't appear in your expected output).

# This version works with GNU sed. For a portable version (including BSD
# and MacOS X systems) scroll down a little more
git log --format=tformat:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%CredCHOMPABLENEWLINES%bENDOFBODY%C(reset)"|sed -e 's/CHOMPABLENEWLINESENDOFBODY//; s/CHOMPABLENEWLINES/\n\n/; s/ENDOFBODY//'

Output of the final version

Some versions or setups of git disable colored output when it doesn't directly go to terminal. In such cases you must also provide the --color=always option to git log.


The final solution, using only portable features of sed, is as follows:

git log --color=always --format=tformat:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%C(red)CHOMPABLENEWLINES%bENDOFBODY%C(reset)"|sed -e 's/CHOMPABLENEWLINESENDOFBODY//; s/CHOMPABLENEWLINES/\'$'\n''\'$'\n/; s/ENDOFBODY//'
like image 68
Leon Avatar answered Sep 22 '22 03:09

Leon