linux命令diff

diff 命令是 Linux 上很是重要的工具,用于比较文件甚至目录的内容,清晰的告诉你先后改动的地方。diff 能够输出为补丁(patch) ,Linux 中还有一条命令patch,能够根据补丁文件,对文件更新修改。当你和别人合做或想为开源项目提供贡献时,能够将本身的修改打成补丁,邮件给合做者,他便可合并你的代码。所以diff也是svn、cvs、git等版本控制工具不可或缺的一部分。 git

diff

diff的基本格式以下: github

$ diff [参数] <变更前的文件> <变更后的文件>

命令参数有如下经常使用的一些,能够根据不一样的模式选用: vim

-b 或--ignore-space-change     不检查空格字符的不一样。
-B 或--ignore-blank-lines      不检查空白行。
-w 或--ignore-all-space        忽略所有的空格字符。
-i 或--ignore-case             不检查大小写的不一样。
-q 或--brief                   仅显示有无差别,不显示详细的信息。

在diff目录时经常使用的参数以下: svn

-r 或--recursive               比较子目录中的文件。
-N 或--new-file                文件A仅出如今某个目录中,预设会显示:Only in目录
                                文件A若使用-N参数,则diff会将文件A与一个空白的文件比较。
-P或--unidirectional-new-file  与-N相似,只有当第二个目录包含了一个第一个目录所没有的文件时,
                                才会将这个文件与空白的文件作比较。

diff有大概四种格式:正常格式并列格式上下文格式合并格式工具

还有git diff与vimdiff模式。 ui

diff能够比较文本文件或目录之间的差别,首先来说解文本文件之间的diff,示例文件以下: spa

文件f1 插件

a b
b
c
d
e

文件f2 3d

a b c
b
d
e
f

正常格式diff

正常格式不用加任何参数,diff f1 f2便可,显示结果以下: 版本控制

1c1
< a b
---
> a b c
3d2
< c
5a5
> f

1c一、3d二、5a5是说明变更的位置,前边数字表明f1中变化的行,后边的则表明f2中变化的行,中间的字母分别表明“改变”(c)、“删除”(d)和“增长”(a)。

<表示f1指定行的内容,---分割两个文件的,而后>表示f2指定行的内容。删除或增长时,则分别f二、f1中指定行无内容。

并列格式diff

其余格式diff都是前后显示两个文件的内容变化,并列格式能够并排显示两个文件的内容变化,更形象的看出文件的变化,和vimdiff显示的有些类似。

使用方法为加入-y参数,便可并列显示,-W num参数可设定并列的宽度,能够不使用。

diff -y -W 50 f1 f2

结果以下:

a b                   | a b c
b                       b
c                     <
d                       d
e                       e
                      > f

|说明此行有变化,<说明此行被删除了,>说明此行是后增长的。

上下文格式diff

标准格式diff显示的内容不够直观,上下文格式则经过显示变化的上下文,而更加的利于理解。

使用方法为使用参数-c参数: diff -c f1 f2,结果以下:

*** f1  2014-04-03 21:24:23.581007082 +0800
--- f2  2014-04-03 21:24:21.324995895 +0800
***************
*** 1,5 ****
! a b
  b
- c
  d
  e
--- 1,5 ----
! a b c
  b
  d
  e
+ f

首先,显示两个文件的基本状况:

*** f1  2014-04-03 21:24:23.581007082 +0800
--- f2  2014-04-03 21:24:21.324995895 +0800

***表示变更前的文件f1,---表示变更后的文件f2。

而后,15个星号将文件的基本状况与变更内容分割开。

最后,显示f1和f2文件的内容变更状况。

*** 1,5 ****表示f1文件的1~5行

--- 1,5 ----表示f2文件的1~5行

!表明次行内容有变更,+表示此行为新增长,-表示此行被删除了。

上下文格式默认显示包括修改行先后的三行内容,可使用-num来设置显示先后num行,如:

diff -c -1 f1 f2

合并格式diff

两个文件大量内容重复,上下文格式将显示不少无用干扰信息,后来就退出了合并式diff。

使用方法为,加入-u参数,diff -u f1 f2,结果以下:

--- f1  2014-04-03 21:24:23.581007082 +0800
+++ f2  2014-04-03 21:24:21.324995895 +0800
@@ -1,5 +1,5 @@
-a b
+a b c
 b
-c
 d
 e
+f

一样前两行表示两个文件的基本状况

而后@@ -1,5 +1,5 @@表示修改的位置,-表明 f1 的1~5行,+表明 f2 的1~5行。

最后是合并显示的变更具体内容,依旧是-表明f1,+表明f2。

同上下文格式同样,合并格式也是默认显示修改先后3行的内容,也可使用-num来设置显示先后num行:

diff -u -1 f1 f2

这里还要提到,git使用的是合并格式diff的变体。当前工做目录下git add f1后,修改f1的内容,可使用以下命令,观察作出的修改

git diff

结果以下:

diff --git a/f1 b/f1
index 924a897..c3b09ff 100644
--- a/f1
+++ b/f1
@@ -1,5 +1,5 @@
-a b
+a b c
 b
-c
 d
 e
+f

和合并格式diff的区别在头部文件基本信息,git diff显示的是a、b两个版本的f1文件的内容变化,而且显示了两个版本的git哈希值(924a897..c3b09ff),与文件的权限(644)。

vimdiff

Vim提供的diff模式称做imdiff,能够很清晰形象的观察到文件内容的变化,方便的进行合并工做。vimdiff的使用方法以下:

vimdiff f1 f2
或者
vim -d f1 f2

下图为结果的画面

vimdiffvimdiff

默认屏幕垂直分割,对比显示两个文件的不一样,若是想要水平分割可使用参数-o(不过怎么也是垂直的好看)。这里能够看到f1和f2中都有的可是内容改变的行被高亮为红色,次行内修改的具体位置被高亮为黄色;f1里有可是在f2中被删除的行,f1中显示为蓝色,f2中显示为绿色;相反,f2中增长的行显示为蓝色,f1中相应位置显示为绿色。这样更突出引发差别的地方,而且若是文件内容较多,连续相同的行会折叠起来,可使用zo和zc打开和关闭折叠。

对不一样修改内容的高亮显示,颜色能够本身自定义,在本身的Vim配置文件~/.vimrc中添加以下语句:

hi DiffAdd ctermbg=blue ctermfg=white
hi DiffDelete ctermbg=green ctermfg=none
hi DiffChange ctermbg=red ctermfg=White
hi DiffText ctermbg=yellow ctermfg=black

使用GUI的话能够配置guibg和guifg。

切换不一样的窗口可使用下列命令:

Ctrl-w l        切换到右边窗口
Ctrl-w h        切换到左边窗口
Ctrl-w j        切换到下边窗口
Ctrl-w k        切换到上边窗口

在编辑文件时也可使用命令模式启动vimdiff模式:

vim f1
:vertical diffsplit f2

若是不加vertical默认使用的水平分割。在Vim中除了diffsplit还有一些其余的命令,利于对文件进行合并和其余操做。

:diffget        把差别点中另外一个文件对应的内容复制到当前行
:diffput        把差别点中当前行的内容复制到另外一个文件对应的位置
:diffpatch      根据补丁文件更新文件内容,后面须要跟一个参数指定文件
:diffupdate     手动刷新比较结果

:qa             同时退出两个文件
:wqa            同时保存并退出

若是Vim安装来vim-fugitive插件,还可使用:Gdiff命令来比较当前文件和暫存区中的文件的不一样,也是利用的vimdiff,显示和操做同上。

目录的diff

目录间的diff比较目录中相同文件名的文件,也可使用正常格式、上下文格式、合并格式、并列格式。

示例目录为d1和d2目录,d1中有文件f一、f3,d2中有f一、f2,其中f1有一些改动。

若是不是用其余参数,不会递归比较子目录中的文件,会显示只存在目录一个目录中的文件,但不显示其详细信息,以下结果是使用diff -u d1 d2的结果:

diff -u d1/f1 d2/f1
--- d1/f1   2014-04-03 19:29:25.910803383 +0800
+++ d2/f1   2014-04-03 19:28:52.918639783 +0800
@@ -1,5 +1,5 @@
-a b c
+a b
b
+c
d
e
-f
只在 d2 存在:f2
只在 d1 存在:f3

在目录的diff中常使用的参数是-ruN,r表示递归比较子目录中的文件,u是合并格式,N表示diff会将只存在与某个目录中的文件与一个空白的文件比较。

patch

将diff的输出重定向到文本文件中,即获得补丁文件(patch),可使用patch命令对文本文件或目录打补丁,从而进行内容更新。

patch的基本用法

patch [参数] <patchfile>

参数:

-p Num  忽略几层文件夹
-E      选项说明若是发现了空文件,那么就删除它
-R      取消打过的补丁。

若是使用参数-p0,表示从当前目录找打补丁的目标文件夹,再对该目录中的文件执行patch操做。 而使用参数-p1,表示忽略第一层目录,从当前目录寻找目标文件夹中的子目录和文件,进行patch操做。

处理单个文件补丁

产生补丁

diff -uN f1 f2 > file.patch

打补丁

patch -p0 < file.patch
或者
patch f1 file.patch

取消补丁

patch -RE -p0 < file.patch
或者
patch -RE f1 file.patch

处理目录补丁

产生补丁

diff -urN d1 d2 > dir.patch

打补丁

cd d1
patch -p1 < ../dir.patch

取消补丁

patch -R -p1 < ../dir.patch

应用补丁时的目标代码和生成补丁时的代码未必相同,打补丁操做可能失败,补丁失败的文件会以.rej结尾。

相关文章
相关标签/搜索