With rsync
What you're doing is essentially an incremental backup: your friend (your backup) already has the original files, and you want to make an archive containing the files you've changed from that original.
Rsync has features for incremental backups.
cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
-a
means to preserve all attributes (times, ownership, etc.).
-c
means to compare file contents and not rely on date and size.
--compare-dest=/some/directory
means that files which are identical under that directory and the source tree are not copied. Note that the path is relative to the destination directory.
Rsync copies all directories, even if no files end up there. To get rid of these empty directories, run find -depth CHANGES_ONLY -type d -empty -delete
(or if your find
doesn't have -delete
and -empty
, run find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null
).
Then make the archive from the CHANGES_ONLY
directory.
The pedestrian way
Traverse the directory with your file. Skip files that are identical with the original. Create directories in the target as necessary. Copy changed files.
cd ORIGINAL_AND_MY_CHANGES
find . \! -type d -exec sh -c '
for x; do
if cmp -s "$x" "../ORIGINAL/$x"; then continue; fi
[ -d "../CHANGES_ONLY/$x" ] || mkdir -p "../CHANGES_ONLY/${%/*}"
cp -p "$x" "../CHANGES_ONLY/$x"
done
' {} +