mirror of
https://github.com/lima-vm/lima.git
synced 2026-10-28 11:44:35 +08:00
For a recursive copy whose destination is an existing directory, the rsync backend copied the *contents* of the source directory, while the scp backend copied the directory itself, like `cp -r` and `scp -r` do. Since `--backend=auto` prefers rsync and only falls back to scp when the guest has no rsync, the outcome of the very same command depended on the guest image. The rsync backend appended a trailing slash to every path of a recursive copy, and a trailing slash on the source is what tells rsync to copy the contents. Derive the form to pass to rsync from the destination instead, so that a trailing slash spelled by the user is no longer significant: - the destination is an existing directory: `SRC DST`, copying SRC into DST; - the destination does not exist yet: `SRC/ DST`, making DST a copy of SRC. A destination that can neither be confirmed nor ruled out to be a directory fails the copy, instead of being assumed to be missing, which would put the files in the wrong place again. This also fixes two related defects of the previous code: `copy -r` of a non-directory into a destination that does not exist made rsync fail on the appended slash, and multiple sources were merged into the destination instead of being copied by name. Add the missing case to copy.bats (both backends, both directions), which only covered a plain `SRC DST` copy into a destination that does not exist yet, plus unit tests for the path rewriting, which needs no VM. `limactl shell --sync` does want the form that copies the contents, so let it spell its own paths with a trailing slash and stop setting Options.Recursive, which for rsync only added a `-r` that `-a` already implies. Fixes #5500 Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>