将 Git Diff 限制为一个或多个函数



我在.git/info/attributes中设置了*.py diff=python。所以 Git 知道函数边界在哪里。git diff -W 甚至可以确保显示整个函数。

但是有没有办法将 git diff 的输出限制为仅一个特定函数(或多个(?

(如果做不到这一点,我想这很尴尬...

编辑 这对git loggit rev-list也很有用:不要向我显示修改 views.py 的每个提交,向我显示修改其中某个函数的提交。(是的,在理想的世界中,views.py 不会是一个 2000 线的庞然大物,经常被 8 个不同的开发人员修改......

好的,感谢Birei,我们有一个解决方案。

在该答案中使用 awk 脚本,并结合一些 bash:

~/scripts/grit:

#!/bin/bash
cmd=$1
shift 1
if [ "$cmd" = "" ]; then
  git
# other commands not relevant to this question go here
elif [ $cmd = "funcdiff" ]; then
  git show "$1:$3" | awk -f ~/scripts/getfunc.awk -v f=$4 > /tmp/.tmp1
  git show "$2:$3" | awk -f ~/scripts/getfunc.awk -v f=$4 > /tmp/.tmp2
  git diff -W --no-index /tmp/.tmp1 /tmp/.tmp2 
else
  git $cmd $@
fi

示例用法:grit funcdiff 009e75 8b7a14 ./staging.py write_uploaded

这也可以作为 git 别名添加到 ~/.gitconfig 中

我没有找到任何其他选项(除了 --function-context 或其-W短选项,已经提到(能够将差异输出限制为单个函数。

即使这个-W选项也并不总是足够的,因为知道"函数"可能因语言而异,如这篇博文所示:

我发现这个选项相当不可靠,至少在大型 PHP 类中是这样。
我的测试发现--function-context经常导致显示几乎所有的原始文件,而 git 似乎对 PHP 的函数边界一无所知。
更改前后的上下文行数似乎是随机的,并且差异也不一定总是显示函数的所有行。

引入此更改的原始补丁消息提供了一些信息:

这个实现与 grep 中的实现具有相同的缺点,即无法显式找到函数的结尾。
这意味着会显示几行额外的上下文,直到下一个识别的函数开始。

因此,对于 git 来说,检测函数的边界似乎很困难。
似乎在这种情况下,git 永远不会检测到函数边界并向我们提供整个文件的上下文。


正如OP Steve Bennett指出的那样,一个潜在的解决方案是定义一个git别名,该别名将在修改前后提取修订版中的函数,以便在这2个"临时"文件上进行差异。
"创建 Git 别名"和"用于从文件中选择单个 Python 函数的 Bash 脚本"中的示例。

这是一个临时解决方案,它将能够解析 OP 碰巧在他的存储库中使用的特定类型的源。

最新更新