我编辑大量的文本文件。 有时是代码。 其他时候是角色扮演游戏 (RPG)、编程书籍或一般通信的书面文字。 有时进行更改很不错,但为了让我的合作者将我的更改与他们最初编写的内容进行比较。 许多人默认使用办公套件,例如 LibreOffice,使用注释或更改跟踪功能。 有时,更简单的工具更有意义,为此,您可以查看编程历史记录,找到 diff
和 patch
等工具,这些工具为跟踪和应用对共享文件的更改提供了标准化格式。
即使对于一个简单的文件,同步两个文档也存在复杂性。 有些项目被更改,有些项目保持不变,添加了新内容,有些项目保持不变但被移动到文档中的不同位置。 如果不愉快地接受所有更改都同样有效,并将旧文件替换为新文件,则很难复制更改。 它也是整体不透明的。 有太多的变化,很难准确地挑选出发生了什么变化。
使用 diff
命令,您可以创建文件更改的记录,使用 patch
,您可以“重放”这些更改到旧版本上,使其与新版本保持同步。
设置
假设您和我正在协作处理一个描述如何泡茶的文件。
到目前为止,文件 tea.md
包含原始的复制粘贴
Boil water.
Warm the teapot.
Add tea and water to the teapot.
Place a tea cosy over the teapot.
Steep for 6 minutes.
Pour tea into cup.
Add milk.
这看起来很合理,但总可以进行优化,因此您将文件发送给我以进行改进。 为了澄清泡茶的过程,我将文件复制为 tea-revision.md
并对其进行编辑,最终得到以下结果
Warm a teapot in the proving drawer of your oven.
Boil water.
Add tea leaves to a tea strainer.
Add strainer and water to teapot.
Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
Optionally, add warm milk.
正如预期的那样,一些项目 (Boil water
和 Pour tea into cup
) 未更改,而其他行 (Warm the teapot
) 则添加了内容。 有些行是全新的,有些行是相同的,但顺序不同。
创建 diff
diff
工具显示两个文件之间的差异。 有几种不同的方法可以查看结果,但我认为最清晰的一种是 --unified
(简写为 -u
) 视图,它显示了哪些行被添加或删除。 以任何方式更改的行都被视为已删除然后添加的行。 默认情况下,diff
将其输出打印到终端。
向 diff
提供旧文件,然后提供新文件
$ diff --unified tea.md tea-revised.md
--- tea.md 2021-11-13 10:26:25.082110219 +1300
+++ tea-revised.md 2021-11-13 10:26:32.049110664 +1300
@@ -1,7 +1,7 @@
+Warm a teapot in the proving drawer of your oven.
Boil water.
-Warm the teapot.
-Add tea and water to the teapot.
-Place a tea cosy over the teapot.
-Steep for 6 minutes.
+Add tea leaves to a tea strainer.
+Add strainer and water to teapot.
+Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
-Add milk.
+Optionally, add warm milk.
行开头的加号 (+
) 表示已添加到旧文件中的内容。 行开头的减号 (-
) 表示已删除或更改的行。
使用 diff 创建补丁
补丁文件只是 diff --unified
命令的输出放入一个文件中。 您可以使用标准的 Bash 重定向来执行此操作
$ diff -u tea.md tea-revised.md > tea.patch
文件的内容与输出到终端的内容完全相同。 我喜欢在 Emacs 中查看补丁文件,它会根据每行是否被添加或删除进行颜色编码。

Seth Kenlon, CC BY-SA 4.0)
使用 patch 应用更改
一旦我有了补丁文件,我就可以将其发送给您,供您查看,并可选择将其应用于您的旧文件。 您可以使用 patch
命令应用补丁
$ patch tea.md tea.patch
添加了行,删除了行,最后,您最终得到一个与我的版本相同的文件
$ cat tea.md
Warm a teapot in the proving drawer of your oven.
Boil water.
Add tea leaves to a tea strainer.
Add strainer and water to teapot.
Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
Optionally, add warm milk.
您可以修补文件的次数没有限制。 您可以迭代我的更改,生成一个新的补丁,并将其发送给我以供审核。 发送更改而不是结果,让每个贡献者都可以查看更改的内容,决定他们想要保留或删除的内容,并准确记录该过程。
安装
在 Linux 和 macOS 上,您已经拥有 diff
和 patch
命令。 在 Windows 上,您可以通过 Cygwin 获取 diff
和 patch
,或者使用 Chocolatey 搜索 diffutils 和 patch。
如果您曾经尝试通过电子邮件或聊天协作处理文件,并且发现自己试图描述需要在哪里进行更改,那么您会喜欢 diff
和 patch
。 一个结构良好的文件,例如代码或以行分隔的 Markdown,易于 diff、patch 和维护。
2 条评论