仅显示基于正则表达式的差异/补丁的相关块

仅显示基于正则表达式的差异/补丁的相关块

git log -G<regex> -p是一个很棒的工具,可以搜索代码库的历史记录以查找与指定模式匹配的更改。然而,在大多数不相关的块的海洋中找到差异/补丁输出中的相关块可能会让人不知所措。

当然可以搜索git log原始字符串/正则表达式的输出,但这对于减少视觉噪音和许多不相关更改的干扰几乎没有作用。

阅读git log,我看到有--pickaxe-all,这与我想要的完全相反:它扩大了输出(到整个变更集),而我想限制它(到特定的块)。

本质上,我正在寻找一种方法来“智能地”将差异/补丁解析为单独的块,然后对每个块执行搜索(仅针对更改的行),丢弃不匹配的块,并输出那些块那样做。

是否存在我所描述的工具?有没有更好的方法来获得匹配/受影响的帅哥?

我所做的一些初步研究......

  • 如果可以进行grepdiff/patch 输出并使上下文选项值动态化(例如,通过正则表达式而不是行计数),这可能就足够了。但grep并不完全是这样构建的(我也不一定要求该功能)。

  • 我找到了补丁工具套件,最初听起来可能适合我的需求。但在阅读其man页面后,这些工具似乎无法处理基于正则表达式的匹配块。 (不过他们可以接受帅哥名单……)

  • 我终于遇到了分割补丁.rb,它似乎可以很好地处理补丁的解析,但是需要对其进行显着增强才能处理通过 读取补丁stdin,匹配所需的块,然后输出块。

答案1

这里https://stackoverflow.com/a/35434714/5305907描述了一种执行您正在寻找的操作的方法。有效地:

git diff -U1 | grepdiff 'console' --output-matching=hunk

它仅显示与给定字符串“console”匹配的帅哥。

答案2

基于@nagu上面的答案和其他链接的答案,我能够git log -G只显示相关的帅哥。

  1. 首先在 $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=$1
    old_file=$2
    old_hex=$3
    old_mode=$4
    new_file=$5
    new_hex=$6
    new_mode=$7
    
    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 镐的工作方式是将输出限制为文件谁的帅哥改变了给定的字符串/正则表达式。这意味着,如果这些文件中的另一个块也包含搜索字符串/正则表达式,但不更改它,它仍然会与上面的脚本一起显示。这是 grepdiff 的限制。 patchutils 项目中有一个开放的拉取请求,要求--only-matching向 grepdiff 添加一个标志,这将提供正确过滤掉这些大块所需的功能。


我在中写了我的解决方案这个要点

答案3

不完全是你所要求的,但 grep 的一种方法是交互添加模式。这要求您在感兴趣的补丁之后检查提交

git checkout COMMIT_ID

然后在 VCS 中再返回一步,但不在工作目录中

git reset --soft HEAD^

(此时,索引和工作目录之间的差异将对应于您感兴趣的补丁。)

您现在可以执行git add -p.这将启动一个交互式会话/,其中有一个选项,允许您找到其中某些行与正则表达式匹配的块。如果您确实想进一步处理这些补丁(例如,准备部分樱桃采摘),则特别有用。

不幸的是,至少现在该/命令add -p只能在单个文件中使用,因此您可能需要跳过几个不相关的文件。

相关内容