如何构建 `Git diff` 驱动

发布: (2026年4月12日 GMT+8 02:07)
5 分钟阅读
原文: Hacker News

Source: Hacker News

2024 年 11 月 起,我一直想写一篇关于如何使用 git diff 为文件之间的比较创建外部命令的文章。

在实现 renovate-packagedata-diff 时,我发现几乎没有关于如何做到这一点的文档,因此值得写篇博客来介绍。

(我后来发现,在 Git Diffs 手册页 中确实有 一些 文档,只是并不容易被发现。)

这件事已经在我的待办事项里搁置了一段时间,最近又被 Andrew Nesbitt 在其关于 Git Diff Drivers 的优秀文章以及本周对使用 oasdiff 对 OpenAPI 规范进行 diff 的探索所提醒。

我想借此机会写一篇博客,介绍这项技术的工作原理,并另外发布一篇关于将 oasdiff 作为 diff driver 使用的文章(链接)。

注意: 这是一个我们希望在输出中展示更多信息的场景,不能仅依赖 textconv 方法将(二进制)文件转换为更易比较的文本格式。在许多情况下,使用 textconv 已足够。

Source:

我们需要处理哪些参数?

虽然许多工具如果期望以 tool [before] [after] 的形式运行,开箱即用,但 git diff 会向调用的外部工具传递 7 个参数。这提供了更丰富的数据,可能会很有用。

实例演示

更新已有文件

renovate-packagedata-diff
  renovate/github-co-cddo-api-catalogue.json             # 1: 仓库中的文件名
  /tmp/git-blob-shryRa/github-co-cddo-api-catalogue.json # 2: “之前”的文件
  f0a1311ae439fff36f994a3be5d5a7eb7d7a34dc               # 3: “之前”文件的 SHA‑1 哈希
  100644                                                 # 4: “之前”文件的八进制模式
  /tmp/git-blob-y2mrZp/github-co-cddo-api-catalogue.json # 5: “之后”的文件
  e39975894a72f706e6a59bccf31120ffaa219ff3               # 6: “之后”文件的 SHA‑1 哈希
  100644                                                 # 7: “之后”文件的八进制模式

添加新文件

renovate-packagedata-diff
  renovate/github-co-cddo-api-catalogue.json             # 1: 仓库中的文件名
  /dev/null                                              # 2: “之前”
  .                                                      # 3: “之前”文件的 SHA‑1 哈希
  .                                                      # 4: “之前”文件的八进制模式
  /tmp/git-blob-iAbnMD/github-co-cddo-api-catalogue.json # 5: “之后”
  5c55e5b99b21db68c360419d44dac906c336bec6               # 6: “之后”文件的 SHA‑1 哈希
  100644                                                 # 7: “之后”文件的八进制模式

删除文件

renovate-packagedata-diff
  renovate/github-co-cddo-api-catalogue.json             # 1: 仓库中的文件名
  /tmp/git-blob-aBldZ4/github-co-cddo-api-catalogue.json # 2: “之前”
  6b24e38aa4aac8e00e44ab68e156744138ef6afc               # 3: “之前”文件的 SHA‑1 哈希
  100644                                                 # 4: “之前”文件的八进制模式
  /dev/null                                              # 5: “之后”
  .                                                      # 6: “之后”文件的 SHA‑1 哈希
  .                                                      # 7: “之后”文件的八进制模式
  • 当文件被创建或删除时使用 /dev/null
  • 在这些情况下不相关的参数会以 . 形式提供。

如果希望你的命令同时处理普通调用和 git diff 参数,也可以检查环境变量 GIT_PAGER_IN_USE 是否已设置。

使用 oasdiff 的示例

正如在我关于此的另一篇文章中所述,凭借上述信息,编写一个轻量级的包装器来比较 OpenAPI 规范的 oasdiff 工具是很直接的。

一个最小实现:

#!/usr/bin/env bash
# A diff driver for `git diff` to provide a human‑readable changelog for a given OpenAPI spec
# (based on https://www.jvt.me/posts/2026/04/11/oasdiff-driver/)

if [[ "$2" == "/dev/null" ]]; then
    echo "$1 was added"
    exit 0
elif [[ "$5" == "/dev/null" ]]; then
    echo "$1 was deleted"
    exit 0
fi

# Prefer colour always reported
oasdiff changelog "$2" "$5" --color always

此脚本不处理权限更改,如有需要可以报告,并且基于文件的 SHA‑1 校验和缓存结果可能是值得的。

0 浏览
Back to Blog

相关文章

阅读更多 »

SQL概念与实践应用

SQL 是一种用于在数据库中存储、检索和分析数据的语言。SQL 命令根据其用途被划分为不同的类别。DDL 与 DML,DDL 数据 …