From f749a1dd7875a83e6415d8c512c5659f0f23c834 Mon Sep 17 00:00:00 2001 From: Mike Kupfer Date: Sun, 30 Oct 2022 10:31:11 -0700 Subject: [PATCH 1/2] Fix cross-filesystem directory trashing (Bug#58721) * lisp/files.el (move-file-to-trash): When trashing a directory with the same name as something that's already in the trash, copy it into the trash folder and then delete it, rather than using rename-file. --- lisp/files.el | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index a2825322580..de4f68ebd51 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -8596,10 +8596,27 @@ move-file-to-trash (setq files-base (substring (file-name-nondirectory info-fn) 0 (- (length ".trashinfo")))) (write-region nil nil info-fn nil 'quiet info-fn))) - ;; Finally, try to move the file to the trashcan. + ;; Finally, try to move the item to the trashcan. If + ;; it's a file, just move it. Things are more + ;; complicated for directories. If the target + ;; directory already exists (due to uniquification) + ;; and the trash directory is in a different + ;; filesystem, rename-file will error out, even when + ;; 'overwrite' is non-nil. Rather than worry about + ;; whether we're crossing filesystems, just check if + ;; we've moving a directory and the target directory + ;; already exists. That handles both the + ;; same-filesystem and cross-filesystem cases. (let ((delete-by-moving-to-trash nil) (new-fn (file-name-concat trash-files-dir files-base))) - (rename-file fn new-fn overwrite))))))))) + (if (or (not is-directory) + (not (file-exists-p new-fn))) + (rename-file fn new-fn overwrite) + (copy-directory fn + (file-name-as-directory new-fn) + t nil t) + (delete-directory fn t)))))))))) + (defsubst file-attribute-type (attributes) -- 2.30.2