rsync icon indicating copy to clipboard operation
rsync copied to clipboard

Allow per-directory relative paths for --compare-dest, --copy-dest and --link-dest

Open Haravikk opened this issue 4 years ago • 0 comments

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.

Haravikk avatar Jul 11 '20 11:07 Haravikk