Subject: bug#28520: closed (Re: bug#28483: 26.0.50; copy-directory does not create directories)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 20 Sep 2017 19:00:04 +0000

Your bug report

#28520: 26.0.50; Dired recursive copy of directory fails

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
28520: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=28520
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#28483: 26.0.50; copy-directory does not create directories
From: Paul Eggert <[email-masked]>
To: Eli Zaretskii <[email-masked]>
Cc: [email-masked], Adam Plaice <[email-masked]>, [email-masked], [email-masked], Tino Calancha <[email-masked]>
Date: Wed, 20 Sep 2017 11:59:37 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

On 09/20/2017 04:26 AM, Eli Zaretskii wrote:
> I think the problem is in this line:
>
> 	  (cond
> 	   ((eq filetype t)       ; Directory but not a symlink.
> 	    (copy-directory file newname keep-time parents)) <<<<<<<<<<<
>
> Instead of 'newname', there should be (file-name-as-directory newname)
> there.  I think.

Thanks for diagnosing the problem and for the fix. That fix should work, 
and I think we can improve on it slightly by using (copy-directory file 
target keep-time parents t), as this makes the cond branch more parallel 
with the other alternatives and avoids a call to file-name-as-directory. 
So I installed the attached patch into the emacs-26 branch to do that, 
and to add a test case for this bug. This patch should also fix 
Bug#28520 "Dired recursive copy of directory fails", so I'll CC: that 
bug report and boldly close it.

PS. Sorry, Adam, for misspelling your first name in the commit message. 
I'll try to remember to fix that when it spills out into the ChangeLog file.

>From b4531a78ded7efb0c133763b5efe1f4dab1aa4de Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Wed, 20 Sep 2017 11:49:12 -0700
Subject: [PATCH] Fix new copy-directory bug with empty dirs

Problem reported by Afdam Plaice (Bug#28520) and by Eli Zaretskii
(Bug#28483#34).  This is another bug that I introduced in my
recent copy-directory changes.
* lisp/files.el (copy-directory): Work with empty subdirectories, too.
* test/lisp/files-tests.el (files-tests--copy-directory):
Test for this bug.
---
 lisp/files.el            | 2 +-
 test/lisp/files-tests.el | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lisp/files.el b/lisp/files.el
index 0c30d40c13..f0a1f2380d 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5564,7 +5564,7 @@ copy-directory
 	      (filetype (car (file-attributes file))))
 	  (cond
 	   ((eq filetype t)       ; Directory but not a symlink.
-	    (copy-directory file newname keep-time parents))
+	    (copy-directory file target keep-time parents t))
 	   ((stringp filetype)    ; Symbolic link
 	    (make-symbolic-link filetype target t))
 	   ((copy-file file target t keep-time)))))
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index f2a9a32180..285a884b69 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -399,11 +399,16 @@ files-tests--with-temp-file
 	 (dirname (file-name-as-directory dir))
 	 (source (concat dirname "source"))
 	 (dest (concat dirname "dest/new/directory/"))
-	 (file (concat (file-name-as-directory source) "file")))
+	 (file (concat (file-name-as-directory source) "file"))
+	 (source2 (concat dirname "source2"))
+	 (dest2 (concat dirname "dest/new2")))
     (make-directory source)
     (write-region "" nil file)
     (copy-directory source dest t t t)
     (should (file-exists-p (concat dest "file")))
+    (make-directory (concat (file-name-as-directory source2) "a") t)
+    (copy-directory source2 dest2)
+    (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
     (delete-directory dir 'recursive)))
 
 (provide 'files-tests)
-- 
2.13.5

Subject: 26.0.50; Dired recursive copy of directory fails
From: adam plaice <[email-masked]>
To: [email-masked]
Date: Tue, 19 Sep 2017 23:34:43 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Copying a directory recursively, with dired ("C"), fails.

To reproduce:

mkdir test_dired_copy/a1/b -p
cd test_dired_copy
emacs -Q --eval '(dired ".")'

In dired, execute `dired-do-copy' (kbd "C") on the `a1' directory,
select `a2' (within the same parent directory) as the destination, and
answer `yes' to (`Recursive copies of ...?').

*Dired log* contains (in my specific case):

Copy ‘/home/adam/test_dired_copy/a1’ to ‘/home/adam/test_dired_copy/a2’ failed:
(file-already-exists File exists /home/adam/test_dired_copy/a2)

Copy failed for 1 of 1 file

The result is that the directory `a2' is created, but the subdirectory
`b' is not created within it. (For repeated testing, `a2' has to be
deleted each time.)

I think (though I'm not completely sure) that the problem can be
traced to copy-directory, since the following elisp fails as well:

(copy-directory "/home/adam/test_dired_copy/a1" "/home/adam/test_dired_copy/a2")

or equivalently (if already within the directory):

(copy-directory "a1" "a2")

The regression occurred in the commit range
52739ffe773eb403f58a6223b7ef64175df58dd7..e22794867d878d53675fcc91d2ef1ad2494a2ff2
(I have not had time to rebuild emacs sufficiently many times and
check which exact commit is responsible).

The bug is present in the heads of both the emacs-26
(4bef92e9e02d074de1d92e30dc5ef4dd62558c80) and master
(b1f83c10df7d1bbb16f4e13d18119ad4aa1a2137) branches.

Thank you,
Adam

In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.18.9)
 of 2017-09-13 built on adam
Repository revision: 4bef92e9e02d074de1d92e30dc5ef4dd62558c80
Windowing system distributor 'The X.Org Foundation', version 11.0.11804000
System Description:    Ubuntu 16.04.3 LTS

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.

Configured using:
 'configure --with-modules --without-pop'

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS NOTIFY
ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11 MODULES LIBSYSTEMD LCMS2

Important settings:
  value of $LANG: en_GB.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Dired by name

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message subr-x puny cl-macs seq byte-opt
gv bytecomp byte-compile cconv format-spec rfc822 mml easymenu mml-sec
password-cache epa derived epg epg-config gnus-util rmail rmail-loaddefs
mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils
mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr
mail-utils dired-aux cl-loaddefs cl-lib dired dired-loaddefs elec-pair
time-date mule-util tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar
dnd fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode elisp-mode lisp-mode prog-mode register page menu-bar
rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock
syntax facemenu font-core term/tty-colors frame cl-generic cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese composite charscript charprop
case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer
cl-preloaded nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting move-toolbar gtk
x-toolkit x multi-tty make-network-process emacs)

Memory information:
((conses 16 100826 7691)
 (symbols 48 20537 1)
 (miscs 40 52 193)
 (strings 32 28786 1222)
 (string-bytes 1 745696)
 (vectors 16 15163)
 (vector-slots 8 497313 9957)
 (floats 8 48 124)
 (intervals 56 824 11)
 (buffers 992 15)
 (heap 1024 24906 1131))