summaryrefslogtreecommitdiff
path: root/lisp/files.el
diff options
context:
space:
mode:
authorPaul Eggert <eggert@penguin.cs.ucla.edu>2022-12-17 12:15:30 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2022-12-17 14:24:16 -0800
commit44c83b239d3cbb5c7675c8abd595fd3e33811ece (patch)
tree3fc699a64bc53b76b34c55cffdb7d3735b4afde9 /lisp/files.el
parentbef1edc9cacb976120dff73b4d7bbdce6ade982b (diff)
downloademacs-44c83b239d3cbb5c7675c8abd595fd3e33811ece.tar.gz
emacs-44c83b239d3cbb5c7675c8abd595fd3e33811ece.tar.bz2
emacs-44c83b239d3cbb5c7675c8abd595fd3e33811ece.zip
Fix copy-directory bug when dest dir exists
* lisp/files.el (copy-directory): Set ‘follow’ depending on whether we made the directory, not based on a guess that is sometimes wrong. When NEWNAME is a directory name and COPY-CONTENTS is nil, do not object merely because the adjusted NEWNAME is already a directory. (Bug#58919). * test/lisp/files-tests.el (files-tests-copy-directory): Test for the bug.
Diffstat (limited to 'lisp/files.el')
-rw-r--r--lisp/files.el19
1 files changed, 12 insertions, 7 deletions
diff --git a/lisp/files.el b/lisp/files.el
index 235eacee704..3cf7833ae02 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -6437,7 +6437,7 @@ into NEWNAME instead."
;; copy-directory handler.
(let ((handler (or (find-file-name-handler directory 'copy-directory)
(find-file-name-handler newname 'copy-directory)))
- (follow parents))
+ follow)
(if handler
(funcall handler 'copy-directory directory
newname keep-time parents copy-contents)
@@ -6457,19 +6457,24 @@ into NEWNAME instead."
t)
(make-symbolic-link target newname t)))
;; Else proceed to copy as a regular directory
- (cond ((not (directory-name-p newname))
+ ;; first by creating the destination directory if needed,
+ ;; preparing to follow any symlink to a directory we did not create.
+ (setq follow
+ (if (not (directory-name-p newname))
;; If NEWNAME is not a directory name, create it;
;; that is where we will copy the files of DIRECTORY.
- (make-directory newname parents))
+ (make-directory newname parents)
;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
;; create NEWNAME if it is not already a directory;
;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
- ((if copy-contents
- (or parents (not (file-directory-p newname)))
+ (unless copy-contents
(setq newname (concat newname
(file-name-nondirectory directory))))
- (make-directory (directory-file-name newname) parents))
- (t (setq follow t)))
+ (condition-case err
+ (make-directory (directory-file-name newname) parents)
+ (error
+ (or (file-directory-p newname)
+ (signal (car err) (cdr err)))))))
;; Copy recursively.
(dolist (file