`
dss16694
  • 浏览: 147321 次
社区版块
存档分类
最新评论

读懂diff

 
阅读更多

转自http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html

 

读懂diff

作者: 阮一峰

日期: 2012年8月29日

diff是Unix系统的一个很重要的工具程序。

它用来比较两个文本文件的差异,是代码版本管理的基石之一。你在命令行下,输入:

  $ diff <变动前的文件> <变动后的文件>

diff就会告诉你,这两个文件有何差异。它的显示结果不太好懂,下面我就来说明,如何读懂diff。

一、diff的三种格式

由于历史原因,diff有三种格式:

  * 正常格式(normal diff)

  * 上下文格式(context diff)

  * 合并格式(unified diff)

我们依次来看。

二、示例文件

为了便于讲解,先新建两个示例文件。

第一个文件叫做f1,内容是每行一个a,一共7行。

  a
  a
  a
  a
  a
  a
  a

第二个文件叫做f2,修改f1而成,第4行变成b,其他不变。

  a
  a
  a
  b
  a
  a
  a

三、正常格式的diff

现在对f1和f2进行比较:

  $ diff f1 f2

这时,diff就会显示正常格式的结果:

  4c4
  < a
  ---
  > b

第一行是一个提示,用来说明变动位置。

  4c4

它分成三个部分:前面的"4",表示f1的第4行有变化;中间的"c"表示变动的模式是内容改变(change),其他模式还有"增加"(a,代表addition)和"删除"(d,代表deletion);后面的"4",表示变动后变成f2的第4行。

第二行分成两个部分。

  < a

前面的小于号,表示要从f1当中去除该行(也就是第4行),后面的"a"表示该行的内容。

第三行用来分割f1和f2。

  ---

第四行,类似于第二行。

  > b

前面的大于号表示f2增加了该行,后面的"b"表示该行的内容。

最早的Unix(即AT&T版本的Unix),使用的就是这种格式的diff。

四、上下文格式的diff

上个世纪80年代初,加州大学伯克利分校推出BSD版本的Unix时,觉得diff的显示结果太简单,最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的diff。

它的使用方法是加入c参数(代表context)。

  $ diff -c f1 f2

显示结果如下:

  *** f1 2012-08-29 16:45:41.000000000 +0800
  --- f2 2012-08-29 16:45:51.000000000 +0800
  ***************
  *** 1,7 ****
   a
   a
   a
  !a
   a
   a
   a
  --- 1,7 ----
   a
   a
   a
  !b
   a
   a
   a

这个结果分成四个部分。

第一部分的两行,显示两个文件的基本情况:文件名和时间信息。

  *** f1 2012-08-29 16:45:41.000000000 +0800
  --- f2 2012-08-29 16:45:51.000000000 +0800

"***"表示变动前的文件,"---"表示变动后的文件。

第二部分是15个星号,将文件的基本情况与变动内容分割开。

  ***************

第三部分显示变动前的文件,即f1。

  *** 1,7 ****
   a
   a
   a
  !a
   a
   a
   a

这时不仅显示发生变化的第4行,还显示第4行的前面三行和后面三行,因此一共显示7行。所以,前面的"*** 1,7 ****"就表示,从第1行开始连续7行。

另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。

第四部分显示变动后的文件,即f2。

  --- 1,7 ----
   a
   a
   a
  !b
   a
   a
   a

除了变动行(第4行)以外,也是上下文各显示三行,总共显示7行。

五、合并格式的diff

如果两个文件相似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff率先推出了"合并格式"的diff,将f1和f2的上下文合并在一起显示。

它的使用方法是加入u参数(代表unified)。

  $ diff -u f1 f2

显示结果如下:

  --- f1 2012-08-29 16:45:41.000000000 +0800
  +++ f2 2012-08-29 16:45:51.000000000 +0800
  @@ -1,7 +1,7 @@
   a
   a
   a
  -a
  +b
   a
   a
   a

它的第一部分,也是文件的基本信息。

  --- f1 2012-08-29 16:45:41.000000000 +0800
  +++ f2 2012-08-29 16:45:51.000000000 +0800

"---"表示变动前的文件,"+++"表示变动后的文件。

第二部分,变动的位置用两个@作为起首和结束。

  @@ -1,7 +1,7 @@

前面的"-1,7"分成三个部分:减号表示第一个文件(即f1),"1"表示第1行,"7"表示连续7行。合在一起,就表示下面是第一个文件从第1行开始的连续7行。同样的,"+1,7"表示变动后,成为第二个文件从第1行开始的连续7行。

第三部分是变动的具体内容。

   a
   a
   a
  -a
  +b
   a
   a
   a

除了有变动的那些行以外,也是上下文各显示3行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式"。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,加号表示第二个文件新增的行。

六、git格式的diff

版本管理系统git,使用的是合并格式diff的变体。

  $ git diff

显示结果如下:

  diff --git a/f1 b/f1
  index 6f8a38c..449b072 100644
  --- a/f1
  +++ b/f1
  @@ -1,7 +1,7 @@
   a
   a
   a
  -a
  +b
   a
   a
   a

第一行表示结果为git格式的diff。

  diff --git a/f1 b/f1

进行比较的是,a版本的f1(即变动前)和b版本的f1(即变动后)。

第二行表示两个版本的git哈希值(index区域的6f8a38c对象,与工作目录区域的449b072对象进行比较),最后的六位数字是对象的模式(普通文件,644权限)。

  index 6f8a38c..449b072 100644

第三行表示进行比较的两个文件。

  --- a/f1
  +++ b/f1

"---"表示变动前的版本,"+++"表示变动后的版本。

后面的行都与官方的合并格式diff相同。

  @@ -1,7 +1,7 @@
   a
   a
   a
  -a
  +b
   a
   a
   a

七、阅读材料

  * diff - Wikipedia

  * How to read a patch or diff

  * How to work with diff representation in git

(完)

分享到:
评论

相关推荐

    静态测试之代码评审的一些建议

    Facebook产品经理王准的一些建议:作为审查者,一定要读懂diff;所有被接受的diff必须是在读懂的前提下。做审查者的人要有“将来如果这些代码线上出问题,我要帮助支持”的心理准备。  Facebook产品经理王准的一些...

    diff2 diff算法实践

    《diff2 diff算法实践》 在信息技术领域,`diff`是一种广泛应用的算法,主要用于比较文本文件之间的差异。这个算法能够高效地找出两个文件之间不同之处,从而帮助开发者追踪代码变化,进行版本控制,或者合并冲突。...

    diff diff算法实践

    《diff diff算法实践》 diff算法,源自Unix操作系统中的一个工具,用于比较两个文本文件的差异,找出它们的相似和不相同之处。在IT行业中,diff算法被广泛应用于版本控制系统、代码审查、文档编辑等领域,它能高效...

    Linux 下 diff 工具源码

    在Linux操作系统中,`diff`是一个非常重要的命令行工具,用于比较两个文件或目录的差异。这个工具在软件开发、版本控制以及系统管理等场景中都有广泛应用。`diff`源码的提供,使得用户可以深入理解其内部工作原理,...

    diff(Java实现)

    这个结果可以进一步解析,生成人类可读的输出,如上下文格式的差异,或者是统一格式的差异。 `diffj-1.1.3`可能是包含Java实现`diff`算法的一个库的版本。这个库可能提供了一些预定义的类和方法,便于开发者在Java...

    diff命令 文件比较工具 文本比较工具 cygwin中的文本比较工具

    它的主要功能是对比两个文件或目录之间的差异,并以可读的格式显示出来。在软件开发、系统管理和文档编辑等领域,`diff`是不可或缺的工具,它能帮助用户快速识别文件的变化,以便于版本控制、代码审查和问题排查。 ...

    js diff组件

    JavaScript Diff组件是一个强大的工具,主要用于比较两个文本字符串或者对象之间的差异。这个组件,通常被称为`jsdifflib`,在Web开发中广泛用于版本控制系统、代码编辑器、文本比较应用等场景,帮助开发者查看和...

    diff和patch说明

    在IT行业中,`diff`和`patch`是两个非常重要的工具,主要用于版本控制和软件更新。它们在源码管理和软件开发领域中起着至关重要的作用。`diff`用于比较两个文件或目录的差异,而`patch`则用来应用这些差异,从而更新...

    Python库 | diff_cover-1.0.3.tar.gz

    《Python库diff_cover详解》 在Python的开发世界中,有一个名为`diff_cover`的工具,它是用于提高代码覆盖率分析的利器。这个工具的核心功能是帮助开发者找出单元测试未覆盖到的代码行,从而提升软件的质量和稳定性...

    Windows下的diff,适用于windows10以下任何版本

    `diff`工具的主要用途是对比两个文本文件或者两个目录之间的差异,并以可读的格式输出它们的不同之处。在Windows环境下,这个工具可以用于编写批处理脚本,以便自动化地检查文件或代码的变更,这对于开发者和系统...

    jsdiff一个javascript的文本差异比较实现

    jsdiff通过计算字符级别的差异,可以生成人类可读的修改差异报告。 ### 主要功能 1. **字符级别的差异计算**:jsdiff的核心功能是计算两个字符串之间的字符级差异,这使得它可以精确地识别出文本的插入、删除和...

    linux diff 命令说明

    ### Linux `diff` 命令详解 #### 一、`diff` 命令概述 在 Linux 系统中,`diff` 是一个非常重要的命令工具,它主要用于比较两个文本文件之间的差异,并以特定格式输出这些差异。这对于版本控制、代码审查、文件...

    Go-Godiff-Google的diff-match-patch库的一个Go移植

    例如,可以使用`diff.Diff`函数来计算两个字符串的差异,`patch.Patch`函数来应用补丁,以及`patch.Unidiff`生成可读的统一差异格式(unified diff)。 **示例代码** ```go import ( "github....

    stata diff命令下载

    stata diff命令下载 解压放到stata目录下C:\stata\ado\ plus\d diff.sthlp 需要其他外部命令的也可以留言,我会尽量帮助你 找到。 其他作品: 上市银行存款总额和贷款总额数据2006-2021 A股公司企 业生命周期stata...

    前端项目-deep-diff.zip

    "前端项目-deep-diff.zip"提供了一个JavaScript实用程序,专门用于计算对象之间的深度差异,帮助开发者捕获和理解这些变化。这个项目不仅可以在Node.js环境中运行,也支持在浏览器端使用,具有广泛的适用性。 `deep...

    difftool纯净版

    《difftool纯净版——深度解析与应用指南》 difftool是一款强大的文件及代码比较工具,主要用于在版本控制系统如Git中对比不同版本之间的差异。它以“纯净版”形式出现,意味着没有捆绑任何第三方软件,提供了一个...

    这个是比较工具diff_tool

    **diff_tool工具详解** 在IT行业中,文件比较是日常工作中不可或缺的一部分,特别是在代码审查、版本控制和文本编辑等场景。`diff_tool`是一款强大的文件对比工具,它可以帮助用户快速识别和理解两个或多个文件之间...

    swift-diff-纯Swift实现的简单diff库

    diff - 纯Swift实现的简单diff库

    helm-diff-linux

    `diff`这个文件很可能是`helm-diff`插件的源代码或者安装包,如果你需要使用`helm-diff`,通常需要将其安装到你的Helm环境中,然后通过`helm plugin list`确认安装成功,并用`helm diff`命令进行实际操作。...

Global site tag (gtag.js) - Google Analytics