I'm not much of a unix guy so I'll just go ahead and ask:

I have a following problem - two folders with plenty of subfolders. I need to diff them.

I tried this:

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

and that results in a 85mb file... and not really what I want.

I want the result of the diff to be many smaller patches, ideally one for every changed file with the contents of the change. That means I have t ochange the way I use diff, and I need to put it in some sort of a loop... So i tried running this little script

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

But it doesn't work :/

Ideally, I want to have a .patch file for every change, but having patches for files that changed in original would do just fine (as I could filter the newly added files and just copy them over)

Can someone provide me with a decent way to do this please?


Here's something choroba asked me to post

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

So yes, it is the proper output even though gedit/geany cannot open it. UltraEdit does...

2 Answers 2


You can use the original format that creates the huge diff file which you can subsequently split into the small files. You might be interested in csplit for the splitting, or you can use a scripting language like Perl:

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

If you need the diff line in each file, add the print after the open.

  • I really don't know anything about perl, can i paste this into a mydiff.sh file and execute it in shell? Also, since this language is somewhat unreadable to me, will it generate a .patch file for every ALTERED file between the two folders?
    – Shark
    Commented Sep 10, 2012 at 12:12
  • Yes, pasting this into your shell script or command prompt should be safe. It will create a patch file for each pair in the current working directory, for a file named a/b.c the patch will be called a_b.c.patch. I did not post a more readable version of the solution as it would take much more space.
    – choroba
    Commented Sep 10, 2012 at 12:44
  • It didn't work for me :/ does it traverse the directory tree and call diff for each file there or what? I don't even know why it doesn't work... And please take up some more space.
    – Shark
    Commented Sep 10, 2012 at 13:13
  • @Shark: It operates on the file created by diff -drupN .... Have you created it?
    – choroba
    Commented Sep 10, 2012 at 13:32
  • I have this in my folder: original_308, my_308, your_diff.sh, kernel.patch. I have found there to be 231 different files, i want those 231 .patch files to end up in a patches/ folder somehow or just following the folder structure.
    – Shark
    Commented Sep 10, 2012 at 13:48

I have wrote a small Perl script to patch the files. This script is very basic, which goes through the directories recursively and fetch the file and creates a diff.

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



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`;

Sample usage: $ ./testpatch.pl original_308/ tmp/ tmp1

I created sample files( header.cpp, head1.S, head.S)

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

After running the script, the diffs were created in a new dir "tmp1"


  • tmp1/arch/arm/boot:header.cpp.patch
  • tmp1/arch/arm/boot/compressed: head1.S.patch head.S.patch

Hope this helps.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .