我编辑很多文本文件。有时是代码。有时是用于角色扮演游戏 (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 创建 patch
patch 文件只是 diff --unified
命令的输出放入一个文件中。您可以使用标准的 Bash 重定向来完成此操作
$ diff -u tea.md tea-revised.md > tea.patch
文件的内容与输出到终端的内容完全相同。我喜欢在 Emacs 中查看 patch 文件,它根据每行是被添加还是被删除来对每行进行颜色编码。

Seth Kenlon, CC BY-SA 4.0)
使用 patch 应用更改
一旦我有了 patch 文件,我可以将其发送给您进行审查,并可选择将其应用于您的旧文件。您可以使用 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.
您可以 patch 文件的次数没有限制。您可以迭代我的更改,生成新的 patch,并将其发送给我进行审查。发送更改而不是结果可以让每个贡献者审查更改了什么,决定他们想要保留或删除什么,并准确记录该过程。
安装
在 Linux 和 macOS 上,您已经拥有 diff
和 patch
命令。在 Windows 上,您可以通过 Cygwin 获取 diff
和 patch
,或者使用 Chocolatey 搜索 diffutils 和 patch。
如果您曾经尝试通过电子邮件或聊天协作处理文件,并且发现自己需要描述您需要进行的更改,那么您会喜欢 diff
和 patch
。精心结构化的文件,例如代码或行分隔的 Markdown,易于 diff、patch 和维护。
2 条评论