1 概述
diff是Unix系统的一个很重要的工具程序的差异,是代码版本管理的基石之一。
文件比较的工具很多,windows系统下面就有不错的工具可以使用,例如常用的Beyond Compare,WinMerge都是图形界面的比较工具而且使用非常方便,如果你仅仅是在windows下工作,这些GUI的比较工具绝对是首选。
2 基本命令
在命令行下的基本命令有
git diff
# 比较工作目录(Working tree)和暂存区域快照(index)之间的差异
# 也就是修改之后还没有暂存起来的变化内容。
git diff --cached
git diff --staged
# 查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异
git diff HEAD
# workspace 在 最新commit的基础上所做的修改
git diff HEAD^
# 比较 workspace与最新commit的前一次commit的差异(注意与git diff HEAD的差别)
git diff HEAD~2
# 比较 workspace 与上2次提交的差异,相当于 git diff HEAD~2 HEAD~0(注意两个HEAD的位置,diff显示的结果表示 后一个(HEAD~0) 相对于 前一个的修改(HEAD~2) )
git diff [branchA] [branchB]
# 对两个分支进行比较
git diff [branchA] [branchB] >>d:/diff/exportname.diff
# 将比较生产diff文件到指定目录
git diff SHA1 SHA2
# 比较两个历史版本之间的差异
3 读懂diff文件
3.1 diff文件的是三种格式
* 正常格式(normal diff)
* 上下文格式(context diff)
* 合并格式(unified diff)
新建一个f1.txt
a
a
a
a
b
a
a
然后新建f2.txt,将f1.txt的第五行的b更改c
a
a
a
a
c
a
a
3.2 正常格式
对f1和f2进行比较
diff f1.txt f2.txt
结果如下
5c5
< b
---
> c
解读如下
5c5
# 用来说明变动位置
# 第一位5表示f1的第五行有变化,
# 第二位c代表change(a代表addition,d代表deletion)
# 第一位5表示变动后成为f2的第五行
< b
# <表示在f1文件中将该行(也就是第五行)去除, b表示去除的内容
---
# 用来分割f1和f2文件
> c
# >表示在f2文件中增加了这一行, c表增加的内容
3.3 上下文格式
使用方法是加入c参数(代表context)
$ diff -c f1.txt f2.txt
结果如下:
*** f1.txt 2017-03-26 01:28:29.864871700 +0000
--- f2.txt 2017-03-26 01:33:45.002896500 +0000
***************
*** 2,7 ****
a
a
a
! b
a
a
\ No newline at end of file
--- 2,7 ----
a
a
a
! c
a
a
\ No newline at end of file
解读如下:
*** f1.txt 2017-03-26 01:28:29.864871700 +0000
--- f2.txt 2017-03-26 01:33:45.002896500 +0000
# 用来显示两个文件的文件名和时间信息
# “***”用来表示变化之前的文件,“---”用来表示变化之后的文件
***************
# 15个星号,将文件的基本情况与变动内容分割开。
*** 2,7 ****
a
a
a
! b
a
a
\ No newline at end of file
# 第三部分显示变动前的文件,即f1
# 此时不光显示变动的第五行,显示第五行的前三行和后三行
# 2,7代表下面显示的内容是从第二行开始,至第七行结束的内容
# 文件内容的每一行最前面,还有一个标记位。
# 如果为空,表示该行无变化;
# 如果是感叹号(!),表示该行有改动;
# 如果是减号(-),表示该行被删除;
# 如果是加号(+),表示该行为新增。
--- 2,7 ----
a
a
a
! c
a
a
\ No newline at end of file
# 第四部分显示变动后的文件,即f2
3.4 合并格式
如果两个文件相似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。"合并格式"的diff,将f1和f2的上下文合并在一起显示。
它的使用方法是加入u参数(代表unified)。
diff -u f1.txt f2.txt
结果如下:
--- f1.txt 2017-03-26 01:49:39.504490900 +0000
+++ f2.txt 2017-03-26 01:49:46.298879500 +0000
@@ -2,6 +2,6 @@
a
a
a
-b
+c
a
a
\ No newline at end of file
解读如下:
--- f1.txt 2017-03-26 01:49:39.504490900 +0000
+++ f2.txt 2017-03-26 01:49:46.298879500 +0000
# 第一部分也是表示文件的基本情况
# -表示变动前的文件,+表示变动后的文件
@@ -2,6 +2,6 @@
# 第二部分,变动的位置用两个@作为起首和结束
# -2,6表示下面显示的是改动前的文件从第二行开始后面的额连续六行
# +2,6表示下面显示的是改动后的文件从第二行开始后面的额连续六行
a
a
a
-b
+c
a
a
\ No newline at end of file
# 第三部分显示改动的内容
# 每一行最前面的标志位,空表示无变动
# 减号表示第一个文件删除的行
# 加号表示第二个文件新增的行。
3.5 git中的diff
版本管理系统git,使用的是合并格式diff的变体
git diff <file>
此时是对同一个文件在暂存区(index)的工作区的两个状态进行比较,如果两个版本没有区别,则不显示任何结果。
不能直接对两个文件进行比较。
f1文件内容:
a
a
a
a
b
a
a
改动之后add进入暂存区,然后改动f1文件内容
a
a
a
a
b
a
c
进行diff比较
git diff f1.txt
结果如下:
diff --git a/f1.txt b/f1.txt
index 551aa9f..8ec00fd 100644
--- a/f1.txt
+++ b/f1.txt
@@ -4,4 +4,4 @@ a
a
b
a
-a
\ No newline at end of file
+c
\ No newline at end of file
解读如下:
diff --git a/f1.txt b/f1.txt
# 表示是git格式的diff、
# 进行比较的是a版本(即变动前)的f1和b版本(即变动后)的f1
index 551aa9f..8ec00fd 100644
# 表示两个版本的git哈希值
# index区域的551aa9f对象,与工作目录区域的8ec00fd对象进行比较
# 最后的六位数字是对象的模式(普通文件,644权限)。
--- a/f1.txt
+++ b/f1.txt
@@ -4,4 +4,4 @@ a
a
b
a
-a
\ No newline at end of file
+c
\ No newline at end of file
# 这一部分与合并格式diff相同