git 日志图中特定提交的突出显示行
Highlight line for specific commit in git log graph
我试图在我的 git 日志图中突出显示特定提交的整行。我之前创建了一个 git 日志别名来格式化我的日志输出。我试图使用我的别名突出显示包含提交 ID 的特定行。
别名 ~/.gitconfig
# Base command for log formatting
lg-base = "log --graph --decorate=short --decorate-refs-exclude='refs/tags/*' --color=always"
# Version 1 log format
lg1 = !"git lg-base --format=format:'%C(#f0890c)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(#d10000)%d%C(reset)'"
通过搜索 6 months
进行测试只是因为它应该表现相同并且可能更好地展示我的问题。
git lg1 | grep --color=always -E '(6 months).*|$'
匹配正确的行。但它并没有突出显示右边的整行,当试图突出显示该行的左侧部分时,它也没有按预期工作。可能是因为我不太会用regex。
git lg1 | grep --color=always -E '.*(6 months).*|$'
而是在开头标记 *
。
如果您有其他方法,我也可以,只要我可以使用我的格式化 git 日志别名即可。
是这里问题的关键:尽管 grep
是 添加自己的 颜色(或颜色)更改转义序列以突出显示该行, Git 已经加入了变色指令。每个这样的指令,对于其中一种命名的颜色,看起来像这样:
ESC[number米
其中 number 部分是前景色的 30 到 37 和背景色的 40 到 47(加上一些额外的粗体或暗色代码,我不会包括在这里)。 (%C(reset) 发送 ESC [ m 并且您的橙色选择器使用 24 位颜色指令,与可追溯到 1990 年代的八种基色相比,它的支持范围更小)。因此,原始输出为:
* <sp> <orange> <hash-ID> <reset> <sp> - <sp> <blue> (n months ago) <reset> ...
grep
在匹配的表达式周围添加了红色,即 ESC [ 31 m 和一个重置 — 但 表达式中的现有转义符仍然存在。
到目前为止,避免这一切的最简单方法是完全停止使用颜色转义序列,这样 grep 添加的转义序列就会像 sore 红拇指一样突出。当然,这违背了您的目标,即在 未 突出显示的行中保留 color-changing 转义符。但是你还没有解释你想用 color-changing 行或部分行的转义来做什么, 被 突出显示。回答这个问题将决定下一步做什么。
有多种方法可以解决这个问题。例如,您可以使用 %x1b(name-of-color)%<directive>%x1b(reset)
代替 %C(color)%<directive>%C(reset)
来插入文字序列 ESC ( 颜色名称或重置) 或 假设 有问题的终端将使用以小写 m
字符结尾的 ANSI 样式转义,并尝试编写sed 或 awk 中的一些东西(我会用 awk 来处理这么复杂的东西,只是因为它不太像写行噪音)进行匹配——awk 支持正则表达式匹配——如果找到,去掉 来自 matched 部分的颜色序列并添加自己的颜色序列。 Post-process 这与插入适当的 terminal-dependent color-change 序列的东西有关,或者保留原始 ESC [ ... m 序列,假设你在 window 中使用该形式,您将获得所需的输出(如果需要,您现在可以通过 less -R
进行管道传输)。
一个可以执行您想要的操作的框架 awk 程序是:
/<desired regex>/ { handle matched line; next; }
{ print }
困难的部分是“处理匹配的行”。 GNU awk 有 RSTART 和 RLENGTH 可以提供很多帮助;参见,例如 this answer。行首到RSTART-1的子串不匹配(这可能为空),RSTART+RLENGTH到行尾的子串(也可能为空)也不匹配; [=21=]
在 RSTART 的子字符串长度 RLENGTH 匹配,如果你想在整个过程中应用你的基本红色(或其他),你可以在这里删除任何 color-changing 序列。
示例脚本(作者:Robin Hellmers)
创建脚本并将其放置在您喜欢的位置,例如
~/.local/bin/highlight-commit.awk
内容
#!/usr/bin/nawk -f
BEGIN {
n = split(commits,arrayCommits," ");
background="145;0;0"
foreground="255;255;255"
}
{
# Compare with every given input e.g. commit id
for (i=1; i <= n; i++) {
if(match([=13=],arrayCommits[i])) {
# Remove any ANSI color escape sequence for matching row
gsub("\x1b\[[0-9;]*m","",[=13=])
# Create ANSI color escape sequence for whole row
[=13=] = sprintf("\x1b[48;2;%sm\x1b[38;2;%sm%s\x1b[0m\x1b[0m",
background,
foreground,
[=13=]);
break;
}
}
printf("%s\n", [=13=]);
}
在~/.gitconfig
中添加如下alias
:
[alias]
highlight-commit = "!f() { git lg | awk -v commits=\"$*\" -f ~/.local/bin/highlight-commit.awk | less -XR; }; f"
通过调用例如两次提交:
git highlight-commit 82451f8 310fca4
我试图在我的 git 日志图中突出显示特定提交的整行。我之前创建了一个 git 日志别名来格式化我的日志输出。我试图使用我的别名突出显示包含提交 ID 的特定行。
别名 ~/.gitconfig
# Base command for log formatting
lg-base = "log --graph --decorate=short --decorate-refs-exclude='refs/tags/*' --color=always"
# Version 1 log format
lg1 = !"git lg-base --format=format:'%C(#f0890c)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(#d10000)%d%C(reset)'"
通过搜索 6 months
进行测试只是因为它应该表现相同并且可能更好地展示我的问题。
git lg1 | grep --color=always -E '(6 months).*|$'
匹配正确的行。但它并没有突出显示右边的整行,当试图突出显示该行的左侧部分时,它也没有按预期工作。可能是因为我不太会用regex。
git lg1 | grep --color=always -E '.*(6 months).*|$'
而是在开头标记 *
。
如果您有其他方法,我也可以,只要我可以使用我的格式化 git 日志别名即可。
grep
是 添加自己的 颜色(或颜色)更改转义序列以突出显示该行, Git 已经加入了变色指令。每个这样的指令,对于其中一种命名的颜色,看起来像这样:
ESC[number米
其中 number 部分是前景色的 30 到 37 和背景色的 40 到 47(加上一些额外的粗体或暗色代码,我不会包括在这里)。 (%C(reset) 发送 ESC [ m 并且您的橙色选择器使用 24 位颜色指令,与可追溯到 1990 年代的八种基色相比,它的支持范围更小)。因此,原始输出为:
* <sp> <orange> <hash-ID> <reset> <sp> - <sp> <blue> (n months ago) <reset> ...
grep
在匹配的表达式周围添加了红色,即 ESC [ 31 m 和一个重置 — 但 表达式中的现有转义符仍然存在。
到目前为止,避免这一切的最简单方法是完全停止使用颜色转义序列,这样 grep 添加的转义序列就会像 sore 红拇指一样突出。当然,这违背了您的目标,即在 未 突出显示的行中保留 color-changing 转义符。但是你还没有解释你想用 color-changing 行或部分行的转义来做什么, 被 突出显示。回答这个问题将决定下一步做什么。
有多种方法可以解决这个问题。例如,您可以使用 %x1b(name-of-color)%<directive>%x1b(reset)
代替 %C(color)%<directive>%C(reset)
来插入文字序列 ESC ( 颜色名称或重置) 或 假设 有问题的终端将使用以小写 m
字符结尾的 ANSI 样式转义,并尝试编写sed 或 awk 中的一些东西(我会用 awk 来处理这么复杂的东西,只是因为它不太像写行噪音)进行匹配——awk 支持正则表达式匹配——如果找到,去掉 来自 matched 部分的颜色序列并添加自己的颜色序列。 Post-process 这与插入适当的 terminal-dependent color-change 序列的东西有关,或者保留原始 ESC [ ... m 序列,假设你在 window 中使用该形式,您将获得所需的输出(如果需要,您现在可以通过 less -R
进行管道传输)。
一个可以执行您想要的操作的框架 awk 程序是:
/<desired regex>/ { handle matched line; next; }
{ print }
困难的部分是“处理匹配的行”。 GNU awk 有 RSTART 和 RLENGTH 可以提供很多帮助;参见,例如 this answer。行首到RSTART-1的子串不匹配(这可能为空),RSTART+RLENGTH到行尾的子串(也可能为空)也不匹配; [=21=]
在 RSTART 的子字符串长度 RLENGTH 匹配,如果你想在整个过程中应用你的基本红色(或其他),你可以在这里删除任何 color-changing 序列。
示例脚本(作者:Robin Hellmers)
创建脚本并将其放置在您喜欢的位置,例如
~/.local/bin/highlight-commit.awk
内容
#!/usr/bin/nawk -f
BEGIN {
n = split(commits,arrayCommits," ");
background="145;0;0"
foreground="255;255;255"
}
{
# Compare with every given input e.g. commit id
for (i=1; i <= n; i++) {
if(match([=13=],arrayCommits[i])) {
# Remove any ANSI color escape sequence for matching row
gsub("\x1b\[[0-9;]*m","",[=13=])
# Create ANSI color escape sequence for whole row
[=13=] = sprintf("\x1b[48;2;%sm\x1b[38;2;%sm%s\x1b[0m\x1b[0m",
background,
foreground,
[=13=]);
break;
}
}
printf("%s\n", [=13=]);
}
在~/.gitconfig
中添加如下alias
:
[alias]
highlight-commit = "!f() { git lg | awk -v commits=\"$*\" -f ~/.local/bin/highlight-commit.awk | less -XR; }; f"
通过调用例如两次提交:
git highlight-commit 82451f8 310fca4