git 日志图中特定提交的突出显示行

发布于 2025-01-14 14:57:02 字数 1160 浏览 7 评论 0原文

我试图在 git 日志图中突出显示特定提交的整行。我之前创建了一个 git log 别名来格式化日志的输出。我尝试使用我的别名突出显示包含 commit-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 个月 进行测试,只是因为它应该表现相同,并且可能会更好地展示我的问题。

git lg1 | git lg1 | git lg1 | git lg1 | git lg1 grep --color=always -E '(6 个月).*|$'

在此处输入图像描述

匹配正确的行。但它不会突出显示右侧的整行,并且当尝试突出显示该行的左侧部分时,它不会按预期工作。可能是因为我缺乏使用正则表达式的技能。

git lg1 | git lg1 | git lg1 | git lg1 | git lg1 grep --color=always -E '.*(6months).*|$'

相反,它在开头标记 *

如果您有其他方法,只要我可以使用格式化的 git log 别名,这对我来说就很好。

输入图片此处描述

I am trying to highlight the whole line for a specific commit in my git log graph. I have since before created a git log alias to format the output of my logs. I have attempted to highlight a specific line containing the commit-id, using my alias.

Alias in ~/.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)'"

Doing a test with searching for 6 months just because it should behave the same and might showcase my issue a bit better.

git lg1 | grep --color=always -E '(6 months).*|$'

enter image description here

Matches the correct lines. But it doesn't highlight the whole line to the right and when trying to highlight the left part of the line as well, it doesn't work as expected. Probably because of my lack in skills of using regex.

git lg1 | grep --color=always -E '.*(6 months).*|$'

Instead it marks the * in the beginning.

If you have a total other approach, that is fine with me as long as I can use my formatted git log alias.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紅太極 2025-01-21 14:57:02

Thomas 的评论是关键这里的问题:虽然 grep 正在添加自己的颜色(或颜色)更改转义序列来突出显示该行,但 Git 已经放入颜色更改指令。对于其中一种指定颜色,每个此类指令如下所示:

ESC[numberm

其中数字部分为前景色30到37,背景色40到47(加上一些粗体或暗淡的额外代码,我不会包括这些代码) 这里)。 (%C(reset) 发送 ESC [ m 并且您的橙色选择器使用 24 位颜色指令,该指令的支持范围不如 8 种基色(可追溯到 1990 年代)。因此,原始输出如下:

* <sp> <orange> <hash-ID> <reset> <sp> - <sp> <blue> (n months ago) <reset> ...

grep 在匹配的表达式周围添加红色(即 ESC [ 31 m)和重置,但表达式内的现有转义仍然保留。

到目前为止,避免这一切的最简单方法是完全停止使用颜色转义序列,以便 grep 添加的颜色转义序列像酸痛的红色拇指一样突出。当然,这违背了您的目标,即使变色转义符保持在突出显示的行中。但您还没有解释您希望如何处理突出显示的行或部分行中的变色转义符。回答这个问题将决定下一步做什么。

有多种方法可以解决这个问题。例如,您可以使用 %x1b(name-of-color)%%x1b( 而不是 %C(color)%%C(reset) reset) 插入文字序列 ESC ( 颜色名称或重置 ),或者假设相关终端将使用以小写 m 字符结尾的 ANSI 样式转义,并尝试在 sed 或 awk 中编写一些内容(我会使用 awk如此复杂的东西,只是因为它不像编写行噪音)进行匹配 - awk 支持正则表达式匹配 - 如果找到,匹配部分中删除颜色序列并添加其 自己的。使用插入适当的与终端相关的颜色更改序列的内容进行后处理,或者保留原始的 ESC [ ... m 序列(假设您位于使用该形式的窗口中),并且您将拥有您想要的输出(如果需要,您现在可以通过 less -R 进行管道传输)。

执行您想要的操作的骨架 awk 程序是:

/<desired regex>/ { handle matched line; next; }
{ print }

困难的部分是“处理匹配行”。 GNU awk 有 RSTART 和 RLENGTH 可以提供很多帮助;例如,请参阅此答案。从行首到RSTART-1的子串不匹配(可能为空),从RSTART+RLENGTH到行尾的子串(也可能为空)也不匹配; RSTART 处长度为 RLENGTH 的 $0 子字符串已匹配,如果您希望在整个过程中应用基本红色(或其他),则可以在此处删除任何颜色变化序列。


示例脚本(作者: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($0,arrayCommits[i])) {
            # Remove any ANSI color escape sequence for matching row
            gsub("\x1b\\[[0-9;]*m","",$0)
            # Create ANSI color escape sequence for whole row
            $0 = sprintf("\x1b[48;2;%sm\x1b[38;2;%sm%s\x1b[0m\x1b[0m", 
                         background,
                         foreground,
                         $0);
            break;
        }
    }
    printf("%s\n", $0);
}

~/.gitconfig 中,添加以下别名

[alias]
    highlight-commit = "!f() { git lg | awk -v commits=\"$*\" -f ~/.local/bin/highlight-commit.awk | less -XR; }; f"

通过调用,例如两次提交:

githighlight-commit 82451f8 310fca4

在此处输入图像描述

Thomas' comment is the key to the issue here: although grep is adding its own color (or colour) changing escape sequences to highlight the line, Git has already put in color changing directives. Each such directive, for one of the named colors, looks like this:

ESC[numberm

where the number part is 30 through 37 for a foreground color and 40 through 47 for a background color (plus some extra codes for bold or dim, which I won't include here). (%C(reset) sends ESC [ m and your orange selector uses a 24-bit color directive, which is less widely supported than the eight base colors, which go back to the 1990s). Hence the original output reads:

* <sp> <orange> <hash-ID> <reset> <sp> - <sp> <blue> (n months ago) <reset> ...

The grep adds red, which is ESC [ 31 m, and a reset, around the matched expression—but the existing escapes within the expression remain.

The easiest way by far to avoid all this is to stop using color escape sequences at all, so that grep's added ones stick out like a sore red thumb. Of course that defeats your goal, which is to keep the color-changing escapes in lines that aren't highlighted. But you haven't explained what you'd like done with the color-changing escapes in lines, or parts of lines, that are highlighted. Answering that will determine what to do next.

There are any number of ways you could handle this. For instance, instead of %C(color)%<directive>%C(reset) you could use %x1b(name-of-color)%<directive>%x1b(reset) to insert the literal sequences ESC ( name of color or reset ), or assume that the terminal in question will use ANSI style escapes that end with the lowercase m character, and try to write something up in sed or awk (I'd use awk for something this complex, just because it's less like writing line noise) that does the match—awk supports regex matching—and if found, strips out the color sequences from the matched part and adds its own. Post-process this with something that inserts the appropriate terminal-dependent color-change sequences, or keep the original ESC [ ... m sequences on the assumption that you're in a window that uses that form, and you'll have the output you want (which you can now pipe through less -R if desired).

A skeleton awk program that does what you want is:

/<desired regex>/ { handle matched line; next; }
{ print }

The hard part is the "handle matched line". GNU awk has RSTART and RLENGTH to help out a lot; see, e.g., this answer. The substring of the line from the beginning to RSTART-1 wasn't matched (this may be empty), and the substring from RSTART+RLENGTH to the end of the line (which may also be empty) also was not matched; the substring of $0 at RSTART for length RLENGTH was matched and here's where you would strip out any color-changing sequences, if you want your basic red (or whatever) applied throughout.


Sample script (by Robin Hellmers)

Creating a script and placing it where you please, e.g.

~/.local/bin/highlight-commit.awk

with the contents

#!/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($0,arrayCommits[i])) {
            # Remove any ANSI color escape sequence for matching row
            gsub("\x1b\\[[0-9;]*m","",$0)
            # Create ANSI color escape sequence for whole row
            $0 = sprintf("\x1b[48;2;%sm\x1b[38;2;%sm%s\x1b[0m\x1b[0m", 
                         background,
                         foreground,
                         $0);
            break;
        }
    }
    printf("%s\n", $0);
}

In ~/.gitconfig, add the following alias:

[alias]
    highlight-commit = "!f() { git lg | awk -v commits=\"$*\" -f ~/.local/bin/highlight-commit.awk | less -XR; }; f"

By calling with e.g. two commits:

git highlight-commit 82451f8 310fca4

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文