使用Git查看文件旧版本的方法

使用Git查看文件旧版本的方法

技术背景

在软件开发过程中,我们经常需要查看文件的旧版本,比如排查问题、恢复误删除的代码等。Git作为一款强大的版本控制系统,提供了多种方式来实现这一需求。

实现步骤

使用git show命令

  • 基本语法
1
git show REVISION:path/to/file
BASH

其中,REVISION可以是Git提交的SHA值、标签名、分支名、相对提交名或任何其他能标识提交的方式。

  • 示例:查看4次提交之前的<repository-root>/src/main.c文件版本:
1
git show HEAD~4:src/main.c
BASH

在Windows的Git中,即使是相对于当前目录的路径,也需要使用正斜杠。

根据日期查看

  • 如果提交发生在最近90天内
1
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt
BASH

这里的HEAD@{2013-02-25}表示在该仓库中2013年2月25日时HEAD的位置。

  • 如果提交不在最近90天内
1
git show $(git rev-list -1 --before="2013-02-26" HEAD):./fileInCurrentDirectory.txt
BASH

使用gitk图形界面工具

  1. 启动gitk
1
gitk /path/to/file
BASH
  1. 在屏幕顶部选择所需的版本,可以根据描述或日期进行选择。默认情况下,屏幕底部显示该版本的差异(对应“patch”单选按钮)。
  2. 查看所选版本的文件:
    • 点击“tree”单选按钮,将显示该版本的文件树的根目录。
    • 逐级展开找到所需的文件。

通过commit hash查看

  1. 显示指定文件的所有更改日志:
1
git log /path/to/file
BASH
  1. 在显示的更改列表中,找到commit hash,如commit 06c98...
  2. 复制commit hash
  3. 运行命令:
1
git show <commitHash>:/path/to/file
BASH

注意,指定相对路径时添加./很重要,例如:

1
git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html
BASH

其他方法

导出文件

1
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt
BASH

快速查看文件与旧版本的差异

1
2
3
git show -1 filename.txt  # 与文件的最后一个版本比较
git show -2 filename.txt # 与文件的倒数第二个版本比较
git show -3 fielname.txt # 与文件的倒数第三个版本比较
BASH

使用git log -p查看更改日志和差异

1
git log -p
BASH

然后按/,输入文件名并按enter。按np查看下一个或上一个匹配项。

方法一

  1. 使用git reflog查找提交ID。
  2. 列出提交中的文件:
1
git diff-tree --no-commit-id --name-only -r <commitHash>
BASH

例如:

1
git diff-tree --no-commit-id --name-only -r d2f9ba4
BASH
  1. 打开所需文件:
1
git show <commitHash>:/path/to/file
BASH

例如:

1
git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift
BASH

方法二

注意:此方法可能会丢失未提交的数据,请先提交或保存未提交的文件到暂存区。

  1. 使用git reflog查找提交ID。
  2. 硬重置到该提交:
1
git reset --hard %commit ID%
BASH

例如:

1
git reset --hard c14809fa
BASH
  1. 进行必要的更改并在所需分支上进行新的提交。

方法三(适用于MacOS,TaoGit)

按照特定截图步骤操作后,即使提交的数据在分离头指针的提交中“丢失”,也可以复制所有需要的数据。

导出文件所有版本的脚本

1
git_dump_all_versions_of_a_file.sh path/to/somefile.txt
BASH

可以从这里获取脚本。

从给定版本获取多个文件的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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)
PYTHON

使用方法:

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

在编辑器中打开结果

1
2
3
# 提交引用,如提交ID、分支名、标签等
REVISION='...'
git show "$REVISION":path/to/file | vim -
BASH

在Vim中,可以通过显式设置filetype来解决语法高亮问题:

1
git show "$REVISION":path/to/file.py | vim -c 'set filetype=python' -
BASH

比较两个历史版本的文件

1
vimdiff <(git show "$REV_0":path/to/file) <(git show "$REV_1":another/path/to/file)
BASH

使用GUI方式

1
2
sudo apt install libcgi-pm-perl gamin
git instaweb --httpd=apache2
BASH

apache2替换为你的Web服务器,或者事先安装lighttpd。执行这些命令后,浏览器将打开,可以使用树状结构和差异比较来查看文件。

核心代码

以下是一些核心代码示例:

1
2
3
4
5
6
7
8
9
10
11
# 使用git show查看文件旧版本
git show HEAD~4:src/main.c

# 根据日期查看文件旧版本
git show $(git rev-list -1 --before="2013-02-26" HEAD):./fileInCurrentDirectory.txt

# 导出文件旧版本
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt

# 比较两个历史版本的文件
vimdiff <(git show "$REV_0":path/to/file) <(git show "$REV_1":another/path/to/file)
BASH

最佳实践

  • 在使用git reset --hard之前,务必确保已经备份了未提交的更改,以免数据丢失。
  • 使用脚本导出文件的所有版本时,确保脚本的权限正确,并且脚本所在的目录在系统的PATH中。
  • 在使用图形界面工具时,熟悉工具的操作快捷键可以提高效率。

常见问题

  • git show命令不显示内容:可能是REVISION或文件路径指定错误,检查并确认这些信息是否正确。
  • 在编辑器中打开git show的结果时语法高亮不正常:可以像在Vim中那样,显式设置filetype来解决。
  • 使用git instaweb时浏览器无法打开:检查Web服务器是否正常运行,以及防火墙是否允许访问相关端口。

使用Git查看文件旧版本的方法
https://119291.xyz/posts/git-view-old-file-version-guide/
作者
ww
发布于
2025年5月23日
许可协议