如何使用 git 日志镐来显示更改本身?

How to show the change itself using git log pickaxe?

我想在 git 日志中搜索特定字符串以查找它所在的位置 modified/deleted/added。

我知道我可以使用 pickaxe(即 git log -S"Text"

当我运行这个命令时,只显示发生更改的提交的名称。我也试过 git log -G"Text" 但没有区别。

当我尝试 git log -p -S"Text" 时,它显示了两个文件版本之间的完整比较。

有没有办法找出文本所在的确切位置(行)changed/added/deleted?

我查看了相关帖子 1, 2 但没有回答我的问题。我正在研究 Windows OS.

Git 不提供执行此操作的内置方法,但您可以使用寻呼机的功能来查找文本。例如,如果您使用较少,则可以 运行 git log -p -G"Text"。然后您可以通过键入 /Text 在此命令的输出中搜索 "Text"。这是迄今为止找到所需内容的最简单方法。

有一种替代的、相当丑陋的方法可以解决这个问题,它可能会满足您的需要。如果您使用 --word-diff-regex=Text,Git 将生成另一种字差异格式,该格式将从 "Text" 的一个实例突出显示到下一个实例,或者如果只有一个实例,则只突出显示单个实例。同样,使用您的寻呼机会更好、更容易阅读。

实现您的目标的另一种方法是使用外部差异驱动程序和 patchutils 包中的 grepdiff 实用程序。 (我回答了 Linux here 的类似问题)。

警告:我不用Windows,好像是patchutils is not available in the usual Windows package managers。所以这个答案的先决条件是自己编译 grepdiff (这可能太多了:P)。如果你能做到这一点,并找到一种方法将其安装在 Git Bash 中,那么这种方法可能会奏效。

  1. 首先在C:\Program Files\Git\usr\bin下创建一个脚本,并将其命名为pickaxe-diff(注意:再一次,我不使用Windows,但我正在阅读因此,这是向 Git Bash PATH) 添加内容的简单方法:

    #!/bin/bash
    
    # pickaxe-diff : external diff driver for Git.
    #                To be used with the pickaxe options (git [log|show|diff[.*] [-S|-G])
    #                to only show hunks containing the searched string/regex.
    
    path=
    old_file=
    old_hex=
    old_mode=
    new_file=
    new_hex=
    new_mode=
    
    filtered_diff=$(diff -u -p $old_file $new_file | \
                    grepdiff "$GREPDIFF_REGEX" --output-matching=hunk | \
                    grep -v -e '+++ ' -e '--- ')
    
    a_path="a/$path"
    b_path="b/$path"
    
    echo "diff --git $a_path $b_path"
    echo "index $old_hex..$new_hex $old_mode"
    echo "--- $a_path"
    echo "+++ $b_path"
    echo "$filtered_diff"
    
  2. 调用 git log -G 并告诉 Git 使用 pickaxe-diff 脚本作为外部 diff 驱动程序:

    export GREPDIFF_REGEX=<string>; 
    GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX
    

这将使用 pickaxe-diff 脚本来生成差异,因此 git log 输出的其余部分(提交哈希、消息等)将保持不变。

警告
Git 镐的工作方式是将输出限制为 文件 ,其 hunks 更改给定的 string/regex。这意味着如果这些文件中的另一个 hunk 也包含搜索 string/regex,但不更改它,它仍将与上述脚本一起显示。这是 grepdiff 的限制(直到版本 0.3.4)。 patchutils 项目中的 recently merged pull requestgrepdiff 添加了一个 --only-match 标志,它应该提供正确过滤掉这些大块头所需的功能(您需要 patchutils 0.4.0 或更高版本)。


我在 this gist 中做了一个 write-up 的解决方案。