为什么在仅使用cp更容易时使用diff / patch


19
diff -u file1.txt file2.txt > patchfile

创建一个补丁文件,该文件包含用于patch将file1.txt转换为与file2.txt完全相同的指令

不能使用cp命令代替吗?我可以想象这对于文件太大并且必须通过网络传输的网络很有用,这种方法可能会节省带宽。还有其他方法可以使用diff / patch在其他情况下是有利的吗?

Answers:


31

与仅将一个文件与另一个文件进行比较相比,差异可能会更加复杂。可以比较整个目录层次结构。考虑一下我要修复GCC中的错误的示例。我的更改在4或5个文件中添加了一行或两行,并删除了这些文件和其他文件中的几行。如果我想将这些更改传达给某人(可能包含在GCC中),我的选择是

  • 复制整个源代码树
  • 仅复制已更改的文件
  • 仅提供我所做的更改

复制整个源代码树没有意义,但是复制其他两个选项又是问题的核心。现在考虑其他人也和我一样在同一个文件上工作,我们都将更改交给了某人。此人将如何知道我们所做的事情以及更改是否兼容(文件的不同部分)或冲突(文件的相同行)?他会区别他们!差异可以告诉他文件之间以及未修改的源文件之间有何不同。如果需要比较,则首先发送比较就更有意义了。一个差异文件还可以包含多个文件中的更改,因此,尽管我总共编辑了9个文件,但我可以提供一个差异文件来描述这些更改。

差异也可以用于提供历史记录。如果三个月前的更改导致了我今天才发现的错误,该怎么办。如果可以在引入错误时缩小范围并将其隔离为特定更改,则可以使用diff来“撤消”或还原更改。如果仅在周围复制文件,这不是我可以轻易做到的。

所有这些都与源代码版本控制相关,在该版本中,程序可能会将文件历史记录从创建到现在的一系列差异。差异提供了历史记录(我可以像在任何特定的日子一样重新创建文件),可以看到谁应该为破坏某个东西而造成责任(差异拥有一个所有者),并且可以通过给它们特定的差异轻松地将更改提交给上游项目(也许他们只对我所做的很多改变感兴趣。

总之,是的,cpdiff和更容易patch,但是diffpatch相比cp,对于跟踪文件更改方式非常重要的情况,和的实用性更大。


实际上,git并不真正将文件历史记录存储为后续提交的差异。对于每个提交存储区,每个文件的内容(请参见“ git show -s --pretty = raw”和“ git ls-tree HEAD”)。然后,在这一层的顶部,许多文件在不同的提交中将是相似的,它使用增量压缩在文件之间共享数据(但这并不依赖于历史记录)。
ysdx

但是,差异是此历史记录的便捷可视化工具。
ysdx

20

获得补丁程序后,您通常可以(即除非您对完全相同的行进行了更改)将补丁程序应用于自己也已更改的一组文件。

该修补程序包含有关文件的旧状态新状态的信息。如果获得了复制的文件,则您将不知道原始文件是什么(旧状态),并且也无法毫不费力地将差异应用于已更改的文件(或一组文件)。因此,对于源文件集,不是主要关注的是空间保留,而是前后信息。

在(差异/统一)差异之前,通常使用针对编辑器的指令来完成此操作(在X后面插入一行,删除Y行),但这仅在您知道这些指令的开始状态时才起作用。因此,仅复制就与您的“解决方案”存在相同的问题。


2
补丁文件还可以使您撤消它并将其一次应用于多个文件
Gilsham 2015年

实际上,统一diff(diff -u)是专为人类设计的改进diff -c,我认为,与常规上下文diff()相比,它们无助于抵御冲突。即使是普通的diff(diff)仍然经常无法确切知道“这些指令的开始状态”。但是,这比公认的答案要好,因为谈论补丁文件如何同时修补多个源文件确实是个麻烦。
Celada

@celeda您对上下文差异是正确的,它与普通差异之间的主要区别在于。如果没有上下文修补程序,则很难反向应用(如果有的话)。
Anthon

12

如果您使用的是diff,则可以看到确切的更改,因此使用diff / patch是一种防止某人遗漏文件中不必要更改的方法。


11

对文件所做的更改通常比要更改的文件小得多。

这意味着存储差异可以节省大量空间。diff创建磁盘时,磁盘空间非常昂贵。

但这也意味着即使该文件已以其他方式更改,您也可以将差异重新应用到该文件。该补丁程序会为你做,并告诉你什么时候有问题。

实际上,这是在软件开发中使用差异的最重要原因。进行更改后(通常更改为多个文件),可以将其另存为差异:结果称为更改集补丁。如果一切顺利,则补丁不仅是一些随意的更改,而且还实现了某种功能上的更改-例如,错误修复或新功能。

同时,即使在不同的位置,也可能由不同的开发人员进行不同的更改。如果未对同一文件的相同部分进行更改,则可以独立应用它们。因此,开发人员可以互相发送补丁进行测试。可以建立代表可能更改的一整套补丁。其中一些最终可能会被拒绝,其余的将被集成到系统中。

因此,使用diff可以并发开发。您不再需要一次进行一项更改。

现代的分布式版本控制系统是这种工作方式的延续。


1

总之可以。如果您在youtube上观看了Thinkg Big Larry Wall的视频,他会谈到diff / patch是如何开始的以及它们解决了什么问题,本质上讲,这是在减小修补程序的灵活性和可读性的同时,通过Internet进行通信的规模。 。

如果您在本地系统上,而不关心这些事情中的任何一项,那么cp还是rsync很好。


谢谢PSKocik。您能否分享该视频的链接?
infantmenot 2015年

我不同意最后的说法。如今,这与规模无关,而在于跟踪您的开发过程,因此变得更易于管理。
reinierpost

@reinierpost使用git跟踪我的开发过程。我不直接进行差异修补。
PSkocik '18年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.