Combine color with conditional newlines in git log output
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/'
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"
# 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/'
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//'
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//'