是否有快速的Git命令来查看文件的旧版本?


1509

Git中是否有命令可以查看(转储到stdout或in $PAGER或中$EDITOR)特定文件的特定版本?



如果由于要检查二进制文件的较旧版本(例如图像)而遇到此问题,则最好对旧提交进行检出,查看需要查看的内容,然后返回HEAD。为此,请git checkout <sha1-of-the-commit-you-need>稍后执行git checkout HEAD
Homero Esmeraldo

Answers:


1730

您可以使用git show来自存储库根目录的路径(./../用于相对路径):

$ git show REVISION:path/to/file

替换REVISION为您的实际修订版(可以是Git提交SHA,标签名称,分支名称,相对提交名称,或在Git中标识提交的任何其他方式)

例如,要查看<repository-root>/src/main.c4次提交之前的文件版本,请使用:

$ git show HEAD~4:src/main.c

Git for Windows 即使在相对于当前目录的路径中也需要正斜杠。有关更多信息,请参见的手册页git-show


5
这实际上似乎不起作用-您是否尝试过?对于“ git show HEAD:path / to / file.c”,我收到“模棱两可的参数”错误。
Mike

2
必须是完整的路径,从git仓库的顶部
richq

20
如果您在Windows上,则可能是路径分隔符。如果我执行git show HEAD:dir \ subdir \ file,则会得到模棱两可的参数。如果我执行git show HEAD:dir / subdir / file,它会按预期工作。
马特·麦克明

12
在:之后必须提供的路径来自git仓库的根目录。(这是在下面给出的答案,但我认为它旨在对此答案进行评论)
MatrixFrog 2011年

9
如果您想在Vim拆分中看到它以便它们一起滚动,我写了一篇简短的博客文章来说明如何做到这一点。
Flaviu

257

按日期执行如下操作:

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt

请注意,这HEAD@{2013-02-25}表示此存储库中的“ HEAD位于2013-02-25上”(使用reflog),而不是“历史记录中此分支中2013-02-25之前的最后一次提交”。


5
太棒了 节省了我的时间,而不是去github查看提交。
费扎尔汗2014年

文件路径上的“点”是我的问题。谢谢!
tomascharad

5
如果您在分支上,则此命令对于master而不是很有用HEAD@{2013-02-25}
funroll 2015年

1
您可以输入时间git log --since='2016-04-28 23:59:59 +0100'吗?
dumbledad '16

7
此语法使用reflog的事实很重要,因此应特别强调,因为reflog并不包含所有commit。参见blog.endpoint.com/2014/05/git-checkout-at-specific-date.html
爱丽丝·希顿

113

如果您喜欢GUI,则可以使用gitk:

  1. 用以下命令启动gitk:

    gitk /path/to/file
    
  2. 在屏幕顶部选择修订版本,例如按描述或日期。默认情况下,屏幕下部显示该版本的差异(对应于“补丁”单选按钮)。

  3. 要查看所选版本的文件:

    • 单击“树”单选按钮。这将显示该修订版中文件树的根。
    • 深入到您的文件。

7
这也适用于tig(这是curses git repo查看器)。
马修·G

1
@Paul Slocum:可能是因为此命令不是常规命令,而不是git的内置命令。我认为该命令仅适用于Windows。
Envil 2013年

请注意,这仅在您从git存储库的根目录开始时才起作用。
Marc

如果您想使用gitk检查某个版本,则也可以使用以下快捷方式:gitk REVISION /path/to/file。例如,当您要检查某个版本时,这会派上用场。
Christian.D

89

您还可以使用命令指定commit hash(通常也称为commit ID)。git show


简而言之

git show <commitHash>:/path/to/file


一步步

  1. 显示给定文件的所有更改的日志 git log /path/to/file
  2. 在显示的更改列表中,它显示commit hash诸如commit 06c98...(06c98 ...是提交哈希)
  3. 复制 commit hash
  4. git show <commitHash>:/path/to/file使用commit hash第3步和path/to/file第1 步运行命令。

注意:./在指定相对路径时添加似乎很重要,即git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html


1
如果您不知道文件路径,请使用git show <SHA1> --name-only它来获取。
蒂娜

此命令op-甚至从内存自动完成-在已删除的目录上进行测试... gg不能获得更多的op
treyBake


23

要快速查看与旧版本文件的区别,请执行以下操作:

git show -1 filename.txt >与文件的最新版本进行比较

git show -2 filename.txt >与第二个修订版进行比较

git show -3 fielname.txt >与最新的第三修订版进行比较


18
这些命令为我显示了与当前版本的差异,但没有显示整个文件。
Jean Paul

18

git log -p不仅会显示提交日志,还会显示每个提交的差异(合并提交除外)。然后,您可以按/,输入文件名,然后按enter。按np转到下一个/上一个事件。这样,您不仅会看到文件中的更改,而且还会看到提交信息。


3
看起来git log -pm还会显示合并提交。
桑博

2
您还可以运行git log -p -- filename.txt以将历史记录限制为仅所需的文件。
让·保罗

3

您可以使用如下脚本将文件的所有版本转储到单独的文件中:

例如

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

此处获取脚本作为对另一个类似问题的解答


1
git_rootgit_log_short并且git_log_message_for_commit丢失。
mogsie

接得好!我把这个答案加倍地贴到了两个不同的地方,只是将其删除并链接到另一个地方,在此之前人们告诉过我这个问题……谢谢@mogsie!
布莱德·帕克斯

这个脚本非常有用!
XMAN

3

方式1 :( 我更喜欢这样)

  1. 查找提交IDgit reflog
  2. 列出提交中的文件 git diff-tree --no-commit-id --name-only -r <commitHash>

示例:git diff-tree --no-commit-id --name-only -r d2f9ba4//“ d2f9ba4”是来自“ 1”的提交ID。

  1. 使用命令打开所需的文件:

git show <commitHash>:/path/to/file

例如:git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift//“ Src / ...”是“ 2”的文件路径。

方式2:

  1. 查找提交IDgit reflog
  2. 硬重置为此提交: git reset --hard %commit ID%

git reset --hard c14809fa

  1. 进行任何不必要的更改,然后对所需的分支进行新的提交:)

0

帮手从给定的版本中获取多个文件

尝试解决合并冲突时,此帮助程序非常有用:

#!/usr/bin/env python3

import argparse
import os
import subprocess

parser = argparse.ArgumentParser()
parser.add_argument('revision')
parser.add_argument('files', nargs='+')
args = parser.parse_args()
toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).rstrip().decode()
for path in args.files:
    file_relative = os.path.relpath(os.path.abspath(path), toplevel)
    base, ext = os.path.splitext(path)
    new_path = base + '.old' + ext
    with open(new_path, 'w') as f:
        subprocess.call(['git', 'show', '{}:./{}'.format(args.revision, path)], stdout=f)

GitHub上游

用法:

git-show-save other-branch file1.c path/to/file2.cpp

结果:以下内容包含文件的备用版本:

file1.old.c
path/to/file2.old.cpp

这样,您可以保留文件扩展名,这样编辑人员就不会抱怨,并且可以轻松地在较新的文件旁边找到旧文件。


@MickeyPerlstein如果您可以通过更好的实现来实现相同的界面,我将不知所措。
西罗桑蒂利冠状病毒审查六四事件法轮功

也许我不明白(如果可以的话,我很抱歉),但这不只是:“ git show version:./ path> new_path”吗?
米奇·佩尔斯坦

@MickeyPerlstein嗨,是的,我的命令生成了该CLI,但是它会循环多个文件并从输入中生成输出名称,因此您不必键入太多内容。当然没有什么革命性的,但是很方便。
西罗桑蒂利冠状病毒审查六四事件法轮功
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.