如何grep git diff?


81

有没有办法显示通过给定模式过滤的git-diff。

就像是

git grepdiff pattern

changed file
+++ some sentence with pattern
changed file 2
--- some other pattern

不幸的是,最简单的解决方案还不够好

git diff | grep pattern 

+++ some sentence with pattern
--- some other pattern
# not an option as doesn't put the filename close to the match

我使用awk提供了一种解决方法

git diff | awk "/\+\+\+/{f = \$2}; /PATTERN/ {print f \$0} "

但是很乐意找出对此有一个命令。


3
显然,名为git-diff-grep的github项目的功能完全不同。
库巴2012年

Answers:


98

不确定但git diff -G <regex>标记不正确吗?

-G <正则表达式>

Look for differences whose added or removed line matches the given <regex>.

15
那不是我要找的东西,因为我只想看匹配模式的行-而不是整个文件的差异,包括模式的更改
Kuba 2012年

那么我想没有比您更简单的解决方案了
CharlesB 2012年

至少git diff -G比完整git diff更好的第一步。
库巴2012年

1
我的版本没有-G标志。它被删除了吗?
RedX 2014年

3
查看哪些文件受正则表达式影响也很有用:git diff -G <regex> --raw
拉曼


11

另一种可能性是查看整个diff并使用常规less命令(键入/然后键入模式)搜索输出。

当您使用less配置了在比赛之前显示一些行时--jump-target=N,这非常有用。像这样尝试:

PAGER="/usr/bin/less --jump-target=10" git diff

这意味着匹配项应该显示在第10行(上面显示了9行上下文),这可能足以查看文件名。

您也可以使用例如--jump-target=.5将其放置在屏幕中间。


3

我使用git log -p,它打开的次数较少(不过是可配置的),而可以使用搜索/。也有git log -S <searchword>


我熟悉这些内容-因为我不是在看历史,而是在当前的工作变化中。
库巴2012年

好了,那么可以使用相同的方法(如robinst所引用)。如果需要输出,则可以使用任何使用libgit2或gitgui / gitk的库。
chelmertz 2012年

1

这为我完成了工作,我希望它将对某人有所帮助:

git diff | grep  -P '^\+|^\-'

1

我认为您处理“ grep”diff输出的方法是最好的解决方法。

您可以使用sed改进awk脚本:

colored="(^[\[[0-9;]*[a-zA-Z])"
marker="^$colored+diff"
pattern="^$colored+.*(\+|\-).*PATTERN"
git diff --color | sed -rn -e "/$marker/! H; /$marker/ ba; $ ba; b; :a; x; /$pattern/ p"
  • colored:正则表达式以匹配终端彩色线
  • marker:标记以匹配来自不同块的划分diff,以彩色“ diff”开头的行
  • pattern:要搜索的模式,以彩色“ +”或“-”开头并包含“ PATTERN”的行

这将打印带有添加或删除的PATTERN的完整差异块,并保持有用的彩色输出。

请注意,^[incolored应该是实际的,字面的^[。您可以通过按Ctrl+ VCtrl+在bash中键入它们[


优秀!!对于试图在bash shell以外的其他地方(例如在IDE中编辑.sh文件)键入此内容的任何人,您都需要替换^[like,colored=$'(\e\[[0-9;]*[a-zA-Z])'而在macOS上,您也需要brew install gnu-sed替换sed --> gsed
Anentropic

0

这是一个自定义的diff工具,允许对内部更改(而不是上下文)进行grepping:

用法

GIT_EXTERNAL_DIFF="mydiff --grep foo" git diff

这将输出包含更改的foo行(包括foo由于更改而消失的行)。可以使用任何grep模式代替foo

每条输出行均以以下前缀开头:

filename: oldlinenum: newlinenum|

脚本也可以不带--grep选项使用,在这种情况下,它如上所述就可以简单格式化完整的差异(即提供完整的上下文)。

米迪夫

#!/bin/bash

my_diff()
{
    diff --old-line-format="$1"':%6dn:      |-%L'     \
         --new-line-format="$1"':      :%6dn|+%L'     \
         --unchanged-line-format="$1"':%6dn:%6dn| %L' \
         $2 $3
}

if [[ $1 == '--grep' ]]
then
    pattern="$2"
    shift 2
    my_diff "$1" "$2" "$5"|grep --color=never '^[^|]\+|[-+].\+'"$pattern"'.*'
else
    my_diff "$1" "$2" "$5"
fi

exit 0

0

在Windows上,一个简单的解决方案是:

git diff -U0 | findstr string

如果要按文件名分组,请使用此

FOR /F "usebackq delims==" %i IN (`git diff --name-only`) do git diff -U0 %~fi | findstr string

0

我一直很满意地使用它:)

grep -ri <MY_PATTERN> $(git diff 790e26393d --name-only) 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.