diff options
author | Paul Eggert <eggert@penguin.cs.ucla.edu> | 2022-12-17 12:15:30 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2022-12-17 14:24:16 -0800 |
commit | 44c83b239d3cbb5c7675c8abd595fd3e33811ece (patch) | |
tree | 3fc699a64bc53b76b34c55cffdb7d3735b4afde9 /lisp/files.el | |
parent | bef1edc9cacb976120dff73b4d7bbdce6ade982b (diff) | |
download | emacs-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.el | 19 |
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 |