Diffle:支持 LSP 的键盘优先 Git diff 查看器
Show HN: Diffle, a keyboard-centric diff viewer with LSP support
Diffle 是一款键盘优先的 Git diff 查看器,支持在浏览器中审查 diff 并对行、代码块或整个文件添加评论,评论可导出为智能体提示词或 GitHub 待提交审查。它内置 LSP 支持,可为 diff 中每种语言启动语言服务器,实现跳转定义、查找引用和悬停文档。Diffle 可通过 pixi、npm 或独立二进制安装,评论保存在 /diffle/ 目录中,不影响工作区。
在浏览器中审查 Git diff,并对行、块或整个文件发表评论。然后把这些评论作为提示交给 agent,或作为待处理的审查交给 GitHub。
安装
pixi global install diffle # conda-forge npm install -g @moritzwilksch/diffle # npm
或者获取独立二进制文件,它不需要 Node.js。在 Linux(x64、arm64、glibc)和 Apple 芯片 macOS 上:
curl -fsSL https://diffle.app/install.sh | sh它会安装到 ~/.local/bin。设置 DIFFLE_INSTALL_DIR 可以更改该位置,或设置 DIFFLE_VERSION=v0.1.9 来固定某个版本。在 Windows(x64、arm64)上,从 PowerShell 运行:
irm https://diffle.app/install.ps1 | iex
想不安装就试用:
pixi exec diffle working
npx @moritzwilksch/diffle working
nix run github:moritzwilksch/diffle -- workingNix 包捆绑了 gh;#minimal 会去掉它,而 #web、#rust 和 #python 会捆绑语言服务器。
选择要审查的内容
diffle # HEAD vs worktree, like a bare `git diff` diffle working # HEAD vs worktree: staged, unstaged, untracked diffle develop # what this branch added since it left develop diffle pr 27 # GitHub PR 27, or its URL; without a number, this branch's PR diffle show a1b2c3d # one commit, like `git show` diffle main..feat # any git-diff revspec: <rev> | a..b | a...b | a b diffle main..worktree # "worktree" names the uncommitted tree on either side diffle range-diff main..v1 main..v2 # how a series of commits was reworked, like `git range-diff` diffle --help # all commands and flags
diffle pr 需要一个 GitHub token。来自其他仓库的 PR 会在临时克隆中打开。
关闭最后一个 diffle 标签页会停止服务器并打印你未关闭的评论。传入 --keep-alive 可让它保持运行。
审查
j/k:下一行或上一行(10j:向下十行)J/K:下一个或上一个文件]/[:下一个或上一个 hunkc:评论C:对整个文件发表评论V:选择一个块R:解决v:标记为已查看/:搜索当前文件g/:搜索所有已更改的文件gf:筛选文件F:打开完整文件Ctrl+o:返回yy:复制所有评论
按 ? 查看完整列表。
比较会在讨论串上方列出其提交。选择一个提交,或用 < 和 > 逐步切换,即可单独查看该提交;All changes 会返回到整个范围。聚焦提交上的评论属于该提交,就像在 diffle show 中一样。
评论存放在 <git-dir>/diffle/ 中,绝不会触碰你的工作区。它们会随着代码变化跟随其文本,一旦文本离开 diff 就会失效。
生成的文件默认折叠,与 GitHub 上一样:.gitattributes 中的 linguist-generated 会标记它们,而 linguist-generated=false 可让某个文件退出此行为。要折叠其他文件,可在设置中或通过 diffle config 添加自动查看的 glob。
将评论发送到 GitHub
拉取请求图标会将一个讨论串或所有未关闭的讨论串添加到 PR 上的待处理审查中。diffle 从不提交它:你需要在 GitHub 上自行编辑、删除和提交这些评论。再次添加某个讨论串会更新其评论,而不是重复添加。
当比较与 PR 已提交的 diff 匹配时,导出才有效,因此未推送的提交和工作区更改会导致无法导出。失效的讨论串会被跳过。
diffle 会依次从 GITHUB_TOKEN、GH_TOKEN,然后从已登录的 gh 获取 token。没有 token 时,除 GitHub 之外的一切仍然可用。GITHUB_API_URL 可将 diffle 指向另一个 GitHub API,就像在 Actions 中一样。
跳转到定义
diffle 会为 diff 中的每种语言启动一个语言服务器,前提是它在 PATH 上找到了对应的服务器:
gd或 Ctrl/Cmd+点击:定义gy:类型定义gA:引用gs/gS:文件或仓库符号gh:悬停,包括 JSON、YAML 和 TOML 的 schema 文档w/b/0/$:逐行遍历该行的符号;光标或指针下的符号会在文件中每次出现的位置着色,写入与读取区分开
diff 之外的结果(例如标准库)以只读方式打开。大型仓库可能需要一段时间来建立索引。
diffle lsp 会显示每种语言使用哪个服务器,以及其余语言需要安装什么:
python pyrefly lsp
rust not on PATH (tried rust-analyzer)
覆盖某个服务器或将其关闭:
diffle config set-lsp rust "rust-analyzer" # persistent diffle config set-lsp java "" # never start one for java diffle config unset-lsp rust # back to PATH diffle working --lsp python="pyrefly lsp" # this run only diffle working --no-lsp # none at all
语言服务器通过仓库内的 shell 运行,可以读取你的用户能读取的任何内容。--no-lsp 不会启动任何服务器。
Shell 补全
diffle completion --shell bash > ~/.local/share/bash-completion/completions/diffle diffle completion --shell zsh > ~/.local/share/zsh/site-functions/_diffle # on fpath, before compinit diffle completion --shell fish > ~/.config/fish/completions/diffle.fish
升级后请重新运行以获取新命令。修订版本不会补全。
位于反向代理之后
diffle 可在诸如 https://proxy.example/diffle/ 这样的路径前缀下工作,无需额外设置。让代理剥离该前缀,包括 /diffle/ws 处的 WebSocket 升级,并信任其公共源:
diffle working -H 0.0.0.0 --no-open --allowed-origin https://proxy.example
如果代理将 Host 和 Origin 重写为其上游地址(例如 Kubernetes 服务名),则改为信任该地址。被拒绝的请求会返回 403,并指明失败的标头。
开发
npm install npm run dev -- working npm test && npm run typecheck && npm run build
客户端更改后重启 npm run dev;服务器提供 dist/client。
npm run fixture -- <dir> 构建测试所审查的仓库,涵盖重命名、二进制文件、
CRLF 等。截图测试在 Docker 中运行,以与 CI 保持一致:
npm run test:e2e:docker # the browser suite npm run test:e2e:docker -- -g search # matching scenarios npm run test:e2e:report # open the last report npm run test:e2e:docker:update # accept new screenshots
更多内容请参见 AGENTS.md。
致谢
diffle 的灵感来自 difit。 差异使用 @pierre/diffs 渲染。
来源:Hacker News · github.com