diff --git a/functions/rscp.fish b/functions/rscp.fish index dc43ab0..46fd651 100644 --- a/functions/rscp.fish +++ b/functions/rscp.fish @@ -173,13 +173,16 @@ function rscp --description "Copy SOURCE... to DESTINATION via rsync (local or N end end - # Failsafe: if the destination already exists, ask before overwriting. + # Failsafe: if the destination already exists *and has content*, ask + # before overwriting. An existing but empty directory is not worth + # asking about - there is nothing that could be lost. set -l dst_disp $dst_raw if test "$dst" != "$dst_raw" set dst_disp "$dst_raw ($dst)" end set -l dst_exists 0 set -l dst_is_dir 0 + set -l dst_nonempty 0 if test $dst_remote -eq 1 set -l qdst (__rscp_shquote $dst_naslocal) if ssh $dst_host test -e $qdst @@ -190,6 +193,15 @@ function rscp --description "Copy SOURCE... to DESTINATION via rsync (local or N if test $dst_exists -eq 1 if ssh $dst_host test -d $qdst set dst_is_dir 1 + set -l listing (ssh $dst_host ls -A $qdst 2>/dev/null) + set -l ls_st $status + if test $ls_st -ne 0; or test (count $listing) -gt 0 + # Unlistable -> stay safe and treat it as non-empty. + set dst_nonempty 1 + end + else + # File (or symlink): overwriting would replace content. + set dst_nonempty 1 end end else @@ -199,20 +211,27 @@ function rscp --description "Copy SOURCE... to DESTINATION via rsync (local or N if test $dst_exists -eq 1 if test -d "$dst" set dst_is_dir 1 + set -l listing (command ls -A -- "$dst" 2>/dev/null) + set -l ls_st $status + if test $ls_st -ne 0; or test (count $listing) -gt 0 + set dst_nonempty 1 + end + else + set dst_nonempty 1 end end end - if test $dst_exists -eq 1 + if test $dst_nonempty -eq 1 if test (count $srcs) -gt 1; and test $dst_is_dir -eq 0 echo "rscp: destination '$dst_disp' exists and is not a directory, but multiple sources were given." >&2 return 1 end if test $force -eq 0 if not isatty stdin - echo "rscp: destination '$dst_disp' already exists. Re-run interactively or pass -y/--yes to overwrite." >&2 + echo "rscp: destination '$dst_disp' already exists and is not empty. Re-run interactively or pass -y/--yes to overwrite." >&2 return 1 end - if not read -l -P "rscp: destination '$dst_disp' already exists. Overwrite/merge? [y/N] " confirm_raw + if not read -l -P "rscp: destination '$dst_disp' already exists and is not empty. Overwrite/merge? [y/N] " confirm_raw echo "rscp: aborted." >&2 return 1 end