有没有办法让git给你一个提交日志,只提交触及文件中的特定行?
就像git blame,但git blame会显示触及特定行的LAST commit。
我希望得到一个类似的日志,不是文件中任何地方的提交列表,而是触及特定行的提交。
有没有办法让git给你一个提交日志,只提交触及文件中的特定行?
就像git blame,但git blame会显示触及特定行的LAST commit。
我希望得到一个类似的日志,不是文件中任何地方的提交列表,而是触及特定行的提交。
当前回答
简化@matt的回答-
get - l14,15——<file_path>
这里你会看到第14行到第15行。
因为-L选项需要Range作为参数,我们不能使用-L选项获得单行的责备。
参考
其他回答
这将调用git blame为每一个有意义的修订显示line $ line文件$ file:
git log --format=format:%H $FILE | xargs -L 1 git blame $FILE -L $LINE,$LINE
像往常一样,责备在每行开头显示修订号。你可以添加
| sort | uniq -c
要获得聚合结果,可以使用更改这一行的提交列表之类的东西。(不完全是,如果代码只是被移动了,这可能会对行中不同的内容显示相同的提交ID两次。为了进行更详细的分析,您必须对相邻提交的git blame结果进行滞后比较。有人知道吗?)
在我的例子中,行号随着时间的推移发生了很大的变化。 我也在git 1.8.3上,它不支持“git blame -L”中的正则表达式。 (RHEL7仍然有1.8.3)
myfile=haproxy.cfg
git rev-list HEAD -- $myfile | while read i
do
git diff -U0 ${i}^ $i $myfile | sed "s/^/$i /"
done | grep "<sometext>"
Oneliner:
myfile=<myfile> ; git rev-list HEAD -- $myfile | while read i; do git diff -U0 ${i}^ $i $myfile | sed "s/^/$i /"; done | grep "<sometext>"
当然,这可以被做成一个脚本或一个函数。
下面是一个定义git别名的解决方案,所以你可以像这样使用它:
git rblame -M -n -L '/REGEX/,+1' FILE
输出示例:
00000000 18 (Not Committed Yet 2013-08-19 13:04:52 +0000 728) fooREGEXbar
15227b97 18 (User1 2013-07-11 18:51:26 +0000 728) fooREGEX
1748695d 23 (User2 2013-03-19 21:09:09 +0000 741) REGEXbar
您可以在.gitconfig中定义别名,也可以简单地运行以下命令
git config alias.rblame !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); echo $line; done' dumb_param
这是一个丑陋的一行程序,所以这里有一个去混淆的等效bash函数:
git-rblame () {
local commit line
while line=$(git blame "$@" $commit 2>/dev/null); do
commit="${line:0:8}^"
if [ "00000000^" == "$commit" ]; then
commit=$(git rev-parse HEAD)
fi
echo $line
done
}
pickaxe解决方案(git log——pickaxe-regex -S' regex ')只会给你添加/删除行,而不会对包含正则表达式的行进行其他更改。
这个解决方案的一个限制是git blame只返回第一个REGEX匹配,所以如果存在多个匹配,递归可能会“跳转”到另一行。一定要检查完整的历史输出以发现那些“跳转”,然后修复REGEX以忽略寄生行。
最后,这里有一个替代版本,在每次提交时运行git show来获得完整的diff:
git config alias.rblameshow !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); git show $commit; done' dumb_param
尝试使用Git 1.8.4中实现的以下命令。
git log -u -L <upperLimit>,<lowerLimit>:<path_to_filename>
在你的例子中,upperLimit & lowerLimit是触摸的line_number
更多信息可以在这里找到。
简化@matt的回答-
get - l14,15——<file_path>
这里你会看到第14行到第15行。
因为-L选项需要Range作为参数,我们不能使用-L选项获得单行的责备。
参考