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


3088

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

我到目前为止:

git log -- [filename]

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

我正在尝试从MS SourceSafe进行过渡,该过渡曾经是一个简单的right-click→ show 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您输入的文件名匹配的任何名称,这实际上可能很吓人。例如:如果您同时有一个分支和一个名为的文件foo,git 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 name在View选项卡中,但我可以接受。:-)


值得注意的是,这仅适用于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 difftool与vimdiff一起使用,以从特定的提交开始查看仓库中文件的更改。我对找到的答案不太满意,所以我把这个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.