读懂diff,在Markdown中使用diff语法展示版本差异
diff用来比较两个文件,在开发过程中,我们免不了要和diff打交道。
- 提交代码到版本库前,对比工作区版本和版本库中的文件的差异;
- 某一功能的合入引发了Bug,对比没有出现Bug之前的版本记录;
- 补丁记录,比如npm的patch-package记录修改npm包源码记录;
- ...

diff 格式类型
在使用diff之前,我们先了解一下diff的格式。diff有三种格式:
- 正常格式(normal diff)
- 上下文格式(context diff)
- 合并格式(unified diff)
下面使用示例说明这三种文件格式,为了方便理解我们创建两个文件f1.txt,f2.txt。
f1.txt
abc
abc
abc
abc
abc
abc
abcf2.txt
abc
abc
xby
abc
abc
abc
abc
deff2.txt 第3行由abc改成了xby,并多了第8行def。
正常格式的diff
$ diff f1.txt f2.txt
2a3
> xby
7c8
< abc
---
> def这里记录了两个变动,每个变动都分为变动的位置和变动的内容。这里的变动指的是,我们如何改变第一个文件才能与第二个文件相匹配。
第一个变动:
2a3
> xby2a3表明变动的位置,前边的2表示f1.txt的第2行,后边的3表示f2.txt的第3行。中间的a是addition的缩写,表示追加,其它模式还有删除(d,代表deletion)和改变(c,代表change)。
>表示增加内容,<表示删除内容。
这里就表明f2.txt相对于f1.txt,在第2行后边增加了一行内容xby。换个说法,f1.txt在第2行后边增加一行xby就会和f2.txt一样。
第二个变动:
7c8
< abc
---
> def中间的分割线是用来分隔f1.txt和f2.txt两个文件。
f1.txt第7行,我的理解是基于第一个变动,这里的abc在第8行,f1.txt中移除第8行abc,再增加一行def,就可以和f2.txt变成一致了。
上下文格式(context diff)
$ diff -c f1.txt f2.txt
*** f1.txt 2024-04-12 07:14:59.880577600 +0800
--- f2.txt 2024-04-12 07:51:09.259859600 +0800
***************
*** 1,7 ****
abc
abc
abc
abc
abc
abc
! abc
--- 1,8 ----
abc
abc
+ xby
abc
abc
abc
abc
! def这个结果分成四个部分。
第一部分的两行,显示两个文件的基本信息:文件名和时间信息。
*** f1.txt 2024-04-12 07:14:59.880577600 +0800
--- f2.txt 2024-04-12 07:51:09.259859600 +0800"***"表示变动前的文件,"---"表示变动后的文件。
第二部分是15个星号,将文件的基本信息与变动内容分割开。
***************第三部分显示变动前的文件,即f1.txt。
*** 1,7 ****
abc
abc
abc
abc
abc
abc
! abc这时不仅显示发生变化的第2行和第7行,还显示变动行的前面和后边的几行(3行)。前面的"*** 1,7 ****"就表示,从第1行开始连续7行。
另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。
第四部分显示变动后的文件,即f2.txt。
--- 1,8 ----
abc
abc
+ xby
abc
abc
abc
abc
! def第3行加了一行,第8行有变动。
合并格式的diff
$ diff -u f1.txt f2.txt
--- f1.txt 2024-04-12 07:14:59.880577600 +0800
+++ f2.txt 2024-04-12 07:51:09.259859600 +0800
@@ -1,7 +1,8 @@
abc
abc
+xby
abc
abc
abc
abc
-abc
+def
它的第一部分,也是文件的基本信息。
--- f1.txt 2024-04-12 07:14:59.880577600 +0800
+++ f2.txt 2024-04-12 07:51:09.259859600 +0800"---"表示变动前的文件,"+++"表示变动后的文件。
第二部分,变动的位置用两个@作为起首和结束。
@@ -1,7 +1,8 @@前面的"-1,7"分成三个部分:减号表示第一个文件(即f1.txt),"1"表示第1行,"7"表示连续7行。合在一起,就表示下面是第一个文件从第1行开始的连续7行。同样的,"+1,8"表示变动后,成为第二个文件从第1行开始的连续8行。
第三部分是变动的具体内容。
abc
abc
+xby
abc
abc
abc
abc
-abc
+def除了有变动的那些行以外,也是上下文各显示3行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式"。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,加号表示第二个文件新增的行。
Markdown diff语法
Markdown diff语法是一种用于显示代码版本差异的Markdown语法,使用diff语法可以清晰的展示代码变化,例如代码的添加、删除、修改。在Markdown中,diff语法使用代码块的语法,需要指定编程语言为diff。
以上面合并格式语法为例:
```diff $ diff -u f1.txt f2.txt --- f1.txt 2024-04-12 07:14:59.880577600 +0800 +++ f2.txt 2024-04-12 07:51:09.259859600 +0800 @@ -1,7 +1,8 @@ abc abc +xby abc abc abc abc -abc +def ```
效果:
可以看到显示的结果中使用颜色对diff结果的各个部分做了区分。
结语
总的来说,diff语法是一种在Markdown中用于展示代码差异的语法,它以直观的方式展示了代码的更改,使得阅读和理解代码变化更加方便和直观。