diffnav:给 git diff 加上 GitHub 风格文件树的终端分页器

Git
终端
开源
Go
开发者工具
2026/10/19
·

阅读时间: 大约 13 分钟

diffnav:给 git diff 加上 GitHub 风格文件树的终端分页器

diffnav 运行界面:左侧 GitHub 风格文件树定位到 tasks/pr.go,右侧 delta 风格并排 diff(绿增棕删)

在终端里审阅一次改动几十个文件的 PR,git diff 原始输出是一长条没有结构的文本流:你知道改了很多文件,却不知道自己现在漂在哪一个文件、还有几个文件没看。diffnav 就是为解决这个”迷失”而生的:它是一个基于 delta的 git diff 分页器,额外加了一个 GitHub 风格的侧边文件树,作者是此前做过终端 PR 面板 gh-dash的 dlvhdr。本文基于官方 README 与 GitHub 仓库元数据(截至 2026-10-19)做一手梳理。

一、背景动机:命令行 review 的结构缺失

GitHub 网页端的 PR 视图天然带文件列表:左侧树状导航、右侧代码、顶部显示”已看/未看”。回到终端,git diff 把所有文件拼接成一个连续滚动流,delta 解决了语法高亮与并排显示,却没有解决”全局导航”——文件多了之后,你只能靠 / 搜索文件名或反复翻页。diffnav 的定位很窄:不重做 diff 引擎,只在 delta 外面套一层带文件树的 TUI,把网页端的导航结构搬回终端。

二、是什么:delta 渲染 + Bubble Tea 外壳

官方描述原话:“A git diff pager based on delta but with a file tree, à la GitHub.” 仓库为 Go 编写、MIT 协议,2024-09-18 创建,最新发布 v0.13.0(2026-10-06),截至调研时约 1,594 stars、66 forks,主分支 2026-10-18 仍有提交。

技术栈(README “Under the Hood”):

  • Bubble Tea:Elm 架构的 Go TUI 框架,负责界面与键盘事件;
  • Bubbletint:主题着色;
  • delta:实际负责文件内容的 diff 渲染(语法高亮、并排/统一视图)。

也就是说,diffnav 自身不实现 diff 算法,而是消费上游 diff 文本、用 delta 画内容、自己画树与导航。

三、使用方式与机制

3.1 接入

三种典型用法:

# 直接管道
git diff | diffnav
gh pr diff https://github.com/dlvhdr/gh-dash/pull/447 | diffnav

# 设为全局 git diff 分页器
git config --global pager.diff diffnav

# 作为 gh 的分页器
GH_PAGER=diffnav gh pr diff <url> --color=never

安装支持 Homebrew(brew install diffnav)或 go install .。README 提示:要让图标正常渲染,需安装 Nerd Font并设为终端字体;不装也能用,可切到 unicode/ascii 图标风格。

3.2 视图与快捷键

界面分两栏:左侧文件树(可折叠目录、按 git 状态着色、显示增删行数),右侧 delta 渲染的当前文件 diff,Tab 在两栏间切换焦点。核心按键:

按键功能
j / k下一个 / 上一个树节点
n / p(或 N)下一个 / 上一个文件
e折叠/展开文件树
t搜索并跳转到文件
s切换并排 / 统一 diff 视图
Ctrl-d / Ctrl-udiff 区半页下/上滚
Ctrl-e / Ctrl-ydiff 区单行下/上滚
y复制当前文件路径
o在 $EDITOR 中打开文件
i循环切换图标风格
T打开主题选择器
q退出

3.3 Watch 模式

--watch(-w)周期性重跑一条命令并刷新界面,默认命令是 git diff、间隔 2s:

diffnav --watch                                  # 监视未暂存改动,每 2s 刷新
diffnav --watch-cmd "git diff --cached" --watch-interval 5s
diffnav --watch-cmd "git diff main..."

适合边改边看未暂存差异的场景。

3.4 配置

配置文件按顺序查找:$DIFFNAV_CONFIG_DIR/config.yml → $XDG_CONFIG_HOME/diffnav/config.yml(仅 macOS)→ ~/.config/diffnav/config.yml(macOS/Linux)→ 系统目录。常用项:showFileTree(启动是否显示树,默认 true)、fileTreeWidth(默认 26)、searchTreeWidth(默认 50)、sideBySide(默认 true)、showDiffStats(文件名旁显示增删行数,默认 true)、colorFileNames(按状态着色,默认 true)、theme(默认 tokyo_night,T 键可预览切换)、startFoldersOpenDepth(启动展开层级,-1 全展开)。

图标风格六档:nerd-fonts-status(默认,带状态色块)、nerd-fonts-simple、nerd-fonts-filetype(语言图标)、nerd-fonts-full(状态+语言)、unicode(+/⛌/●)、ascii(+/x/*)。

diffnav 并排视图滚动:左侧未读树节点,右侧 delta 高亮新增(绿)与删除(棕)

四、关键事实表(均来自官方 README / 仓库 API)

项目官方数值/表述
仓库 / 语言 / 协议dlvhdr/diffnav,Go,MIT
创建时间2024-09-18
最新发布v0.13.0(2026-10-06)
Star / Fork(调研时 API)约 1,594 / 66
diff 渲染引擎delta
TUI 框架 / 主题Bubble Tea / Bubbletint
Watch 默认间隔2s
文件树默认宽度 / 搜索面板宽度26 / 50
默认主题 / 默认视图tokyo_night / 并排(side-by-side)
图标依赖Nerd Font(可降级 unicode/ascii)

五、评测方法与口径说明

本文没有独立跑分:diffnav 是导航型查看器,没有延迟、内存等公开基准,README 也未提供性能数字。上表 star/fork 为 GitHub API 调研当日快照,会随时间变化;版本号以 GitHub Releases 为准。界面截图来自仓库自带演示动画(out.gif)抽帧,终端为 kitty、配色 tokyonight、字体 CommitMono,属官方展示环境,不代表默认终端效果。

六、适用 / 不适用场景

适合:

  • 一次 PR 改动文件多(十几个以上),需要在文件间快速跳转、确认进度的终端重度用户;
  • 已经在用 delta、喜欢并排视图,只缺一个文件树的人;
  • 边写边用 --watch 监视未暂存改动的小步迭代;
  • gh-dash 用户,同作者的交互习惯可以平移。

不适合:

  • 需要在终端里直接编辑、接受 chunk 的人(diffnav 是 pager,不是 patch 工具);
  • 文件改动只有两三个、git diff 一眼看完的小提交(树是负担);
  • 无法安装 Nerd Font 又拒绝 unicode/ascii 降级的环境。

七、客观分析:优势与局限

优势:

  1. 职责单一、组合友好:不重造 diff 引擎,复用 delta,以管道/pager 方式接入现有 git 工作流,pager.diff 一行配置全局生效;
  2. 导航闭环:树跳转、文件搜索(t)、路径复制(y)、编辑器打开(o)覆盖了 review 的主要动作;
  3. 可配置度高:树宽、面板宽、图标六档、多主题、启动展开深度都可调;
  4. 作者延续 gh-dash 的 TUI 经验,Bubble Tea 生态下交互一致性较好。

局限(含官方/事实边界):

  1. 只是查看器:不能 stage/unstage、不能编辑补丁,审阅后的动作仍要回到 git 命令;
  2. 图标强依赖 Nerd Font:不装字体时 nerd-fonts 系列图标会退化为乱码方块,需手动切 unicode/ascii;
  3. 单维护者、项目年轻:2024 年中才创建,配置路径在 macOS/Linux 间有差异,生态(如 Vim/Emacs 集成)未覆盖;
  4. Watch 模式为轮询刷新:固定间隔重跑命令,大 diff 下刷新成本需自行观察,README 未给出性能上限;
  5. 无并行 review/评论能力:相比 gh-dash 的 PR 管理,diffnav 只做本地 diff 浏览。

八、它意味着什么 / 谁该关注

diffnav 代表了一类”给成熟工具补一块缺失拼图”的终端小工具路线:delta 已经把 diff 渲染做到位,缺的只是全局结构,于是用 TUI 壳把文件树补上。对终端派开发者,它是 GitHub PR 文件列表的平价替代;对工具作者,它示范了如何不重复造轮子、只在管道接口处增值。值得每个在终端里 review 大型 diff 的人试一次,但不要期待它替代完整的 PR 客户端。

参考来源