如何将两个文件夹区分为多个补丁文件

如何将两个文件夹区分为多个补丁文件

我对 Unix 不太了解,所以我直接问吧:

我遇到了以下问题 - 两个文件夹有很多子文件夹。我需要对它们进行差异比较。

我尝试过这个:

diff -drupN vanila_kernel_3.0.8 my_kernel_3.0.8 > kernel.patch

结果文件大小变成了 85mb...这并不是我真正想要的。

我希望 diff 的结果是许多较小的补丁,理想情况下是每个更改的文件都有一个包含更改内容的补丁。这意味着我必须改变使用 diff 的方式,我需要将其放入某种循环中……所以我尝试运行这个小脚本

for file in original_308/*.*; do
    diff -dupN "$file" "my_308/${file##*/}" > "$file".patch
done

但它不起作用:/

理想情况下,我希望每个更改都有一个 .patch 文件,但是对原始更改的文件进行修补就可以了(因为我可以过滤新添加的文件并将它们复制过来)

有人可以为我提供一个不错的方法来做到这一点吗?

编辑:

这是 choroba 让我发布的内容

diff -Naur -x '*.o' -x '*.cmd' -x '*.d' original_308/arch/arm/boot/compressed/head.S my_308/arch/arm/boot/compressed/head.S
--- original_308/arch/arm/boot/compressed/head.S    2011-10-25 07:11:12.000000000 +0200
+++ my_308/arch/arm/boot/compressed/head.S  2012-07-04 03:57:25.000000000 +0200
@@ -656,6 +656,8 @@
@       b   __arm6_mmu_cache_off
@       b   __armv3_mmu_cache_flush

所以是的,尽管 gedit/geany 无法打开它,但它是正确的输出。UltraEdit 确实如此...

答案1

您可以使用创建巨大 diff 文件的原始格式,随后将其拆分为小文件。您可能对csplit拆分感兴趣,或者您可以使用脚本语言(如 Perl):

perl -ne 'if(/^diff -drupN (.*) (.*)/) {
              my $f = $1;
              $f =~ s{/}{_}g;
              open $FH, ">", "$f.patch" or die $!;
          } else {
              print {$FH} $_;
          }' kernel.patch

如果需要diff每个文件中都有此行,请print在 后添加open

答案2

我编写了一个小型 Perl 脚本来修补这些文件。这个脚本非常简单,它会递归遍历目录并获取文件并创建差异。

Usage: script_name.pl <source_dir> <dest_dir> <dir_2_create_diffs>

测试补丁

#!/usr/bin/perl

use File::Find;
my $source = $ARGV[0];
my $dest = $ARGV[1];
my $pathdir = $ARGV[2];

unless (defined $ARGV[2]) { print "Usage: $0 <source> <dest> <patch_directory>\n"; exit 0; }
my @alldir;
find sub {
     return if -d;
     push @alldir, $File::Find::name;
}, "$source";
for my $path ( @alldir) {
     my @tmp = split ("/",$path); my $rmt_dir = shift(@tmp); 
     my $fpath = join("/",@tmp);  my $fn = $tmp[-1];
     pop(@tmp); my $strp_path = join("/",@tmp);
     `mkdir -p $pathdir/$strp_path` unless( -d "$pathdir/$strp_path");
     `diff -dupN $path $dest$fpath > $pathdir/$strp_path/$fn.patch`;
}

使用示例:$ ./testpatch.pl original_308/ tmp/ tmp1

我创建了示例文件(header.cpp,head1.S,head.S)

  • original_308/arch/arm/boot:header.cpp
  • original_308/arch/arm/boot/压缩:head1.S head.S
  • tmp/arch/arm/boot:header.cpp
  • tmp/arch/arm/boot/压缩:head1.S head.S

运行脚本后,差异在新目录“tmp1”中创建

输出:

  • tmp1/arch/arm/boot:header.cpp.补丁
  • tmp1/arch/arm/boot/压缩:head1.S.patch head.S.patch

希望这可以帮助。

相关内容