Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What I'm trying to do is create a zipfile (or some different archive) which contains all the changed files from 2 provided directories. The path of the files should be persisted in the archive, so the archive can function as a patch.

So basically similar to:

diff -crN old_dir new_dir > pathfile

But then, for convenience, create a zipfile containing all the changed files.

Is there a standard solution for this or would I need to create my own script for this?

share|improve this question
up vote 2 down vote accepted

You can list modified files using rsync:

rsync -rnc --log-format='%f' new_dir/ old_dir/
  • -r stands for recursive
  • -n stands for performing a trial run (synonym for --dry-run)
  • -c tells rsync to compare file depending on their checksum
  • --log-format='%f'provides us filenames (long form)

This will give you the list of modified files in the new_dir/

Then, you just need to provide this list to zip:

zip patch.zip `rsync -rnc --log-format='%f' new/ old/`

Note that if you provide full path ( /path/to/new/dir/ ) using long name format ( %f ), rsync will return an additional line ( /path/to/new/dir/. ). If you use short name format ( %n ), rsync will not return this line.

share|improve this answer
    
what happens when there are spaces and newlines in the file names? – Ярослав Рахматуллин Dec 7 '12 at 11:43
    
This did the trick perfectly, thanks! – Sander Roes Dec 7 '12 at 11:51

I don't mean to preach, but the beauty of a *nix environment is the diversity of tools. Unfortunately I'm not aware of a software package that does what you ask for, but it can be done with a script. Hopefully, this example will help you write such a script.


We have a couple of folders with multiple files in them (permutations of 0-5 x 0-5).

$ ls new/ |sort | column -x -c 50 | sed 's/\t/ /g'
00 01 02 03 04 05
10 11 12 13 14 15
20 21 22 23 24 25
30 31 32 33 34 35
40 41 42 43 44 45
50 51 52 53 54 55

I removed seven random files from old and the new folder has 7 "new" files in it now:

$ find . -type d -exec sh -c 'echo -n {} " "; ls {} |wc -l' \;
.  2
./new  36
./old  29

Rsync (is a grand tool for copying files and making two folders alike) can isolate these new files:

$ rsync --size-only --out-format=%f -rin new/ old/
new/05
new/15
new/21
new/22
new/35
new/54
new/55

These file names can be fed into an archiving tool such as tar after we copy them to a new location:

$ mkdir diff/new
$ rsync -r --size-only --compare-dest=../../old/ new/  diff/new/
$ tar -C diff -czf diff.tar.gz .

And the contents of the archive are our new files:

$ tar tf diff.tar.gz
./
./new/
./new/55
./new/54
./new/35
./new/05
./new/22
./new/15
./new/21
share|improve this answer
    
Thanks for the step-by-step explanation – Sander Roes Dec 7 '12 at 11:52

You must log in to answer this question.

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