Git责备-先前的提交?


390

是否有可能看到谁在提交报告之前编辑了特定行git blame,例如给定行的提交历史?

例如,我运行以下命令(在一流的uncrustify项目上):

$ git blame -L10,+1 src/options.cpp
^fe25b6d (Ben Gardner 2009-10-17 13:13:55 -0500 10) #include "prototypes.h"

如何确认提交之前谁编辑了该行fe25b6d?又是谁之前编辑它承诺?


7
如果您寻找先前提交的原因是空格更改,请使用该-w选项。还有-M用于移动/复制的代码
brita_ 2014年

要查找涉及给定单词的所有提交,请参见下面的脚本
VonC 2014年


3
不知道@AaronHoffman发布时github是什么样子,但是现在很容易在github中怪罪-并且为以前的版本指责
鲁芬

Answers:


389
git blame -L 10,+1 fe25b6d^ -- src/options.cpp

您可以为git blame指定一个修订版本,以从(而不是默认值HEAD)开始查找;fe25b6d^是的父母fe25b6d


106
您是否可以获得完整的历史记录,而不必使用不同的哈希值多次重新输入命令?
2011年

13
我不认为Git具有内置的方式来获取所有涉及行号的责备(这是有道理的,因为由于插入和删除,给定行在文件的整个历史记录中可能没有一致的行号)行)。
琥珀

17
@Amber:可以肯定地说,该功能不存在,但是确实可以通过简单地做一个人会做的事情就天真地实现:责怪它一次,抓住报告的信息,怪罪于此。 , 等等。
卡斯卡贝尔2011年

15
git gui使得可以轻松查看行的历史记录,因为这些版本是可单击的。
Zitrax 2011年

5
@shadyabhi --通常用作命令行参数中的分隔符-在Git的情况下,通常用于从文件名列表中分离诸如提交哈希之类的东西。
琥珀

191

您可以使用git log -L查看一系列行的演变。

例如 :

git log -L 15,23:filename.txt

表示“跟踪名为filename.txt的文件中第15至23行的演变”。


12
这是一个可靠的答案,解决了安德斯(Anders Zommarin)关于如何查看特定行随时间变化的问题。
bigtex777

4
仅供参考:git log -L <开始>,<结束>:<文件>需要Git 1.8.4+参见:git-scm.com/docs/git-log#git-log--Lltstartgtltendgtltfilegt以获得语法选项
Neon

30

琥珀的答案是正确的,但我不清楚。语法为:

git blame {commit_id} -- {path/to/file}

注意:--用来将树状sha1与相对文件路径分开。1个

例如:

git blame master -- index.html

完全学分制,以琥珀色为了解所有的事情!:)


1
我同意你的观点。但是,评论系统太受限制,无法清晰地呈现所有信息。我已在评论中添加了此答案的内容;不过,我坚持将这个答案留在便于访问的地方。
ThorSummoner 2014年

1
它应该是单独的帖子或编辑内容。我喜欢将此作为单独的答案。
Flimm 2014年

27

您可能要签出:

git gui blame <filename>

为您提供漂亮的图形化显示,例如“ git blame”,但每行具有可单击的链接,以移至较早的提交。将鼠标悬停在链接上可以看到带有提交详细信息的弹出窗口。不是我的积分...在这里找到它:

http://zsoltfabok.com/blog/2012/02/git-blame-line-history/

git gui是git的图形Tcl / Tc界面。没有任何其他参数,它启动了一个非常简单但有用的图形应用程序,用于提交文件,大块甚至单行以及其他类似的命令,例如amend,revert,push ...这是git stock套件的一部分。在Windows上,它包含在安装程序中。在debian上-我对其他* nix系统一无所知-它必须单独安装:

apt-get install git-gui

从文档:

https://git-scm.com/docs/git-gui

描述

Git的基于Tcl / Tk的图形用户界面。git gui专注于允许用户通过提交新提交,修改现有提交,创建分支,执行本地合并以及获取/推送到远程存储库来更改其存储库。

与gitk不同,git gui专注于提交生成和单个文件注释,并且不显示项目历史记录。但是,它确实提供了菜单操作以从git gui中启动gitk会话。

已知git gui可在所有流行的UNIX系统,Mac OS X和Windows(在Cygwin和MSYS下)上工作。在一定程度上遵循了特定于OS的用户界面指南,使git gui成为用户的本机界面。

指令

在给定版本(或工作目录,如果未指定)上的指定文件上启动blame查看器。

浏览器

启动一个树形浏览器,显示指定提交中的所有文件。通过浏览器选择的文件在非常规查看器中打开。

citool

启动git gui并安排在退出并返回shell之前进行一次完全提交。该界面仅限于提交操作,从而略微减少了应用程序的启动时间并简化了菜单栏。

显示当前正在运行的git gui版本。


它对我不起作用。我可以单击给定行上的更改,但这只是将视图更改为该提交,并且当前行现在显示为this:但是我如何查看该行的先前版本以及何时添加?
BeeOnRope

我知道这是一个用例,其中git gui是最好的解决方案
宏伟的

17

在以前的答案的基础上,这款bash单线衬垫应为您提供所需的东西。它显示最近5次修订的特定文件特定行的git blame历史记录:

LINE=10 FILE=src/options.cpp REVS=5; for commit in $(git rev-list -n $REVS HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done

在此命令的输出中,对于特定的提交,您可能会看到行的内容更改,或者显示的行号甚至可能更改。

这通常表明该行是在该特定提交之后第一次添加的。这也可能表明该行已从文件的另一部分移出。


5
请注意,这是最后一次$ FILE更改的$ REVS版本,而不是最后一次$ LINE更改的$ REVS版本。
Max Nanasy

您指的是哪个答案?
Flimm 2014年

我不记得了。可能我可以更好地验证未来。
Will Sheppard 2014年


11

一个非常独特的解决方案是使用git log:

git log -p -M-跟随--stat-路径/到/你/文件

正如安德烈解释这里


1
我创建了一个别名来使用它:git config --global alias.changes 'log -p -M --follow --stat --'然后我可以简单地键入git changes path/to/your/file
Tizio Fittizio

到目前为止,这是最好的答案,而这正是我想要的。简洁大方。
马斯克

10

如果您正在使用JetBrains Idea IDE(及其衍生产品),则可以选择几行,右键单击上下文菜单,然后单击Git->显示历史记录以进行选择。您将看到影响所选行的提交列表:

在此处输入图片说明


对于我来说,这比其他答案更好(使用IntelliJ)。花了一些时间来加载所有修订,但值得等待。
史蒂夫·钱伯斯

1

在Will Shepard的答案的基础上,他的输出将包含没有更改的提交的重复行,因此您可以按以下方式过滤它们(使用此答案

LINE=1 FILE=a; for commit in $(git rev-list HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

请注意,我删除了REVS参数,这可以追溯到root提交。这是由于Max Nanasy的上述观察。


1

基于DavidN的答案,我想遵循重命名的文件:

LINE=8 FILE=Info.plist; for commit in $(git log --format='%h%%' --name-only --follow -- $FILE | xargs echo | perl -pe 's/\%\s/,/g'); do hash=$(echo $commit | cut -f1 -d ','); fileMayRenamed=$(echo $commit | cut -f2 -d ','); git blame -n -L$LINE,+1 $hash -- $fileMayRenamed; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

参考:在git日志中很好地显示文件重命名历史记录


1

从Git 2.23开始,您可以使用git blame --ignore-rev

对于问题中给出的示例,这将是:

git blame -L10,+1 src/options.cpp --ignore-rev fe25b6d

(但是这是一个棘手的问题,因为fe25b6d是文件的第一个修订版!)


0

我使用这个小bash脚本来查看怪历史。

第一个参数:要查看的文件

后续参数:传递给git blame

#!/bin/bash
f=$1
shift
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    echo "--- $hash"
    git blame $@ $hash -- "$f" | sed 's/^/  /'
  done
}

您可以提供-L 70,+ 10之类的怪参数但是最好使用git blame的正则表达式搜索,因为行号通常会随着时间而“变化”。


0

基于stangls答案,我将此脚本以git-bh的形式放在PATH(甚至在Windows中)中:

这使我可以查找涉及单词的所有提交:

git bh path/to/myfile myWord

脚本:

#!/bin/bash
f=$1
shift
csha=""
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    res=$(git blame -L"/$1/",+1 $hash -- "$f" 2>/dev/null | sed 's/^/  /')
    sha=${res%% (*}
    if [[ "${res}" != "" && "${csha}" != "${sha}" ]]; then
      echo "--- ${hash}"
      echo "${res}"
      csha="${sha}"
    fi
  done
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.