aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2022-12-17 12:15:30 -0800
committerPaul Eggert2022-12-17 14:24:16 -0800
commit44c83b239d3cbb5c7675c8abd595fd3e33811ece (patch)
tree3fc699a64bc53b76b34c55cffdb7d3735b4afde9
parentbef1edc9cacb976120dff73b4d7bbdce6ade982b (diff)
downloademacs-44c83b239d3cbb5c7675c8abd595fd3e33811ece.tar.gz
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.
-rw-r--r--lisp/files.el19
-rw-r--r--test/lisp/files-tests.el9
2 files changed, 20 insertions, 8 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."
6437 ;; copy-directory handler. 6437 ;; copy-directory handler.
6438 (let ((handler (or (find-file-name-handler directory 'copy-directory) 6438 (let ((handler (or (find-file-name-handler directory 'copy-directory)
6439 (find-file-name-handler newname 'copy-directory))) 6439 (find-file-name-handler newname 'copy-directory)))
6440 (follow parents)) 6440 follow)
6441 (if handler 6441 (if handler
6442 (funcall handler 'copy-directory directory 6442 (funcall handler 'copy-directory directory
6443 newname keep-time parents copy-contents) 6443 newname keep-time parents copy-contents)
@@ -6457,19 +6457,24 @@ into NEWNAME instead."
6457 t) 6457 t)
6458 (make-symbolic-link target newname t))) 6458 (make-symbolic-link target newname t)))
6459 ;; Else proceed to copy as a regular directory 6459 ;; Else proceed to copy as a regular directory
6460 (cond ((not (directory-name-p newname)) 6460 ;; first by creating the destination directory if needed,
6461 ;; preparing to follow any symlink to a directory we did not create.
6462 (setq follow
6463 (if (not (directory-name-p newname))
6461 ;; If NEWNAME is not a directory name, create it; 6464 ;; If NEWNAME is not a directory name, create it;
6462 ;; that is where we will copy the files of DIRECTORY. 6465 ;; that is where we will copy the files of DIRECTORY.
6463 (make-directory newname parents)) 6466 (make-directory newname parents)
6464 ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil, 6467 ;; NEWNAME is a directory name. If COPY-CONTENTS is non-nil,
6465 ;; create NEWNAME if it is not already a directory; 6468 ;; create NEWNAME if it is not already a directory;
6466 ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME]. 6469 ;; otherwise, create NEWNAME/[DIRECTORY-BASENAME].
6467 ((if copy-contents 6470 (unless copy-contents
6468 (or parents (not (file-directory-p newname)))
6469 (setq newname (concat newname 6471 (setq newname (concat newname
6470 (file-name-nondirectory directory)))) 6472 (file-name-nondirectory directory))))
6471 (make-directory (directory-file-name newname) parents)) 6473 (condition-case err
6472 (t (setq follow t))) 6474 (make-directory (directory-file-name newname) parents)
6475 (error
6476 (or (file-directory-p newname)
6477 (signal (car err) (cdr err)))))))
6473 6478
6474 ;; Copy recursively. 6479 ;; Copy recursively.
6475 (dolist (file 6480 (dolist (file
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index b9fbeb8a4e0..011bfa67cc2 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1346,7 +1346,9 @@ name (Bug#28412)."
1346 (dest (concat dirname "dest/new/directory/")) 1346 (dest (concat dirname "dest/new/directory/"))
1347 (file (concat (file-name-as-directory source) "file")) 1347 (file (concat (file-name-as-directory source) "file"))
1348 (source2 (concat dirname "source2")) 1348 (source2 (concat dirname "source2"))
1349 (dest2 (concat dirname "dest/new2"))) 1349 (dest2 (concat dirname "dest/new2"))
1350 (source3 (concat dirname "source3/d"))
1351 (dest3 (concat dirname "dest3/d")))
1350 (make-directory source) 1352 (make-directory source)
1351 (write-region "" nil file) 1353 (write-region "" nil file)
1352 (copy-directory source dest t t t) 1354 (copy-directory source dest t t t)
@@ -1354,6 +1356,11 @@ name (Bug#28412)."
1354 (make-directory (concat (file-name-as-directory source2) "a") t) 1356 (make-directory (concat (file-name-as-directory source2) "a") t)
1355 (copy-directory source2 dest2) 1357 (copy-directory source2 dest2)
1356 (should (file-directory-p (concat (file-name-as-directory dest2) "a"))) 1358 (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
1359 (make-directory source3 t)
1360 (write-region "x\n" nil (concat (file-name-as-directory source3) "file"))
1361 (make-directory dest3 t)
1362 (write-region "y\n" nil (concat (file-name-as-directory dest3) "file"))
1363 (copy-directory source3 (file-name-directory dest3) t)
1357 (delete-directory dir 'recursive)))) 1364 (delete-directory dir 'recursive))))
1358 1365
1359(ert-deftest files-tests-abbreviate-file-name-homedir () 1366(ert-deftest files-tests-abbreviate-file-name-homedir ()