问题
I set *.py diff=python
in .git/info/attributes
. So Git knows where function boundaries. git diff -W can even make sure the whole function is shown.
But is there a way to limit the output of a git diff to just a particular function (or more than one)?
(Failing that, I guess it's awk...)
EDIT This would also be useful for git log
and git rev-list
: don't show me every commit that modifies views.py, show me commits that modify a certain function in it. (Yes, in an ideal world, views.py wouldn't be a 2000 line behemoth frequently modified by 8 different developers...)
回答1:
Ok, thanks to Birei, we have a solution.
Use the awk script in that answer, combined with a bit of 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
Example usage: grit funcdiff 009e75 8b7a14 ./staging.py write_uploaded
This could also be added as a git alias in ~/.gitconfig
回答2:
I didn't find any other option (other than the --function-context
or its -W
short option, already mentioned) able to restrict a diff output to a single function.
And even that -W
option isn't always enough, knowing that a 'function' can vary greatly from language to language, as illustrated in this blog post:
I’ve found this option rather unreliable, at least within a large PHP class.
My tests found--function-context
often results in displaying almost all of the original file, and git appears ignorant of PHP’s function boundaries.
The number of context lines before and after a change seem random, and the diff doesn’t necessarily always show all lines of the function, either.The original patch message that introduced this change sheds some light:
This implementation has the same shortcoming as the one in grep, namely that there is no way to explicitly find the end of a function.
That means that a few lines of extra context are shown, right up to the next recognized function begins.So it appears detecting a function’s boundaries is difficult for git.
It seems in this instance, git never detects a function boundary and gives us the context of the entire file.
As the OP Steve Bennett points out, a potential solution would be to define a git alias which would extract the function in the revision before and after modification, in order to diff on those 2 'temp' files.
Example in "Creating Git Aliases" and "Bash script to select a single Python function from a file".
This is an ad-hoc solution which will be able to parse the specific type of source the OP happens to work with in his repo.
来源:https://stackoverflow.com/questions/10478210/limit-git-diff-to-one-or-more-functions