git log -G<regex> -p
是一个很棒的工具,可以搜索代码库的历史记录以查找与指定模式匹配的更改。然而,在大多数不相关的块的海洋中找到差异/补丁输出中的相关块可能会让人不知所措。
当然可以搜索git log
原始字符串/正则表达式的输出,但这对于减少视觉噪音和许多不相关更改的干扰几乎没有作用。
阅读git log
,我看到有--pickaxe-all
,这与我想要的完全相反:它扩大了输出(到整个变更集),而我想限制它(到特定的块)。
本质上,我正在寻找一种方法来“智能地”将差异/补丁解析为单独的块,然后对每个块执行搜索(仅针对更改的行),丢弃不匹配的块,并输出那些块那样做。
是否存在我所描述的工具?有没有更好的方法来获得匹配/受影响的帅哥?
我所做的一些初步研究......
答案1
这里https://stackoverflow.com/a/35434714/5305907描述了一种执行您正在寻找的操作的方法。有效地:
git diff -U1 | grepdiff 'console' --output-matching=hunk
它仅显示与给定字符串“console”匹配的帅哥。
答案2
基于@nagu上面的答案和其他链接的答案,我能够git log -G
只显示相关的帅哥。
首先在 $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"
调用
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
只能在单个文件中使用,因此您可能需要跳过几个不相关的文件。