Subject: Re: bug#47058: 28.0.50; Dired Z: insert-directory: Reading directory: No such file or directory, CrossLine_linux_x86

From: Gregory Heytings <[email-masked]>
Date: Wed, 22 Sep 2021 07:15:36 +0000

>
> If you move a directory over another by renaming, the previous directory 
> is gone, and replaced by the one you moved in its place, right?  I'm not 
> talking about what GNU mv does, I'm talking about what Emacs will do 
> when renaming a directory into another one.
>

Sorry, I don't understand your question.  With the patch, if the output 
directory already exists, an "File already exists" is displayed, as I 
think should be the case.

I attach a slightly improved version, in which a tar file containing a 
single regular file is uncompressed into a directory.

From 5bbfd5d72d8543bac4baa6b6526e86a3f72feff6 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <[email-masked]>
Date: Wed, 22 Sep 2021 07:10:46 +0000
Subject: [PATCH] Uncompress tar files in a DWIMish way

* lisp/dired-aux.el (dired-compress-file-suffixes): Add a '-C %o'
argument to tar commands.
(dired-compress-file): Extract files in a temporary directory; if
it contains a single file, use it as the output file, otherwise
rename the temporary directory and use it as the output file.
---
 lisp/dired-aux.el | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 53fbcfb6d0..85e450c3f4 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1134,9 +1134,9 @@ dired-compress-file-suffixes
     ;; "tar -zxf" isn't used because it's not available on the
     ;; Solaris 10 version of tar (obsolete in 2024?).
     ;; Same thing on AIX 7.1 (obsolete 2023?) and 7.2 (obsolete 2022?).
-    ("\\.tar\\.gz\\'" "" "gzip -dc %i | tar -xf -")
-    ("\\.tar\\.xz\\'" "" "xz -dc %i | tar -xf -")
-    ("\\.tgz\\'" "" "gzip -dc %i | tar -xf -")
+    ("\\.tar\\.gz\\'" "" "gzip -dc %i | tar -C %o -xf -")
+    ("\\.tar\\.xz\\'" "" "xz -dc %i | tar -C %o -xf -")
+    ("\\.tgz\\'" "" "gzip -dc %i | tar -C %o -xf -")
     ("\\.gz\\'" "" "gzip -d")
     ("\\.lz\\'" "" "lzip -d")
     ("\\.Z\\'" "" "uncompress")
@@ -1148,8 +1148,8 @@ dired-compress-file-suffixes
     ("\\.bz2\\'" "" "bunzip2")
     ("\\.xz\\'" "" "unxz")
     ("\\.zip\\'" "" "unzip -o -d %o %i")
-    ("\\.tar\\.zst\\'" "" "unzstd -c %i | tar -xf -")
-    ("\\.tzst\\'" "" "unzstd -c %i | tar -xf -")
+    ("\\.tar\\.zst\\'" "" "unzstd -c %i | tar -C %o -xf -")
+    ("\\.tzst\\'" "" "unzstd -c %i | tar -C %o -xf -")
     ("\\.zst\\'" "" "unzstd --rm")
     ("\\.7z\\'" "" "7z x -aoa -o%o %i")
     ;; This item controls naming for compression.
@@ -1278,15 +1278,26 @@ dired-compress-file
            nil)
           ((and suffix (setq command (nth 2 suffix)))
            (if (string-match "%[io]" command)
-               (prog1 (setq newname (file-name-as-directory newname))
+               (let ((tmp (file-name-as-directory (make-temp-file newname t))))
                  (dired-shell-command
                   (replace-regexp-in-string
-                   "%o" (shell-quote-argument newname)
+                   "%o" (shell-quote-argument tmp)
                    (replace-regexp-in-string
                     "%i" (shell-quote-argument file)
                     command
                     nil t)
-                   nil t)))
+                   nil t))
+                 (let* ((files (directory-files
+                                tmp nil
+                                directory-files-no-dot-files-regexp))
+                        (first-file (concat tmp (car files))))
+                   (if (or (> (length files) 1)
+                           (and (= (length files) 1)
+                                (file-regular-p first-file)))
+                       (rename-file tmp newname)
+                     (rename-file first-file newname)
+                     (delete-directory tmp)))
+                 (file-name-as-directory newname))
              ;; We found an uncompression rule.
              (let ((match (string-search " " command))
                    (msg (concat "Uncompressing " file)))
-- 
2.33.0