使用Git版本查看文件的更改历史记录


3088

如何在Git中查看单个文件的更改历史记录以及更改后的完整详细信息?

我到目前为止:

git log -- [filename]

它向我显示了文件的提交历史记录,但是如何获得每个文件更改的内容?

我正在尝试从MS SourceSafe进行过渡,该过渡曾经是一个简单的right-clickshow history


41
上面的链接不再有效。该链接今天有效:Git社区书
克里斯,2010年

1
上面的链接(由Chris发布)不再有效。该链接今天有效:git-scm.com/book/en/v2
Cog

Answers:


2370

为此,我将使用:

gitk [filename]

或跟随文件名重命名

gitk --follow [filename]

28
但是我什至有一个工具将上述内容与“ git blame”结合在一起,使我可以浏览文件的源代码,因为它随时间变化了……
Egon Willighagen 2010年

26
不幸的是,这并没有遵循重命名文件的历史记录。
Dan Molding

146
我也在寻找以前重命名并首先找到该线程的文件的历史记录。解决方案是使用Phil 此处指出的“ git log --follow <文件名>” 。
Florian Gutmann

115
作者正在寻找命令行工具。gitk随GIT一起提供,它既不是命令行应用程序也不是特别好的GUI。
mikemaccana 2011年

72
他在寻找命令行工具吗?“右键单击->显示历史记录”当然并不意味着它。
hdgarrood

2234

您可以使用

git log -p filename

让git为每个日志条目生成补丁。

看到

git help log

更多选项-它实际上可以做很多事情:)要获得特定提交的差异,您可以

git show HEAD 

或任何其他按标识符的修订。或使用

gitk

直观地浏览更改。


8
git show HEAD显示所有文件,您是否知道如何跟踪单个文件(如Richard所要求的那样)?
乔纳斯·拜斯特伦(JonasByström)2011年

5
您使用:git show <版本>-文件名,如果存在版本号,它将显示该版本的差异。
马科斯·奥利维拉

4
--stat也有帮助。您可以将它与-p一起使用。
拉菲·哈查杜安

5
这很棒。gitk在指定不再存在的路径时表现不佳。我使用了git log -p-path。
Paulo Casaretto

6
加上gitk看起来是由布吉怪物(boogie monster)建造的。这是一个很好的答案,最适合原始问题。
ghayes

1494

git log --follow -p -- path-to-file

这将显示文件的整个历史记录(包括重命名后的历史记录以及每个更改的差异)。

换句话说,如果命名的文件bar曾经被命名为foo,则git log -p bar(不带--follow选项)将仅显示文件的历史记录,直到文件重命名为止-当文件名为时,它不会显示文件的历史记录foo。使用git log --follow -p bar将显示文件的整个历史记录,包括文件时的任何更改foo。该-p选项确保每个更改都包含差异。


18
--stat也有帮助。您可以将它与-p一起使用。
拉菲·哈查杜安

23
我同意这是真正的答案。(1.)--follow确保您看到文件重命名(2.)-p确保您看到文件如何更改(3.)仅命令行。
Trevor Boyd Smith

3
@NHDaly我注意到--已添加,但我不知道为什么这样做会更好?它是做什么的?
约翰·

40
@Benjohn该--选项告诉Git它已经到达选项的末尾,其后的所有内容--都应视为参数。因为git log只有路径名称以破折号开头,这才有意义。假设您想知道一个文件名称为“ --follow”的文件的历史记录:git log --follow -p -- --follow
Dan Molding

10
@Benjohn:通常,此命令--很有用,因为它还可以防止与revision您输入的文件名匹配的任何名称,这实际上可能很吓人。例如:如果您同时有一个分支和一个名为的文件foogit log -p foo则将显示git日志的历史记录foo,而不是该文件 的历史记录foo。但是@DanMoulding是正确的,因为该--follow命令仅将单个文件名作为其参数,所以它的必要性较小,因为它不能为revision。我才知道 也许您是正确的,然后将其排除在答案之外;我不确定。
NHDaly

172

如果您希望保留基于文本的内容,则可能要使用tig

快速安装:

  • apt-get# apt-get install tig
  • 自制软件(OS X)$ brew install tig

使用它来查看单个文件的历史记录:tig [filename]
或浏览详细的回购历史记录:tig

类似于gitk但基于文本。支持终端中的颜色!


23
出色的基于文本的工具,很好的答案。当我看到无头服务器上安装gitk的依赖项时,我吓坏了。会再次投票A +++
汤姆·麦肯齐

您也可以使用tig查看特定文件,即 tig -- path/to/specific/file
tig

109

git whatchanged -p filenamegit log -p filename在这种情况下也等效。

您还可以查看何时使用更改了文件中的特定代码行git blame filename。这将为文件中的每一行打印出简短的提交ID,作者,时间戳和完整的代码行。当您发现一个错误并想知道它何时被引入(或它是谁的错)之后,这非常有用。


4
+1,但filename在command中不是可选的git blame filename
rockXrock

7
“鼓励新用户改用git-log。(...)保留该命令主要是出于历史原因;”
ciastek

104

SourceTree用户

如果您使用SourceTree可视化您的存储库(它是免费的,还算不错),您可以右键单击一个文件并选择Log Selected

在此处输入图片说明

下方的显示比gitk和列出的大多数其他选项友好得多。不幸的是(目前),没有一种简单的方法可以从命令行启动此视图-SourceTree的CLI当前仅打开存储库。

在此处输入图片说明


1
我特别喜欢“跟随重命名的文件”选项,该选项使您可以查看文件是否被重命名或移动。
克里斯(Chris

但是除非我弄错了(请让我知道!),一个人一次只能在GUI中比较两个版本?是否有一个客户端具有优雅的界面,可以一次比较多个不同版本?可能具有Sublime Text中的缩小视图?我认为那将非常有用。
山姆·莱沃伦

@SamLewallen如果我理解正确,那么您想比较三个不同的提交吗?这听起来类似于三向合并(我的,您的,基本的),通常此策略用于解决合并冲突,而不必比较三个任意提交。有很多工具支持三种方式的合并stackoverflow.com/questions/10998728/…但诀窍在于为这些工具提供了特定的修订版gitready.com/intermediate/2009/02/27/…–
Mark Fox

谢谢马克·福克斯,这就是我的意思。您是否知道会执行此操作的任何应用程序?
山姆·莱沃伦

1
@ MarnenLaibow-Koser我不记得当时为什么需要SHA。啊哈哈
AechoLiu

63

要显示什么版本和作者最后修改了文件的每一行:

git blame filename

或者,如果您要使用功能强大的怪怪GUI:

git gui blame filename

49

阅读并玩一些后的其他答案的摘要:

通常的命令行命令是

git log --follow --all -p dir/file.c

但是,您也可以使用gitk(gui)或tig(text-ui)来提供更多人类可读的查看方式。

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

在debian / ubuntu下,这些可爱工具的安装命令符合预期:

sudo apt-get install gitk tig

我目前正在使用:

alias gdf='gitk --follow --all -p'

这样我就可以键入gdf dir以获取子目录中所有内容的集中历史记录dir


2
我认为这是一个很好的答案。也许您还没有获得投票,因为您回答了其他方法(恕我直言更好)以查看更改,即通过gitk和tig以及除git外。
PopcornKing

只是为了补充答案。找到路径(在git空间中,直到存储库中仍存在该路径)。然后使用上述命令“ git log --follow --all -p <folder_path / file_path>”。在某些情况下,filde / folder可能会在历史记录中被删除,因此找到仍然存在的最大路径,并尝试获取其历史记录。工程!
parasrish

2
--all适用于所有分支机构,其余部分在
@Dan

1
哦,老兄,经过了很长一段时间,一直在寻找一种很好的解决方案来跟踪重命名以外的文件,最后,我在这里找到了它。像魅力一样工作!谢谢!
xZero

25

将此别名添加到您的.gitconfig中:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

并使用如下命令:

> git lg
> git lg -- filename

输出看起来几乎与gitk输出相同。请享用。


在运行lg快捷方式后,我说(并引用)“ Beautiful!”。但是,请注意,“-graph”之后的“ \ n”是错误的。
jmbeck

3
也可以使用git lg -p filename-它返回搜索文件的漂亮差异。
埃格尔2015年

22

最近我发现 tig它非常有用。在某些情况下,我希望它可以执行A或B操作,但大多数情况下它都比较整洁。

对于您的情况,tig <filename>可能就是您想要的。

http://jonas.nitro.dk/tig/


在centos yum上安装
tig

17

您可以将vscode与GitLens一起使用,这是一个非常强大的工具。安装GitLens后,转到GitLens选项卡,选择FILE HISTORY即可浏览。

在此处输入图片说明


15

我写git-playback就是为了这个目的

pip install git-playback
git playback [filename]

这样的好处是既可以在命令行中显示结果(如git log -p),又可以让您使用箭头键(如gitk)逐步完成每个提交。




9

您也可以尝试使用它列出更改了文件特定部分的提交(在Git 1.8.4中实现)。

返回的结果将是修改此特定部分的提交列表。命令:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

其中upperLimit是文件的起始行号,lowerLimit是文件的结束行号。

有关更多详细信息,访问https://www.techpurohit.com/list-some-useful-git-commands


7

使用出色的Git扩展程序,您可以转到历史记录中文件仍然存在的位置(如果已删除,否则转到HEAD),切换到File tree选项卡,右键单击文件并选择File history

默认情况下,它通过重命名跟随文件,并且Blame选项卡允许查看给定修订版本的名称。

它有一些小问题,例如单击删除修订时显示fatal: Not a valid object nameView选项卡中,但我可以接受。:-)


值得注意的是,这仅适用于Windows。
埃文·哈恩

3
@EvanHahn不准确,通过单声道可以在Linux上也使用GitExtension,我们在ubuntu上使用它,并且很高兴。参见git-extensions-documentation.readthedocs.org/en/latest/…–
Shmil The Cat,

7

如果您使用“存储库”菜单下的git GUI(在Windows上),则可以使用“可视化母版的历史记录”。在顶部窗格中突出显示一个提交,在右下角突出显示一个文件,您将在左下角看到该提交的差异。


这如何回答这个问题?
jmbeck

3
嗯,OP没有指定命令行,而是从SourceSafe(这是一个GUI)转移过来,指出您可以执行与Windows上的Git GUI中的VSS几乎相同的操作似乎很相关。
cori


4

我一直在寻找的答案不在此线程中,是为了查看我准备提交的文件中的更改。即

git diff --cached

1
如果您想包含本地(未暂存的)更改,我经常会运行git diff origin/master以展示您的本地分支和master分支之间的完整差异(可以通过远程更新git fetch
ghayes 2013年

4

如果您使用TortoiseGit,则应该可以右键单击该文件并执行TortoiseGit --> Show Log。在弹出的窗口中,确保:

  • ' Show Whole Project'选项未选中。

  • ' All Branches'选项被选中。


TortoiseGit(以及Eclipse Git)以某种方式错过了所选文件的修订版,请不要指望它!
Noam Manos 2015年

@NoamManos,我还没有遇到这个问题,所以我无法验证您的说法是否正确。
user3885927

我的错误,它仅在Eclipse中发生,但是在TortoiseGit中,如果取消选中“显示所有项目” +“所有分支”(如果文件在合并到主目录之前已提交到另一个分支,则可以看到文件的所有修订版)科)。我会更新您的答案。
Noam Manos 2015年


2

如果您将eclipse与git插件配合使用,则它具有与历史记录的出色对比视图。右键单击该文件,然后选择“与...比较” =>“历史记录”


但是,这将不允许您查找已删除的文件。
avgvstvs 2013年

一个文件的两个版本相比较是查看文件的变化历史的不同
golimar

0

我可能是关于OP何时开始的地方,正在寻找一个简单的方法,使我可以将git difftoolvimdiff一起使用,以从特定的提交开始查看仓库中文件的更改。我对找到的答案不太满意,所以我把这个git inc remental rep orter(gitincrep)脚本放在一起,对我很有用:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

调用时不带参数,这将从回购历史记录的开头开始,否则将从您提供的任何缩写提交哈希开始,一直到现在-您可以随时按ctrl-C退出。第一个参数之后的任何参数都将限制差异报告,使其仅包括这些参数中列出的文件(我认为这是OP想要的,我建议所有小项目除外)。如果要检查对特定文件的更改希望从头开始,则需要为arg1提供一个空字符串。如果您不是vim用户,则可以用自己喜欢的diff工具替换vimdiff

行为是在找到相关更改后输出提交注释,并开始为每个更改的文件提供vimdiff运行(即git difftool行为,但在这里有效)。

这种方法可能很幼稚,但是在这里和相关的文章中浏览了很多解决方案,其中许多涉及在我没有管理员访问权限的系统上安装新工具,并且界面具有自己的学习曲线。上面的脚本完成了我想要的操作,而没有任何处理。当我需要更复杂的内容时,我将在这里研究许多出色的建议-但我认为这直接响应OP。


0

我找到了一种非常简单的解决方案,可以快速找到文件的历史记录。

  1. 对文件进行随机更改
  2. 它会在您的源代码树上显示为未提交的更改
  3. 右键单击该文件,然后选择“选择日志”

在此处输入图片说明

它将显示所有提交的历史记录。


该GUI来自何处?
colidyre

Sourcetree UI。谢谢
savvyBrar
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.