在 git 日志输出中将颜色与条件换行符结合起来

Combine color with conditional newlines in git log output

当我调用以下命令时:

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

我得到如下所示的输出:

我希望提交主体变暗,所以我尝试在格式字符串的末尾插入指令 %C(dim)。不过好像没有一个插入位置可以达到我的目的:

此外,我无法将 'chomp' 运算符 - 移动到颜色命令,因为它总是 "evaluate" 显示为非空字符串(因此,换行符不是咀嚼)。

有没有办法实现我的目标?

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

一种解决方法是在格式字符串中为换行符放置一个自定义占位符(不使用 %-b 魔法),然后使用 sed 对输出进行后处理。在下面的示例中,占位符是 CHOMPABLENEWLINES 字符串(当然您可以将其替换为您选择的任何文本,只需确保 它可以' t 出现在您的提交消息中):

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/'

请注意,此方法还解决了 %C 指令的效果仅延伸到当前行末尾的问题(至少在 git 2.7.4 中)。因此,在多行主体的情况下,颜色仅应用于其第一行。比较:

# 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/'

可以通过以 %C(reset) 指令结束格式字符串来抵消持久颜色设置的不良副作用。然后我们还需要一个用于 %b 占位符结尾的自定义标记,因为从 sed 的角度来看,视觉行尾不再是实际的行尾。在下面的例子中,字符串 ENDOFBODY 被用作这样的标记(当然你必须 select 它这样它就不会出现在你的预期输出中).

# 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//'

git 的某些版本或设置在不直接进入终端时禁用彩色输出。在这种情况下,您还必须向 git log.

提供 --color=always 选项

最终解决方案,仅使用 sed 的可移植特性,如下所示:

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//'

我想我找到了一种不依赖外部工具(如 sed)的方法。

我希望它的工作方式是,我只添加一个换行控件和一个颜色格式化程序,这两个都可以工作,比如

things things %C(yellow)%+d%C(reset)

但是黄色被忽略了。但是,像这样将 yellow 更改为 auto

things things %C(auto)%+d%C(reset)

应用了一些颜色,但它是一组默认颜色。不过,您可以在 git 配置中更改这些颜色!所以漂亮的格式不会是 100% 可移植的(就像你不能将它内联到 git 命令中给你的同事)但它在我的终端上工作。

要找到要更改的配置值,我必须进行一些试验。 运行 git help -c | grep color 查看颜色配置值列表。着色 %d 的那些(给定提交上的所有分支名称)在这里:

color.decorate.HEAD
color.decorate.branch
color.decorate.grafted
color.decorate.remoteBranch
color.decorate.stash
color.decorate.tag

可能还有另一个类似的配置值会像 OP 想要的那样使提交消息变暗。然后您可以 运行 git config --global color.decorate.HEAD yellow 将其添加到您的 git 配置文件中:

[color "decorate"]
    HEAD = yellow

其他配置值也一样。

所以最终我的配置是这样的:

[format]
    pretty = format:%C(bold cyan)%h%Creset %C(cyan)<%an>%Creset %Cgreen(%cr)%Creset%  %s%C(auto)%+d%C(reset)
[color "decorate"]
    HEAD = yellow
    branch = yellow
    grafted = yellow
    remoteBranch = yellow
    stash = yellow
    tag = yellow