有没有办法让git给你一个提交日志,只提交触及文件中的特定行?
就像git blame,但git blame会显示触及特定行的LAST commit。
我希望得到一个类似的日志,不是文件中任何地方的提交列表,而是触及特定行的提交。
有没有办法让git给你一个提交日志,只提交触及文件中的特定行?
就像git blame,但git blame会显示触及特定行的LAST commit。
我希望得到一个类似的日志,不是文件中任何地方的提交列表,而是触及特定行的提交。
当前回答
我不相信有什么内置的。这很棘手,因为很少有一行更改多次,而文件的其余部分也没有发生重大更改,所以最终往往会导致行号更改很多。
如果你足够幸运,这一行总是有一些识别特征,例如赋值给一个名称从未改变的变量,你可以使用regex选项git blame -L。例如:
git blame -L '/variable_name *= */',+1
但这只会找到正则表达式的第一个匹配项,所以如果你没有一个匹配行的好方法,它就没有太大的帮助。
我猜你可以做点什么。我现在没有时间写代码,但是…沿着这条线。运行git blame -n -L $n,$n $file。第一个字段是前一次提交所触及的,第二个字段是该提交中的行号,因为它可能会改变。获取这些,然后运行git blame -n $n,$n $commit^ $file,也就是说,从上次修改文件之前的提交开始。
(请注意,如果更改行的最后一次提交是合并提交,这将失败。如果作为合并冲突解决的一部分,行被更改,那么这种情况可能发生的主要方式。)
编辑:我今天偶然看到了这篇2011年3月的邮件列表,其中提到tig和git gui有一个功能可以帮助你做到这一点。对于git本身来说,这个特性似乎已经考虑过了,但还没有完成。
其他回答
简化@matt的回答-
get - l14,15——<file_path>
这里你会看到第14行到第15行。
因为-L选项需要Range作为参数,我们不能使用-L选项获得单行的责备。
参考
尝试使用Git 1.8.4中实现的以下命令。
git log -u -L <upperLimit>,<lowerLimit>:<path_to_filename>
在你的例子中,upperLimit & lowerLimit是触摸的line_number
更多信息可以在这里找到。
您可以混合使用git blame和git log命令来检索git blame命令中每次提交的摘要并附加它们。类似于以下bash + awk脚本。它将提交摘要作为代码注释内联添加。
git blame FILE_NAME | awk -F" " \
'{
commit = substr($0, 0, 8);
if (!a[commit]) {
query = "git log --oneline -n 1 " commit " --";
(query | getline a[commit]);
}
print $0 " // " substr(a[commit], 9);
}'
一句话:
git blame FILE_NAME | awk -F" " '{ commit = substr($0, 0, 8); if (!a[commit]) { query = "git log --oneline -n 1 " commit " --"; (query | getline a[commit]); } print $0 " // " substr(a[commit], 9); }'
请参见Git:发现哪些提交曾经接触过一系列行。
从Git 1.8.4开始,Git log有-L来查看行范围的演变。
例如,假设您查看git blame的输出。这里- l150,+11表示“只看150到150+11行”:
$ git blame -L 150,+11 -- git-web--browse.sh
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 150) die "The browser $browser is not
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 151) fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 152) fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 153)
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 154) case "$browser" in
81f42f11 git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:38 +0100 155) firefox|iceweasel|seamonkey|iceape)
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 156) # Check version because firefox < 2.0 do
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 157) vers=$(expr "$($browser_path -version)"
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 158) NEWTAB='-new-tab'
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 159) test "$vers" -lt 2 && NEWTAB=''
a0685a4f git-web--browse.sh (Dmitry Potapov 2008-02-09 23:22:22 -0800 160) "$browser_path" $NEWTAB "$@" &
你想知道155行的历史。
然后,使用git log。这里,-L 155,155:git-web——browse.sh表示“跟踪文件git-web——browse.sh中155行到155行的演变”。
$ git log --pretty=short -u -L 155,155:git-web--browse.sh
commit 81f42f11496b9117273939c98d270af273c8a463
Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
web--browse: support opera, seamonkey and elinks
diff --git a/git-web--browse.sh b/git-web--browse.sh
--- a/git-web--browse.sh
+++ b/git-web--browse.sh
@@ -143,1 +143,1 @@
-firefox|iceweasel)
+firefox|iceweasel|seamonkey|iceape)
commit a180055a47c6793eaaba6289f623cff32644215b
Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
web--browse: coding style
diff --git a/git-web--browse.sh b/git-web--browse.sh
--- a/git-web--browse.sh
+++ b/git-web--browse.sh
@@ -142,1 +142,1 @@
- firefox|iceweasel)
+firefox|iceweasel)
commit 5884f1fe96b33d9666a78e660042b1e3e5f9f4d9
Author: Christian Couder <chriscool@tuxfamily.org>
Rename 'git-help--browse.sh' to 'git-web--browse.sh'.
diff --git a/git-web--browse.sh b/git-web--browse.sh
--- /dev/null
+++ b/git-web--browse.sh
@@ -0,0 +127,1 @@
+ firefox|iceweasel)
在我的例子中,行号随着时间的推移发生了很大的变化。 我也在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>"
当然,这可以被做成一个脚本或一个函数。