两个目录树的差异,创建文件/文件夹级别的补丁(包括二进制文件)

6
有很多解决方案可以为文本文件等创建文件级补丁。我正在寻找的是一个简单的脚本/ shell命令,它将比较旧版和新版,并给我列出需要复制到旧版本中的文件树,使其与新版本相等(假设更新后未删除文件)。请注意,这两个文件夹都包含二进制文件和文本文件。
以前,我们使用了以下黑客方法:
fdupes -qrf newversion/ oldversion/ | grep "newversion" | xargs rm;
这样就留下了文件夹“newversion”,可以打包成补丁。
不幸的是,这种方法最终导致灾难性的结果,因为fdupes没有考虑文件名。
如果有像fdupes一样实际包含文件名在比较中的工具就太好了。

你是否只需要newversion/目录下的“新建”文件列表而不是“修改”的文件列表? - another.anon.coward
新文件和修改过的文件。 - Chris Weiss
3个回答

5
diff命令可以输出不同的文件名。
diff --quiet --recurse --unidirectional-new-file OLDDIR NEWDIR

Files old/main and new/main differ
Files old/main.cpp and new/main.cpp differ
Files old/Makefile and new/Makefile differ
Files old/sounds/popalien.wav and new/sounds/popalien.wav differ
Files old/sounds/saucer.wav and new/sounds/saucer.wav differ

当然,输出结果并不美观,但是由于你只想查找需要打包为补丁的新文件,一个快速的sed管道可以起到很好的作用:
diff --quiet --recurse -unidirectional-new-file OLDDIR NEWDIR | \
  sed "s/^.* and \(.*\) differ/\1/"

抱歉,我没有看到需要翻译的内容,请您再次提供需要翻译的文本。
new/main
new/main.cpp
new/Makefile
new/sounds/popalien.wav
new/sounds/saucer.wav

在 "and" 以及前面加入空格

"diff" 的操作数顺序很重要,第一个参数位于 ' and ' 的左侧,第二个参数位于其右侧。请注意这一点。

此外,如果您从 NEWDIR 中删除文件,则该命令不能找到已删除的文件,只能找到已添加或更改的文件。为了输出未在任何一个子目录中找到的文件名,请将 --unidirection-new-file 替换为 --new-file。(除 --unidirectional 外,所有选项都有短选项)


1

diff -ruN 旧版本 新版本


0

我知道已经过了很长时间。我需要同样的解决方案。我找到了这篇文章,但它不够充分。然后我发现rsync可以完成工作,但前提是要“打补丁”相同的副本,并且不需要与其他更改合并。我打算将其用于更新断开连接的机器上的yum镜像。我的完整解决方案有点复杂,我正在从记忆中编写命令,因此一些细节可能有误,但核心如下:

# create identical copy "copy.0"
rsync -a master/ copy.0/

# Presumably transfer copy.0/ to another machine for offline use
# but copy.0 must not mutate outside of this process or sync probably
# will not work.

# some time later update master, e.g. rsync master from upstream mirror
# mutates master in some way, changes/adds/removes remove files including
# binaries
echo -n $'\001\002' > master/new.bin
rm master/gone.bin

# generate rsync batch that can be used to ``patch`` copy.0
# to become identical to master
rsync -a --delete --itemize-changes --only-write-batch=copy.0.batch \
    master/ copy.0/
# now the file copy.0.batch contains only the deltas to be applied

# transfer the batch file to where it needs to be applied

# apply the batch to copy.0
rsync -a --delete --itemize-changes --read-batch=copy.0.batch copy.0/

这个处理删除和许多其他事情,可能包括权限、时间戳等,但我认为它可能无法将硬链接作为硬链接处理,并可能将它们创建为单独的未链接文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接