有没有办法让git给你一个提交日志,只是提交了一个文件中特定的行 ?
类似于git blame,但是git blame将显示触及特定行的最后一次提交。
git blame
我希望得到一个类似的日志,不是文件中任何地方的提交列表,而是触及特定行的提交。
你可以通过使用picko -axe来获得一组提交。
git log -S'the line from your file' -- path/to/your/file.txt
这将为您提供影响该文件中该文本的所有提交。如果文件在某个时候被重命名,您可以添加——follow-parent。
如果你想在每次编辑时检查提交,你可以将结果管道到git show:
git log ... | xargs -n 1 git show
我不相信有什么内置的。这很棘手,因为很少有一行更改多次,而文件的其余部分也没有发生重大更改,所以最终往往会导致行号更改很多。
如果你足够幸运,这一行总是有一些标识特征,例如,赋值给一个名称从未改变的变量,你可以使用正则表达式选择git blame -L。例如:
git blame -L
git blame -L '/variable_name *= */',+1
但是这只会为这个正则表达式找到第一个匹配,所以如果你没有一个很好的方法来匹配行,它没有太大的帮助。
我猜你可以做点什么。我现在没有时间写代码,但是…沿着这条线。# EYZ0运行。第一个字段是之前提交的内容,第二个字段是那提交中的行号,因为它可能会改变。获取这些文件,然后运行git blame -n $n,$n $commit^ $file,也就是说,从上次修改文件之前的提交开始执行相同的操作。
git blame -n $n,$n $commit^ $file
(请注意,如果更改行的最后一次提交是合并提交,这将失败。如果作为合并冲突解决的一部分,行被更改,那么这种情况可能发生的主要方式。)
编辑:我今天偶然看到此邮件列表帖子从2011年3月开始,其中提到tig和git gui有一个功能可以帮助你做到这一点。对于git本身来说,这个特性似乎已经考虑过了,但还没有完成。
tig
git gui
这将调用git blame对每一个进行有意义的修订,以显示文件$FILE的$LINE行:
$FILE
$LINE
git log --format=format:%H $FILE | xargs -L 1 git blame $FILE -L $LINE,$LINE
像往常一样,责备在每行开头显示修订号。你可以添加
| sort | uniq -c
要获得聚合结果,可以使用更改这一行的提交列表之类的东西。(不完全是,如果代码只是被移动了,这可能会对行中不同的内容显示相同的提交ID两次。为了进行更详细的分析,您必须对相邻提交的git blame结果进行滞后比较。有人知道吗?)
下面是一个定义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 }
十字镐解决方案(git log——pickax -regex -S' regex ')只会给您添加/删除行,而不是包含正则表达式的行的其他更改。
这个解决方案的一个限制是git责备只返回第一个REGEX匹配,所以如果存在多个匹配,递归可能会“跳转”到另一行。一定要检查完整的历史输出以发现那些“跳转”,然后修复REGEX以忽略寄生行。
最后,这里有一个替代版本,在每次提交时运行git显示来获得完整的差异:
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:发现哪些提交曾经触碰过某个行范围。
从Git 1.8.4开始, git log有-L来查看一系列线条的演变。
git log
-L
例如,假设您查看git blame的输出。这里-L 150,+11表示“只看150到150+11行”:
-L 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行的演变”。
-L 155,155:git-web--browse.sh
git-web--browse.sh
$ 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)
一个非常简单的方法是使用vim-fugitive。只需在vim中打开文件,使用V选择感兴趣的行,然后输入
V
:Glog
现在您可以使用:cnext和:cprev来查看该行被修改的文件的所有修订。在任何时候,输入:Gblame以查看sha、作者和日期信息。
:cnext
:cprev
:Gblame
尝试使用Git 1.8.4中实现的以下命令。
git log -u -L <upperLimit>,<lowerLimit>:<path_to_filename>
所以,在你的情况下,upperLimit &lowerLimit是被触动的line_number
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 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>"
当然,这可以被做成一个脚本或一个函数。
简化@matt的回答-
# EYZ0
在这里你会得到一行14 to 15的责备。
14 to 15
# EYZ4。
Reference .
如果该行的位置(行号)在文件的历史记录中保持不变,这将在每次提交时显示该行的内容:
git log --follow --pretty=format:"%h" -- 'path/to/file' | while read -r hash; do echo $hash && git show $hash:'path/to/file' | head -n 544 | tail -n1; done
将544更改为行号,path/to/file更改为文件路径。
544
path/to/file
简单的git责备命令 线路启动&结束(735750)< / p >
L735,750(语法)
git责备-L735,750 patient.php(文件路径&名称)