I'm copying lots of files that have changed from one server to another using rsync. I know I can use the -n
option to do a dry run, so I can see what files have been changed. However is it possible to get rsync to print a diff of the file contents that's changed? I'd like to see what's happening before doing a copy? Something I can save to a file and the apply with diff(1) later?
- 30,211
- 62
- 184
- 246
7 Answers
There might be a better way, but this might work, albeit not that efficiently:
rsync -vrn / dest:/ > ~/file_list
Then edit test to remove the stats, then:
while read file; do
diff $file <(ssh dest "cat $file")
done < ~/edited_file_list
Another Option:
You might also consider mounting the file system with something like sshfs/fuse, and then just using diff.
- 82,107
- 71
- 302
- 444
-
Note: I didn't test those commands ;-) – Kyle Brandt Sep 04 '09 at 11:31
-
Good start, but there's loads of extra output from rsync, such as the statistics, and "sending incremental file list", etc – Amandasaurus Sep 04 '09 at 11:43
-
You could use --out-format="%f" – Kyle Brandt Sep 04 '09 at 11:49
-
If you use the out-format, drop the v, and grep -v 'skipping non-regular file' ... That should get it pretty clean – Kyle Brandt Sep 04 '09 at 11:51
-
Just checking if by chance there is a new / better method to `rsync --diff` two years later... – Déjà vu Jan 13 '13 at 12:30
-
The `while` only read the first line of the file. Solved by writing the `diff` commands to a temporary script: `while read file; do echo "diff $file <(ssh dest \"cat $file\")" >> /tmp/diffCheck; done < ~/edited_file_list; bash /tmp/diffCheck; rm /tmp/diffCheck`. – Roger Dueck Mar 23 '17 at 19:57
-
Given that `rsync` is copying from local to remote, it might be intuitive to reverse the `diff` arguments, so that the diff produced can be applied to the remote file, which is what `rsync` is doing. As it stands, you'll produce a reversed patch file. – Jim L. Sep 13 '19 at 18:15
For create patch:
rsync -arv --only-write-batch=patch new/ old/
For apply it:
rsync -arv --read-batch=patch dir/
or use auto-generated script:
./patch.sh
Sources:
- 3
- 2
- 159
- 1
- 3
rsync can't do this natively, but if there's a possibility of using unison you can produce diff style format from that.
- 9,751
- 1
- 32
- 33
To expand on Kyle's answer, this automates the process. Note that it is totally untested, probably pretty fragile, and may delete your computer and kill your dog.
#!/bin/bash
REMOTE=${1?Missing Remote Path}
LOCAL=${2?Missing Local Path}
# Trim trailing slash since we'll be adding it as a separator later
REMOTE=${REMOTE%/}
LOCAL=${LOCAL%/}
#Break it down
RHOST=${REMOTE%:*}
RPATH=${REMOTE#*:}
while read FILE; do
diff -u ${LOCAL}/${FILE} <(ssh $RHOST "cat ${RPATH}/${FILE}")
done < <(rsync -vrn $REMOTE/ $LOCAL/ | sed '1d;/^$/q')
- 14,885
- 7
- 49
- 71
It's not possible natively because rsync only cares about binary differences between files.
You might be able to script it, using rsync's output. But it would be hackish.
I do believe it's natively possible with Unison though.
- 25,189
- 5
- 52
- 70
Why not just use something like diff (for text files) or xdelta (for binary files) to generate the diffs? Why do you need to specifically get something out of rsync?
- 95,029
- 29
- 173
- 228
The rsync algorithm works by comparing binary chunks of the file. Such binary diff is not meant to be printable. There is a command called rdiff that uses the rsync algorithm to generate a binary diff, but I don't think it'd be useful for what you describe, it is commonly used to implement incremental backups.
- 707
- 3
- 9
- 19