From e22794867d878d53675fcc91d2ef1ad2494a2ff2 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 10 Sep 2017 22:07:30 -0700 Subject: [PATCH 1/6] Make copy-directory act like copy-file etc. Do the special dance with the destination only if it is a directory name, for consistency with copy-file etc. (Bug#27986). * doc/emacs/files.texi (Copying and Naming): * doc/lispref/files.texi (Create/Delete Dirs): * etc/NEWS: Document this. * lisp/files.el (copy-directory): Treat NEWNAME as special only if it is a directory name. --- doc/emacs/files.texi | 8 ++++---- doc/lispref/files.texi | 5 +++-- etc/NEWS | 4 ++-- lisp/files.el | 22 ++++++++++------------ 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 0cf46b6..ca4f223 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1572,10 +1572,10 @@ Copying and Naming @findex copy-directory @kbd{M-x copy-directory} copies directories, similar to the -@command{cp -r} shell command. If @var{new} is an existing directory, -it creates a copy of the @var{old} directory and puts it in @var{new}. -If @var{new} is not an existing directory, it copies all the contents -of @var{old} into a new directory named @var{new}. +@command{cp -r} shell command. If @var{new} is a directory name, it +creates a copy of the @var{old} directory and puts it in @var{new}. +Otherwise it copies all the contents of @var{old} into a new directory +named @var{new}. @cindex renaming files @findex rename-file diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index eacaf04..901382f 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2976,8 +2976,9 @@ Create/Delete Dirs @deffn Command copy-directory dirname newname &optional keep-time parents copy-contents This command copies the directory named @var{dirname} to -@var{newname}. If @var{newname} names an existing directory, +@var{newname}. If @var{newname} is a directory name, @var{dirname} will be copied to a subdirectory there. +@xref{Directory Names}. It always sets the file modes of the copied files to match the corresponding original file. @@ -2992,7 +2993,7 @@ Create/Delete Dirs The fifth argument @var{copy-contents}, if non-@code{nil}, means to copy the contents of @var{dirname} directly into @var{newname} if the -latter is an existing directory, instead of copying @var{dirname} into +latter is a directory name, instead of copying @var{dirname} into it as a subdirectory. @end deffn diff --git a/etc/NEWS b/etc/NEWS index 4187dd8..136d458 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1285,8 +1285,8 @@ documentation and had inherent races that led to security holes. A call like (rename-file C D) that used the old, undocumented behavior can be written as (rename-file C (file-name-as-directory D)), a formulation portable to both older and newer versions of Emacs. -Affected functions include add-name-to-file, copy-file, -make-symbolic-link, and rename-file. +Affected functions include add-name-to-file, copy-directory, +copy-file, make-symbolic-link, and rename-file. * Lisp Changes in Emacs 26.1 diff --git a/lisp/files.el b/lisp/files.el index 85e649f..7ab6f76 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5501,10 +5501,10 @@ copy-directory create parent directories if they don't exist. Interactively, this happens by default. -If NEWNAME names an existing directory, copy DIRECTORY as a -subdirectory there. However, if called from Lisp with a non-nil -optional argument COPY-CONTENTS, copy the contents of DIRECTORY -directly into NEWNAME instead." +If NEWNAME is a directory name, copy DIRECTORY as a subdirectory +there. However, if called from Lisp with a non-nil optional +argument COPY-CONTENTS, copy the contents of DIRECTORY directly +into NEWNAME instead." (interactive (let ((dir (read-directory-name "Copy directory: " default-directory default-directory t nil))) @@ -5526,19 +5526,17 @@ copy-directory ;; Compute target name. (setq directory (directory-file-name (expand-file-name directory)) - newname (directory-file-name (expand-file-name newname))) + newname (expand-file-name newname)) - (cond ((not (file-directory-p newname)) - ;; If NEWNAME is not an existing directory, create it; + (cond ((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)) - ;; If NEWNAME is an existing directory and COPY-CONTENTS + ;; If NEWNAME is a directory name and COPY-CONTENTS ;; is nil, copy into NEWNAME/[DIRECTORY-BASENAME]. ((not copy-contents) - (setq newname (concat - (file-name-as-directory newname) - (file-name-nondirectory - (directory-file-name directory)))) + (setq newname (concat newname + (file-name-nondirectory directory))) (and (file-exists-p newname) (not (file-directory-p newname)) (error "Cannot overwrite non-directory %s with a directory" -- 2.7.4