Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Diff of two directory trees to create file/folder level patch (incl. binary files)

There's lots of solutions for creating a file level patch for text files and the like. What I'm looking for is an easy script/shell command that will compare oldversion/ newversion/ and give me a tree of files that I need to copy over oldversion to make it be equal to newversion (assuming files are not removed in the updated version). Note that the two folders contain both binary and text files.

Previously, we were using the hack:

fdupes -qrf newversion/ oldversion/ | grep "newversion" | xargs rm;

Leaving us with the folder "newversion" that could be packaged as a patch.

Unfortunately, this turned out to be disastrous because fdupes does not consider filenames.

What'd be great is something like fdupes that actually did include the filename in the comparison.

like image 974
Chris Weiss Avatar asked Sep 21 '11 23:09

Chris Weiss


2 Answers

The diff command can be asked to output filenames which differ.

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

Of course, it's not a nice output, but since you're only looking for NEW files to package as a patch, a quick sed pipe works wonders:

diff --quiet --recurse -unidirectional-new-file OLDDIR NEWDIR | \
  sed "s/^.* and \(.*\) differ/\1/"

(broken for readability)

new/main
new/main.cpp
new/Makefile
new/sounds/popalien.wav
new/sounds/saucer.wav

Spaces around 'and' and preceeding 'differ'

The ORDER of the operands to diff makes a difference, first argument is left of ' and ', second is after. Watch out for that.

Also, if you delete a file from NEWDIR, this will not find it as given, only added or changed files. To also output filenames for files not found in either subdir, replace the --unidirection-new-file with --new-file. (short options exist for all except --unidirectional..)

like image 80
lornix Avatar answered Oct 01 '22 12:10

lornix


diff -ruN oldversion newversion

like image 45
Mircea Avatar answered Oct 01 '22 14:10

Mircea