ChatGPT解决这个技术问题 Extra ChatGPT

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

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

git log -- [filename] 向我显示文件的提交历史记录,但如何查看更改的文件内容?

上面的链接(由 Chris 发布)不再有效。此链接今天有效:git-scm.com/book/en/v2
@chris:你说的链接是什么?在一些现已删除的评论中?

M
Mateen Ulhaq

这让 Git 可以为每个日志条目生成补丁:

git log -p -- filename

有关更多选项,请参阅 git help log — 它实际上可以做很多好事。 :)

要获取特定提交的差异,请使用

git show HEAD

或通过标识符指定任何其他修订。

要直观地浏览更改:

gitk

git show HEAD 显示所有文件,你知道如何跟踪单个文件(正如 Richard 所要求的)吗?
您使用: git show -- 文件名,它将显示该版本的差异,以防万一。
--stat 也很有帮助。您可以将它与 -p 一起使用。
这很棒。 gitk 在指定不再存在的路径时表现不佳。我使用了 git log -p --path 。
加上 gitk 看起来像是由布吉怪物建造的。这是一个很好的答案,最适合原始问题。
M
Mateen Ulhaq

对于图形视图,请使用 gitk

gitk [filename]

要跨文件重命名跟踪文件:

gitk --follow [filename]

但我什至有一个将上述内容与“git blame”相结合的工具,让我可以浏览文件的源代码,因为它会随着时间的推移而改变......
不幸的是,这不遵循文件过去重命名的历史。
我也在寻找以前重命名的文件的历史记录,并首先找到了这个线程。解决方案是使用“git log --follow <filename>”正如菲尔指出的here
作者正在寻找一个命令行工具。虽然 gitk 与 GIT 一起提供,但它既不是命令行应用程序,也不是特别好的 GUI。
他是在寻找命令行工具吗? “右键单击-> 显示历史记录”当然并不意味着它。
M
Mateen Ulhaq
git log --follow -p -- path-to-file

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

换句话说,如果名为 bar 的文件曾经被命名为 foo,那么 git log -p bar(没有 --follow 选项)将只显示文件的历史记录,直到它被重命名 - 它不会显示文件被称为 foo 时的历史记录。使用 git log --follow -p bar 将显示文件的整个历史记录,包括在文件被称为 foo 时对文件所做的任何更改。 -p 选项确保每次更改都包含差异。


--stat 也很有帮助。您可以将它与 -p 一起使用。
我同意这是真正的答案。 (1.) --follow 确保您看到文件重命名 (2.) -p 确保您看到文件如何更改 (3.) 它只是命令行。
@NHDaly 我注意到添加了 -- ,但我不知道为什么这样做最好?它是做什么的?
@Benjohn -- 选项告诉 Git 它已到达选项的末尾,并且 -- 后面的任何内容都应视为参数。对于 git log,只有当您的路径名以 破折号 开头时,这才有意义。假设您想知道名称为“--follow”的文件的历史记录:git log --follow -p -- --follow
@Benjohn:通常, -- 很有用,因为它还可以防止任何与您输入的文件名匹配的 revision 名称,这实际上可能很可怕。例如:如果您有一个名为 foo 的分支和一个文件,则 git log -p foo 将显示 git log 历史记录到 foo,而不是 file foo 的历史记录。但是@DanMoulding 是正确的,因为 --follow 命令仅将单个文件名作为其参数,因此这不是必需的,因为它不能是 revision。我刚刚学到了。也许您当时将其排除在答案之外是对的;我不确定。
M
Mateen Ulhaq

tig 是基于终端的查看器,其颜色支持类似于基于 GUI 的 gitk

快速安装:

APT:apt-get 安装 tig

Homebrew (OS X): $ brew install tig

使用它来查看单个文件的历史记录:tig [filename]

或通过以下方式浏览详细的存储库历史记录:tig


优秀的基于文本的工具,很好的答案。当我看到在我的无头服务器上安装 gitk 的依赖项时,我吓坏了。会再次投票A +++
您也可以使用 tig 查看特定文件,即 tig -- path/to/specific/file
要显示文件的所有更改,包括重命名,请使用 tig --follow filename。非常感谢@falken 帮助我们发现了如此出色的 TUI 工具。
f
farktronix

在这种情况下,git whatchanged -p filename 也等同于 git log -p filename

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


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

源树用户

如果您使用 Sourcetree 来可视化您的存储库(它是免费的并且非常好),您可以右键单击一个文件并选择 Log Selected

https://i.stack.imgur.com/CHvfE.png

显示(下图)比 gitk 和列出的大多数其他选项更友好。不幸的是(此时)没有简单的方法可以从命令行启动这个视图——Sourcetree 的 CLI 目前只是打开存储库。

https://i.stack.imgur.com/Y9ALz.png


我特别喜欢“关注重命名的文件”选项,它允许您查看文件是否被重命名或移动。
但除非我弄错了(请告诉我!),在 gui 中一次只能比较两个版本?是否有任何客户端具有优雅的界面,可以同时区分多个不同的版本?可能有像 Sublime Text 那样的缩小视图?我认为那将非常有用。
@SamLewallen如果我理解正确,您想比较三个不同的提交?这听起来类似于三向合并(我的、你的、基础的)——通常这种策略用于解决合并冲突,不一定要比较三个任意提交。有许多工具支持三向合并stackoverflow.com/questions/10998728/…,但诀窍是为这些工具提供特定的修订gitready.com/intermediate/2009/02/27/…
你救了我的命。您可以使用 gitk 找到 SHA1 哈希,然后根据找到的 SHA1 打开 SourceTree 输入 Log Selected..
@MarnenLaibow-Koser 我不记得当时为什么需要 SHA。啊哈哈。
C
Colin D Bennett

要显示上次修改文件每一行的版本和作者:

git blame filename

或者如果你想使用强大的责备 GUI:

git gui blame filename

blame 命令不显示有关已删除代码的信息。通过 gitk 或 tig 查看每个提交表明了这一点。
P
Peter Mortensen

阅读并玩了一下其他答案的摘要:

通常的命令行命令是

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

但您也可以使用 gitk (GUI) 或 tig (文本 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 中所有内容的集中历史记录。


我认为这是一个很好的答案。也许您也没有获得投票,因为您回答了其他方式(恕我直言,更好)来查看更改,即除了 git 之外,还通过 gitk 和 tig。
只是为了补充答案。找到路径(在 git 空间中,直到它仍然存在于存储库中)。然后使用上述命令“git log --follow --all -p ”。可能存在这种情况,该文件/文件夹将在历史记录中被删除,因此找到仍然存在的最大路径,并尝试获取其历史记录。有效!
--all 适用于所有分支,其余部分在@Dan 的答案中进行了解释
哦,伙计,经过这么长时间寻找超越重命名跟踪文件的好解决方案,终于,我在这里找到了它。像魅力一样工作!谢谢!
P
Peter Mortensen

您可以将 Visual Studio Code 与 GitLens 一起使用。这是一个非常强大的工具。

安装好 GitLens 后,进入 GitLens 标签页,选择 FILE HISTORY 即可浏览。

https://i.stack.imgur.com/H0j9A.png


P
Palesz

将此别名添加到您的 .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 快捷方式后,我说(我引用)“漂亮!”。但是,请注意“--graph”之后的“\n”是一个错误。
也可以使用 git lg -p filename - 它返回搜索文件的漂亮差异。
l
li ki

最近我发现了 tig,发现它非常有用。在某些情况下,我希望它是 A 或 B,但大多数时候它相当整洁。

对于您的情况,tig <filename> 可能就是您要查找的内容。

https://jonas.github.io/tig/


j
jitendrapurohit

你也可以试试这个,它列出了更改文件特定部分的提交(在 Git 1.8.4 中实现)。

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

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

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

http://techpurohit.in/list-some-useful-git-commands 上有更多详细信息。


链接已损坏 - 域techpurohit.com不再存在。
@PeterMortensen 嗨,该链接已替换为存档链接。
J
Jian

我为此写了 git-playback

pip install git-playback
git playback [filename]

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


G
George Anderson

或者:

gitx -- <path/to/filename>

如果您使用 gitx


出于某种原因,我的 gitx 打开空白。
@IgorGanapolsky,您必须确保您位于 git 存储库的根目录
P
Peter Mortensen

Sourcetree UI 中,您可以通过在右键单击上下文菜单中选择“Log Selected”选项来查找文件的历史记录:

https://i.stack.imgur.com/uxBTn.png

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


这个 GUI 是从哪里来的?
源树用户界面。谢谢
什么是窗户?
@Emobe:你什么意思?你能详细说明吗? (屏幕截图似乎来自 Microsoft Windows。)
A
Adi Shavit

如果您想查看文件的整个历史记录,包括所有其他分支,请使用:

gitk --all <filename>

P
Peter Mortensen

如果您使用的是 Git GUI(在 Windows 上):

在 Repository 菜单下,您可以使用“Visualize master's History”。突出显示顶部窗格中的提交和右下角的文件,您将在左下角看到该提交的差异。


这如何回答这个问题?
好吧,OP 没有指定命令行,并且从 SourceSafe(这是一个 GUI)开始,指出您可以在 Windows 上的 Git GUI 中的 VSS 中执行几乎相同的操作似乎是相关的。
l
li ki

使用出色的 Git Extensions,您可以转到文件仍然存在的历史记录中的某个点(如果它已被删除,否则只需转到 HEAD),切换到 File tree 选项卡,右键单击文件并选择File history

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

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


值得注意的是,这仅适用于 Windows。
@EvanHahn 不准确,通过单声道也可以在 Linux 上使用 GitExtension,我们在 ubuntu 上使用它并且非常满意。见git-extensions-documentation.readthedocs.org/en/latest/…
A
Antonín Slejška

SmartGit

在菜单中启用以显示未更改的文件:查看/显示未更改的文件右键单击文件并选择“日志”或按“Ctrl-L”


N
Noam Manos

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

未选中“显示整个项目”选项。

选中“所有分支”选项。


TortoiseGit(以及 Eclipse Git)不知何故错过了所选文件的修订版,不要指望它!
@NoamManos,我没有遇到过这个问题,所以我无法验证您的陈述是否正确。
我的错误,它只发生在 Eclipse 中,但在 TortoiseGit 中,如果取消选中“显示所有项目”+选中“所有分支”,您可以看到文件的所有修订(如果文件在另一个分支上提交,然后合并到主分支)。我会更新你的答案。
P
Peter Mortensen

我要找的答案不在这里。这是为了查看我为提交暂存的文件中的更改。 IE,

git diff --cached

如果您想包含本地(未暂存的)更改,我经常运行 git diff origin/master 以显示您的本地分支和主分支之间的完全差异(可以通过 git fetch 从远程更新)
L
Lukasz Czerwinski

git diff -U <filename> 为您提供统一的差异。

它应该用红色和绿色着色。如果不是,请先运行:git config color.ui auto


P
Peter Mortensen

如果您将 Eclipse 与 Git 插件一起使用,它具有与历史记录的出色比较视图。右键单击文件并选择“比较”→“历史记录”。


但是,这将不允许您找到已删除的文件。
比较文件的两个版本不同于查看文件的更改历史记录
o
oracleif

我可能是关于 OP 开始时的位置,寻找一些简单的东西,让我可以使用 git difftool 和 vimdiff 来查看从特定提交开始对我的 repo 中文件的更改。我对找到的答案不太满意,所以我把这个 git 增量报告器 (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。