If you use --delete
and --exclude
together what is in the excluded location won't get deleted even if the source files are removed.
But that raises the issue that the folder won't be rsync
'd at all. So you will need another rsync
job to sync
that folder.
Eg.
rsync -nav /home/richardjh/keepall/ /home/backup/richardjh/keepall/
rsync -nav --exclude=keepall --delete /home/richardjh /home/backup/richardjh
You could run these the other way around, but then it would delete all removed files and then replace them, which is not as efficient.
You can't do it as a one liner.
What you want to do is reasonable, but using rsync
to do it on its own is not. So the answer is no.
The reason is simple: rsync
keeps no history of what was in each directory and has no way of knowing what needs to be deleted and what not. Not without additional support.
You should ask yourself why you like to do this with rsync
and make that more clear. There are other programs that use librsync1.so
that are more intelligent.
With the relaxed constraints that you don't need
rsync
per se, you can take a look at
rdiff-backup:
mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b
This shows xx
and yy
are in b
.
touch b/zz
rm a/xx
rdiff-backup a b
This shows xx
and zz
are in b
. rdiff-backup
also keeps a directory rdiff-backup-data
in b
so you can rollback any changes, you should purge this on a regular basis using the rdiff-backup
commands. (The example is with local files to show extra data in the target does not get deleted, but rdiff-backup works over a network as well).
Another alternative is to setup some distributed revision control system (mercurial, bazaar, git). With mercurial e.g. you can have a script (I use a Makefile for that), that pushes all the changes to the server and then does an update of the checked out files there, ignore any additional files that are on the remote server (but have not been put under revision control).
On the server you would do:
hg init
hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client
hg commit -m "initial setup"
On the client:
hg clone ssh://username@server/dir_to_repository
Now if you remove a file on the client and do:
hg commit -m "removed file"
ssh username@server "cd dir_to_repository; hg update --clean"
Your removed file is removed on the server, but any other data (not added to the repository) does not get deleted.
Best Answer
Only if you… select one of the delete options. See
man rsync
for more information, but here is an excerpt:There is more detailed information for these options further down the
man
page.