rsync
rsync copied to clipboard
Allow per-directory relative paths for --compare-dest, --copy-dest and --link-dest
After a bit of confusion, I've realised that options such as --compare-dest
given a relative path are relative to the root of the rsync destination, rather than as I had mistakenly assumed relative to the current target directory of a scan, i.e- rsync --link-dest=baz src/ dest/
for foo/bar
will search dest/baz/foo/bar
rather than dest/foo/bar/baz
as I had thought, which makes this relative form a bit less useful.
What I would like to see is essentially the same behaviour as per-directory merge rules, whereby a path is relative to each directory scanned. This would allow some useful new searching options.
For example, if you have a hierarchy of TV shows, and the current structure has every episode in a single directory, and you later restructure this with per-season sub-directories (i.e- missing files are one place deeper in the hierarchy), then you could potentially avoid a large amount of re-copying by doing something like:
rsync -a --delete-delay --link-dest=': ..' src/ dest/
i.e- for each missing file, rsync will also try looking within the immediately enclosing folder, even better if combined with --fuzzy
(at a potential cost to scan speed). If your files might have gone two or three levels deeper then you could also add --link-dest=': ../..' --link-dest=': ../../..'
and so-on.
I'm undecided on what the best way to implement this as an option would be. There are several alternatives I can think of off the top of my head:
-
Prefix: As used in my examples, I went with a prefix to the path of
:
since this would be consistent with per-directory merge rules. Downside to this is that colons are valid characters on some file-systems, so while the chance of collision with a genuine root-relative path is low it's not impossible. The only other prefix I can think of would be/
but it wouldn't have the consistency factor with merge rules, and is even less intuitive. -
New Options: The overkill solution is a new option for each of the current
--*-dest
options, e.g---compare-dest-per-dir
,--copy-dest-per-dir
and--link-dest-per-dir
. Would work, but would be three new options. -
--search-enclosing=n: One new option specifying the number of enclosing directories relative to the current directory to search. Default of 0 is current behaviour (current directory only),
1
means search parent as well (in both destination and--*-dest
alternatives),3
means search up to three levels higher and so-on. This only covers the use-case of scanning enclosing though, and might restrict usefulness. -
Flags: Rather than full new options (as per New Options above) it might be possible to instead use one or two flag options that change behaviour. For example
--dir-relative-dest
would tell rsync to treat all--*-dest
options with relative paths as being per-directory, rather than relative to destination root. A second option--both-relative-dest
would have rsync try both root-relative and per-directory relative paths.