在 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)
。不过好像没有一个插入位置可以达到我的目的:
在换行之后和 (conditional newline-chomping) %-b
command 之前插入 %C(dim)
正确应用调光效果,但打破条件换行:
git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%C(dim)%-b"
在换行符和(条件换行符)%-b
命令之前插入 %C(dim)
可以正确保留条件换行符,但无法应用调光效果(即原始输出没有变化):
git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%C(dim)%n%n%-b"
此外,我无法将 '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
当我调用以下命令时:
git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%-b"
我得到如下所示的输出:
我希望提交主体变暗,所以我尝试在格式字符串的末尾插入指令 %C(dim)
。不过好像没有一个插入位置可以达到我的目的:
在换行之后和 (conditional newline-chomping)
%-b
command 之前插入%C(dim)
正确应用调光效果,但打破条件换行:git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%n%n%C(dim)%-b"
在换行符和(条件换行符)
%-b
命令之前插入%C(dim)
可以正确保留条件换行符,但无法应用调光效果(即原始输出没有变化):git log --format=format:"%C(yellow)%h %C(blue)%s %C(green)%ad %C(reset)%an%C(dim)%n%n%-b"
此外,我无法将 '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