使diff忽略符号链接

6

我的项目具有以下结构

/project/config.mk
/project/dir1/config.mk -> ../config.mk
/project/dir2/config.mk -> ../config.mk

当我使用diff创建补丁文件时,/project/config.mk被正确处理了,但两个符号链接出现了问题。它们都被视为新文件,差异部分是config.mk文件的全部内容。我尝试查找diff选项以禁用跟随符号链接,但没有这样的选项可用。欢迎提出任何建议。
根据Overbose的建议,我创建了这个脚本。它能够正常工作。感谢大家抽出时间来回答。
#!/bin/sh -v
ori_dir=$1
new_dir=$2
patch_file=./patch_file
if [ -f ${patch_file} ]
then
        rm ${patch_file}
fi
ori_files=`cd ${ori_dir} ; find ./ -type f ! -type l`
for i in ${ori_files} ; do 
        if [ -f ${ori_dir}/$i ] 
        then
                if [ -f ${new_dir}/$i ]
                then
                        diff -rup ${ori_dir}/$i ${new_dir}/$i >> ${patch_file}
                fi
        fi
done
4个回答

22
在GNU diff v3.3中,现在有一个选项--no-dereference,可以完成此操作。

2
“--no-dereference”选项在Ubuntu Xenial Xerus(16.04)和Raspian Jessie(8)的man页面中没有提到,但在“diff --help”中有描述。 - zrajm

4
如果您添加以下行:

dir1/config.mk
dir2/config.mk

创建一个名为.ignore-diff的文件,然后你可以像这样执行diff(1)

diff -ur -X .ignore-diff

1
即使像这样忽略了,损坏的符号链接似乎仍然会引发错误。 - ire_and_curses

2

以下是使用find的方法:

find . ! -type l

这个选项应该跳过后续的符号链接。在运行diff之前,使用该命令来定位您的文件。


请问您能提供命令行吗? - Dien Nguyen
@dien:抱歉,我刚刚尝试了-P选项,但它并没有像我期望的那样工作。无论如何,如果你只需要在常规文件上计算差异,可以使用以下命令:find . -type f - Heisenbug
@dien:完整的命令是什么?你是如何向diff命令提供输入的?你使用脚本吗? - Heisenbug
嗨Overbose,find . ! -type l可以工作,它只列出非符号链接文件。我该如何将这些输出提供给diff命令?(我的两个目录是project.origin和project,我已经调用了find ./project.origin ! -type l)。再次感谢! - Dien Nguyen
@dien:现在你是怎么做到的?如果你还没有做任何事情,你可以编写一个脚本来完成。我认为用一行命令实现这个解决方案有点棘手。将文件结果存储到两个列表中,然后进行比较。 - Heisenbug

0

总结我尝试过的内容。对于我的情况,可行的解决方案是使用 --no-dereference。

关于 -X 选项,您可以通过此链接获取帮助:stackoverflow.com : how-do-you-diff-a-directory-for-only-files-of-a-specific-type

# max diff
diff -ruN ~/xxx-web/ ~/www/xxx/xxx-web/ > ~/xxx-web/20180523-diff.patch
# but may get too much symbolic link following, so in GNU diff v3.3 use :
diff --no-dereference -ruN ~/xxx-web/ ~/www/xxx/xxx-web/ > ~/xxx-web/20180523-diff.patch

## if no options available, you can try a solution that do not seem to work under 3.3 :
# find . -type l > .diffignore
## passing direct file will not work, it require file pattern ?
# diff -ruN -x .diffignore 
## passing with xargs do not seem to work the way below on 3.3 ...
# diff -ruN $(cat .diffignore | xargs -L1 echo "-x ")
# diff -ruN $(cat .diffignore | xargs -i echo "-x '{}'" | sed 's,\./vivaoresto-web/,*,g') \
# inFolder outFolder > diff.patch
# if you wanna apply your path in the source directory :
cd ~/www/xxx/xxx-web/
patch -p1 < ~/xxx-web/20180523-diff.patch

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