该diff程序以其各种形式,相当擅长计算两个文本文件之间的差异,并且比完整地显示两个文件更紧凑地表达它.它将差异显示为插入和删除的行块的序列(或在某些情况下更改的行,但这相当于删除后插入).patch源控制系统使用相同或非常类似的程序或算法来最小化表示同一文件的两个版本之间的差异所需的存储.这里和这里讨论算法.
但是当文件块在文件中移动时,它会掉下来.
假设您有以下两个文件,a.txt并且b.txt(假设它们都是数百行而不是6行):
a.txt b.txt
----- -----
1 4
2 5
3 6
4 1
5 2
6 3
Run Code Online (Sandbox Code Playgroud)
diff a.txt b.txt 显示这个:
$ diff a.txt b.txt
1,3d0
< 1
< 2
< 3
6a4,6
> 1
> 2
> 3
Run Code Online (Sandbox Code Playgroud)
从a.txtto 更改b.txt可以表示为"取前三行并将它们移动到最后",但是diff显示移动的行块的完整内容两次,错过了非常简短地描述这个大变化的机会.
请注意,diff -e仅显示一次文本块,但这是因为它不显示已删除行的内容.
是否存在diff算法的变体(a)保留diff表示插入和删除的能力,以及(b)有效地表示移动的文本块而不必显示其全部内容?
考虑一个文件(1.c)包含作者M和J所做的三个函数和更改.如果有人运行git blame 1.c,他将获得以下输出:
^869c699 (M 2012-09-25 14:05:31 -0600 1)
de24af82 (J 2012-09-25 14:23:52 -0600 2)
de24af82 (J 2012-09-25 14:23:52 -0600 3)
de24af82 (J 2012-09-25 14:23:52 -0600 4) public int add(int x, int y) {
de24af82 (J 2012-09-25 14:23:52 -0600 5) int z = x+y;
de24af82 (J 2012-09-25 14:23:52 -0600 6) return z;
de24af82 (J 2012-09-25 14:23:52 -0600 7) }
de24af82 (J 2012-09-25 14:23:52 -0600 8)
^869c699 (M 2012-09-25 14:05:31 -0600 9) public int multiplication(int y, int z){
^869c699 …Run Code Online (Sandbox Code Playgroud)