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?
8 Answers
There might be a better way, but this might work, albeit not that efficiently:
rsync -irn / dest:/ | grep -oP '^\S+\s+\K.+' > ~/file_list Review that list, then:
while read -r file; do file_quoted=\'${file//\'/\'\\\'\'}\' diff "$file" <(ssh dest "cat $file_quoted") done < ~/file_list Another Option:
You might also consider mounting the file system with something like sshfs/fuse, and then just using diff.
- Note: I didn't test those commands ;-)Kyle Brandt– Kyle Brandt2009-09-04 11:31:59 +00:00Commented Sep 4, 2009 at 11:31
- Good start, but there's loads of extra output from rsync, such as the statistics, and "sending incremental file list", etcAmandasaurus– Amandasaurus2009-09-04 11:43:51 +00:00Commented Sep 4, 2009 at 11:43
- You could use --out-format="%f"Kyle Brandt– Kyle Brandt2009-09-04 11:49:17 +00:00Commented Sep 4, 2009 at 11:49
- If you use the out-format, drop the v, and grep -v 'skipping non-regular file' ... That should get it pretty cleanKyle Brandt– Kyle Brandt2009-09-04 11:51:54 +00:00Commented Sep 4, 2009 at 11:51
- Just checking if by chance there is a new / better method to
rsync --difftwo years later...Déjà vu– Déjà vu2013-01-13 12:30:10 +00:00Commented Jan 13, 2013 at 12:30
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:
- 1Whilst batch operations are useful for applying changes later, such as to avoid large transfers over a network and apply them offline, they do not produce a human-readable diff of the files' contents, which was the point of the question.Walf– Walf2024-12-19 04:30:53 +00:00Commented Dec 19, 2024 at 4:30
rsync can't do this natively, but if there's a possibility of using unison you can produce diff style format from that.
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?
- I don't need rsync, but it need to be remoteAmandasaurus– Amandasaurus2009-09-04 11:38:27 +00:00Commented Sep 4, 2009 at 11:38
-
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') There's a way to do this by utilising the --compare-dest=DIR option of rsync. It can do a sparse sync (transfer only the changed files) into a temporary directory, which you can diff against on the remote. This safely leaves the real destination files untouched.
Example:
rsync --recursive --checksum --compare-dest=../dest-actual/ /path/to/source/ remote-server:/path/to/dest-for-diffing/ ssh remote-server cd /path/to/ diff --recursive --unified=4 dest-actual/ dest-for-diffing/ > ~/changes.patch vim ~/changes.patch You can pipe the diff through grep -vE '^Only in ' to skip the noise from unchanged files. Note that this, like other solutions here, does not deal with files that have been deleted from the local but still exist on the remote.
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.
- 1Is mine what you meant by hackish? :-)Kyle Brandt– Kyle Brandt2009-09-04 11:32:59 +00:00Commented Sep 4, 2009 at 11:32
- Absolutely, Kyle :DDan Carley– Dan Carley2009-09-04 11:35:14 +00:00Commented Sep 4, 2009 at 11:35
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.