检索文件中特定行的提交日志?

jro*_*ind 465 git

有没有办法让git为你提交一个提交日志,只提交触及文件中特定的提交?

喜欢git blame,但git blame会向您显示触及特定行的最后提交.

我真的想得到一个类似的日志,而不是文件中任何地方的提交列表,而只是提交到特定行的提交.

Mat*_*ure 581

另请参阅Git:发现哪些提交触及了一系列行.


自从Git 1.8.4以来,git log已经-L看到了一系列线路的演变.

例如,假设您查看git blame输出.这-L 150,+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 "$@" &
Run Code Online (Sandbox Code Playgroud)

而你想知道现在的第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)
Run Code Online (Sandbox Code Playgroud)

  • 升级到Git 1.8.4或更高版本. (11认同)
  • 如果我想知道“ commitA中第155行的历史”(而不是HEAD中的第155行)怎么办?我可以简单地使用`git log commitA-hash -L 155,155:file-name`吗? (3认同)
  • 'git log --topo-order --graph -u -L 155,155:git-web--browse.sh' - 这给出了一个致命的错误:'无效的对象名称155,155'.Git版本:1.8.3.2.有什么建议? (2认同)
  • 这工作得很好,除非文件已被移动/重命名...似乎 --follow 不喜欢与行范围参数组合。 (2认同)

Ada*_*ruk 65

你可以使用pick-ax获得一组提交.

git log -S'the line from your file' -- path/to/your/file.txt
Run Code Online (Sandbox Code Playgroud)

这将为您提供影响该文件中该文本的所有提交.如果文件在某个时候重命名,您可以添加--follow-parent.

如果您想在每个编辑中检查提交,可以将结果传递给git show:

git log ... | xargs -n 1 git show
Run Code Online (Sandbox Code Playgroud)

  • 我不确定我看到这有多大帮助.如果文本受到影响,那么该行不再相同,因此pickaxe只会向您显示最近的更改.然后你必须做`git log -S'the之前版本的''等等,就像你最终用`git blame -L`做的那样.它会比'git blame'慢得多,因为它必须在任何地方寻找文本,而不仅仅是在给定的位置. (5认同)
  • 为什么将此称为_pick-axe_?:) (3认同)

jit*_*hit 41

尝试使用Git 1.8.4中实现的以下命令.

git log -u -L <upperLimit>,<lowerLimit>:<path_to_filename>
Run Code Online (Sandbox Code Playgroud)

所以,在你的情况下upperLimit,lowerLimit是感动的line_number

  • 我认为使用`-L`时会忽略`--pretty = short`.请改正 (2认同)

Cor*_*ein 14

一个非常简单的方法是使用vim-fugitive.只需在vim中打开文件,选择您感兴趣的行V,然后输入

:Glog
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用:cnext:cprev查看修改该行的文件的所有修订版.在任何时候,输入:Gblame以查看sha,author和date信息.


Swa*_*aps 12

简化@ matt的答案 -

git blame -L14,15 -- <file_path>

在这里你会得到一个线路的责任14 to 15.

由于-L期权Range作为一个参数,我们无法Blame使用-L期权获得单行.

参考

  • 如果您只对第 14 行感兴趣,`gitblame -L14,14 -- &lt;file_path&gt;` 也可以工作。 (6认同)

Cas*_*bel 10

我不相信这里有任何内置的东西.由于在没有文件的其余部分发生重大变化的情况下,单行更改几次很少,因此很难实现,因此您最终会更改线路数量.

如果你足够幸运,该行总是具有一些识别特征,例如对名称从未改变的变量的赋值,则可以使用正则表达式选择git blame -L.例如:

git blame -L '/variable_name *= */',+1
Run Code Online (Sandbox Code Playgroud)

但是这只能找到该正则表达式的第一个匹配,所以如果你没有一个很好的匹配线的方法,那就不太有用了.

我想你可以破解一些东西.我现在没有时间写出代码,但......就这些问题做了些什么.跑git blame -n -L $n,$n $file.第一场是上一次提交感动,第二场是行号提交,因为它可能已经改变.抓住那些,并运行git blame -n $n,$n $commit^ $file,即从最后一次更改文件之前的提交开始.

(请注意,如果最后一次更改行的提交是合并提交,则会失败.如果在合并冲突解决方案中更改了行,则可能会发生这种情况.)

编辑:我今天在2011年3月发布这个邮件列表帖子,提到了这个帖子tig并且git gui有一个功能可以帮助你做到这一点.看起来git本身已经考虑了这个功能,但还没有完成.


krl*_*mlr 6

这将调用git blame每一个有意义的修订秀行$LINE的文件$FILE:

git log --format=format:%H $FILE | xargs -L 1 git blame $FILE -L $LINE,$LINE
Run Code Online (Sandbox Code Playgroud)

像往常一样,责备显示每行开头的修订号.你可以追加

| sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

获取聚合结果,类似于更改此行的提交列表.(不完全是,如果代码只是被移动了,这可能会为该行的不同内容显示两次相同的提交ID.对于更详细的分析,您必须git blame对相邻提交的结果进行滞后比较.任何人? )


Luc*_*mon 6

这是一个定义git别名的解决方案,因此您可以像这样使用它:

git rblame -M -n -L '/REGEX/,+1' FILE
Run Code Online (Sandbox Code Playgroud)

输出示例:

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
Run Code Online (Sandbox Code Playgroud)

您可以在.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
Run Code Online (Sandbox Code Playgroud)

这是一个丑陋的单行,所以这里是一个去混淆的等效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
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


小智 6

简单易用的 git Blame 命令行开始和结束 (735,750)

L735,750(语法)

git Blame -L735,750病人.php(文件路径和名称)