aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2017-10-20 12:46:54 +0200
committerMichael Albinus2017-10-20 12:46:54 +0200
commitb500e06f4d05dc094b79f8f2c063e070a5a3306e (patch)
treee0d6131de893be18d6217f7709a40a5bedd2c72d
parentd815de017bb531fed751ee0515ed90b73d7a9936 (diff)
downloademacs-b500e06f4d05dc094b79f8f2c063e070a5a3306e.tar.gz
emacs-b500e06f4d05dc094b79f8f2c063e070a5a3306e.zip
Fix Bug#28896
* lisp/net/tramp-adb.el (tramp-adb-handle-rename-file): * lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file): * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file): Handle FILENAME being a directory. (Bug#28896) * test/lisp/net/tramp-tests.el (tramp-test11-copy-file) (tramp-test12-rename-file): Test also FILENAME being a directory.
-rw-r--r--lisp/net/tramp-adb.el69
-rw-r--r--lisp/net/tramp-gvfs.el7
-rw-r--r--lisp/net/tramp-sh.el174
-rw-r--r--test/lisp/net/tramp-tests.el382
4 files changed, 322 insertions, 310 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index e75efcf483f..bf21db2e8d8 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -802,38 +802,43 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
802 (setq filename (expand-file-name filename) 802 (setq filename (expand-file-name filename)
803 newname (expand-file-name newname)) 803 newname (expand-file-name newname))
804 804
805 (let ((t1 (tramp-tramp-file-p filename)) 805 (if (file-directory-p filename)
806 (t2 (tramp-tramp-file-p newname))) 806 (progn
807 (with-parsed-tramp-file-name (if t1 filename newname) nil 807 (copy-directory filename newname t t)
808 (with-tramp-progress-reporter 808 (delete-directory filename 'recursive))
809 v 0 (format "Renaming %s to %s" filename newname) 809
810 810 (let ((t1 (tramp-tramp-file-p filename))
811 (if (and t1 t2 811 (t2 (tramp-tramp-file-p newname)))
812 (tramp-equal-remote filename newname) 812 (with-parsed-tramp-file-name (if t1 filename newname) nil
813 (not (file-directory-p filename))) 813 (with-tramp-progress-reporter
814 (let ((l1 (file-remote-p filename 'localname)) 814 v 0 (format "Renaming %s to %s" filename newname)
815 (l2 (file-remote-p newname 'localname))) 815
816 (when (and (not ok-if-already-exists) 816 (if (and t1 t2
817 (file-exists-p newname)) 817 (tramp-equal-remote filename newname)
818 (tramp-error v 'file-already-exists newname)) 818 (not (file-directory-p filename)))
819 ;; We must also flush the cache of the directory, because 819 (let ((l1 (file-remote-p filename 'localname))
820 ;; `file-attributes' reads the values from there. 820 (l2 (file-remote-p newname 'localname)))
821 (tramp-flush-file-property v (file-name-directory l1)) 821 (when (and (not ok-if-already-exists)
822 (tramp-flush-file-property v l1) 822 (file-exists-p newname))
823 (tramp-flush-file-property v (file-name-directory l2)) 823 (tramp-error v 'file-already-exists newname))
824 (tramp-flush-file-property v l2) 824 ;; We must also flush the cache of the directory, because
825 ;; Short track. 825 ;; `file-attributes' reads the values from there.
826 (tramp-adb-barf-unless-okay 826 (tramp-flush-file-property v (file-name-directory l1))
827 v (format 827 (tramp-flush-file-property v l1)
828 "mv -f %s %s" 828 (tramp-flush-file-property v (file-name-directory l2))
829 (tramp-shell-quote-argument l1) 829 (tramp-flush-file-property v l2)
830 (tramp-shell-quote-argument l2)) 830 ;; Short track.
831 "Error renaming %s to %s" filename newname)) 831 (tramp-adb-barf-unless-okay
832 832 v (format
833 ;; Rename by copy. 833 "mv -f %s %s"
834 (copy-file 834 (tramp-shell-quote-argument l1)
835 filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid) 835 (tramp-shell-quote-argument l2))
836 (delete-file filename)))))) 836 "Error renaming %s to %s" filename newname))
837
838 ;; Rename by copy.
839 (copy-file
840 filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid)
841 (delete-file filename)))))))
837 842
838(defun tramp-adb-handle-process-file 843(defun tramp-adb-handle-process-file
839 (program &optional infile destination display &rest args) 844 (program &optional infile destination display &rest args)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 2b29a1b55f5..51d24cbc1b0 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -675,6 +675,11 @@ file names."
675 (unless (memq op '(copy rename)) 675 (unless (memq op '(copy rename))
676 (error "Unknown operation `%s', must be `copy' or `rename'" op)) 676 (error "Unknown operation `%s', must be `copy' or `rename'" op))
677 677
678 (if (file-directory-p filename)
679 (progn
680 (copy-directory filename newname keep-date t)
681 (when (eq op 'rename) (delete-directory filename 'recursive)))
682
678 (let ((t1 (tramp-tramp-file-p filename)) 683 (let ((t1 (tramp-tramp-file-p filename))
679 (t2 (tramp-tramp-file-p newname)) 684 (t2 (tramp-tramp-file-p newname))
680 (equal-remote (tramp-equal-remote filename newname)) 685 (equal-remote (tramp-equal-remote filename newname))
@@ -738,7 +743,7 @@ file names."
738 (when t2 743 (when t2
739 (with-parsed-tramp-file-name newname nil 744 (with-parsed-tramp-file-name newname nil
740 (tramp-flush-file-property v (file-name-directory localname)) 745 (tramp-flush-file-property v (file-name-directory localname))
741 (tramp-flush-file-property v localname))))))) 746 (tramp-flush-file-property v localname))))))))
742 747
743(defun tramp-gvfs-handle-copy-file 748(defun tramp-gvfs-handle-copy-file
744 (filename newname &optional ok-if-already-exists keep-date 749 (filename newname &optional ok-if-already-exists keep-date
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index bdb7a132408..52a6b8fac0b 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -2039,96 +2039,102 @@ of `copy' and `rename'. FILENAME and NEWNAME must be absolute
2039file names." 2039file names."
2040 (unless (memq op '(copy rename)) 2040 (unless (memq op '(copy rename))
2041 (error "Unknown operation `%s', must be `copy' or `rename'" op)) 2041 (error "Unknown operation `%s', must be `copy' or `rename'" op))
2042 (let ((t1 (tramp-tramp-file-p filename))
2043 (t2 (tramp-tramp-file-p newname))
2044 (length (tramp-compat-file-attribute-size
2045 (file-attributes (file-truename filename))))
2046 (attributes (and preserve-extended-attributes
2047 (apply 'file-extended-attributes (list filename)))))
2048 2042
2049 (with-parsed-tramp-file-name (if t1 filename newname) nil 2043 (if (file-directory-p filename)
2050 (when (and (not ok-if-already-exists) (file-exists-p newname)) 2044 (progn
2051 (tramp-error v 'file-already-exists newname)) 2045 (copy-directory filename newname keep-date t)
2052 2046 (when (eq op 'rename) (delete-directory filename 'recursive)))
2053 (with-tramp-progress-reporter
2054 v 0 (format "%s %s to %s"
2055 (if (eq op 'copy) "Copying" "Renaming")
2056 filename newname)
2057 2047
2058 (cond 2048 (let ((t1 (tramp-tramp-file-p filename))
2059 ;; Both are Tramp files. 2049 (t2 (tramp-tramp-file-p newname))
2060 ((and t1 t2) 2050 (length (tramp-compat-file-attribute-size
2061 (with-parsed-tramp-file-name filename v1 2051 (file-attributes (file-truename filename))))
2062 (with-parsed-tramp-file-name newname v2 2052 (attributes (and preserve-extended-attributes
2063 (cond 2053 (apply 'file-extended-attributes (list filename)))))
2064 ;; Shortcut: if method, host, user are the same for
2065 ;; both files, we invoke `cp' or `mv' on the remote
2066 ;; host directly.
2067 ((tramp-equal-remote filename newname)
2068 (tramp-do-copy-or-rename-file-directly
2069 op filename newname
2070 ok-if-already-exists keep-date preserve-uid-gid))
2071
2072 ;; Try out-of-band operation.
2073 ((and
2074 (tramp-method-out-of-band-p v1 length)
2075 (tramp-method-out-of-band-p v2 length))
2076 (tramp-do-copy-or-rename-file-out-of-band
2077 op filename newname keep-date))
2078
2079 ;; No shortcut was possible. So we copy the file
2080 ;; first. If the operation was `rename', we go back
2081 ;; and delete the original file (if the copy was
2082 ;; successful). The approach is simple-minded: we
2083 ;; create a new buffer, insert the contents of the
2084 ;; source file into it, then write out the buffer to
2085 ;; the target file. The advantage is that it doesn't
2086 ;; matter which file name handlers are used for the
2087 ;; source and target file.
2088 (t
2089 (tramp-do-copy-or-rename-file-via-buffer
2090 op filename newname keep-date))))))
2091
2092 ;; One file is a Tramp file, the other one is local.
2093 ((or t1 t2)
2094 (cond
2095 ;; Fast track on local machine.
2096 ((tramp-local-host-p v)
2097 (tramp-do-copy-or-rename-file-directly
2098 op filename newname
2099 ok-if-already-exists keep-date preserve-uid-gid))
2100 2054
2101 ;; If the Tramp file has an out-of-band method, the 2055 (with-parsed-tramp-file-name (if t1 filename newname) nil
2102 ;; corresponding copy-program can be invoked. 2056 (when (and (not ok-if-already-exists) (file-exists-p newname))
2103 ((tramp-method-out-of-band-p v length) 2057 (tramp-error v 'file-already-exists newname))
2104 (tramp-do-copy-or-rename-file-out-of-band
2105 op filename newname keep-date))
2106 2058
2107 ;; Use the inline method via a Tramp buffer. 2059 (with-tramp-progress-reporter
2108 (t (tramp-do-copy-or-rename-file-via-buffer 2060 v 0 (format "%s %s to %s"
2109 op filename newname keep-date)))) 2061 (if (eq op 'copy) "Copying" "Renaming")
2062 filename newname)
2110 2063
2111 (t 2064 (cond
2112 ;; One of them must be a Tramp file. 2065 ;; Both are Tramp files.
2113 (error "Tramp implementation says this cannot happen"))) 2066 ((and t1 t2)
2067 (with-parsed-tramp-file-name filename v1
2068 (with-parsed-tramp-file-name newname v2
2069 (cond
2070 ;; Shortcut: if method, host, user are the same for
2071 ;; both files, we invoke `cp' or `mv' on the remote
2072 ;; host directly.
2073 ((tramp-equal-remote filename newname)
2074 (tramp-do-copy-or-rename-file-directly
2075 op filename newname
2076 ok-if-already-exists keep-date preserve-uid-gid))
2077
2078 ;; Try out-of-band operation.
2079 ((and
2080 (tramp-method-out-of-band-p v1 length)
2081 (tramp-method-out-of-band-p v2 length))
2082 (tramp-do-copy-or-rename-file-out-of-band
2083 op filename newname keep-date))
2084
2085 ;; No shortcut was possible. So we copy the file
2086 ;; first. If the operation was `rename', we go back
2087 ;; and delete the original file (if the copy was
2088 ;; successful). The approach is simple-minded: we
2089 ;; create a new buffer, insert the contents of the
2090 ;; source file into it, then write out the buffer to
2091 ;; the target file. The advantage is that it doesn't
2092 ;; matter which file name handlers are used for the
2093 ;; source and target file.
2094 (t
2095 (tramp-do-copy-or-rename-file-via-buffer
2096 op filename newname keep-date))))))
2097
2098 ;; One file is a Tramp file, the other one is local.
2099 ((or t1 t2)
2100 (cond
2101 ;; Fast track on local machine.
2102 ((tramp-local-host-p v)
2103 (tramp-do-copy-or-rename-file-directly
2104 op filename newname
2105 ok-if-already-exists keep-date preserve-uid-gid))
2106
2107 ;; If the Tramp file has an out-of-band method, the
2108 ;; corresponding copy-program can be invoked.
2109 ((tramp-method-out-of-band-p v length)
2110 (tramp-do-copy-or-rename-file-out-of-band
2111 op filename newname keep-date))
2112
2113 ;; Use the inline method via a Tramp buffer.
2114 (t (tramp-do-copy-or-rename-file-via-buffer
2115 op filename newname keep-date))))
2114 2116
2115 ;; Handle `preserve-extended-attributes'. We ignore possible 2117 (t
2116 ;; errors, because ACL strings could be incompatible. 2118 ;; One of them must be a Tramp file.
2117 (when attributes 2119 (error "Tramp implementation says this cannot happen")))
2118 (ignore-errors 2120
2119 (apply 'set-file-extended-attributes (list newname attributes)))) 2121 ;; Handle `preserve-extended-attributes'. We ignore possible
2120 2122 ;; errors, because ACL strings could be incompatible.
2121 ;; In case of `rename', we must flush the cache of the source file. 2123 (when attributes
2122 (when (and t1 (eq op 'rename)) 2124 (ignore-errors
2123 (with-parsed-tramp-file-name filename v1 2125 (apply 'set-file-extended-attributes (list newname attributes))))
2124 (tramp-flush-file-property v1 (file-name-directory v1-localname)) 2126
2125 (tramp-flush-file-property v1 v1-localname))) 2127 ;; In case of `rename', we must flush the cache of the source file.
2126 2128 (when (and t1 (eq op 'rename))
2127 ;; When newname did exist, we have wrong cached values. 2129 (with-parsed-tramp-file-name filename v1
2128 (when t2 2130 (tramp-flush-file-property v1 (file-name-directory v1-localname))
2129 (with-parsed-tramp-file-name newname v2 2131 (tramp-flush-file-property v1 v1-localname)))
2130 (tramp-flush-file-property v2 (file-name-directory v2-localname)) 2132
2131 (tramp-flush-file-property v2 v2-localname))))))) 2133 ;; When newname did exist, we have wrong cached values.
2134 (when t2
2135 (with-parsed-tramp-file-name newname v2
2136 (tramp-flush-file-property v2 (file-name-directory v2-localname))
2137 (tramp-flush-file-property v2 v2-localname))))))))
2132 2138
2133(defun tramp-do-copy-or-rename-file-via-buffer (op filename newname keep-date) 2139(defun tramp-do-copy-or-rename-file-via-buffer (op filename newname keep-date)
2134 "Use an Emacs buffer to copy or rename a file. 2140 "Use an Emacs buffer to copy or rename a file.
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index c88abbfcb26..e92d1b6203c 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -1883,96 +1883,98 @@ This checks also `file-name-as-directory', `file-name-directory',
1883 (let (quoted) 1883 (let (quoted)
1884 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) 1884 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
1885 (tmp-name2 (tramp--test-make-temp-name nil quoted)) 1885 (tmp-name2 (tramp--test-make-temp-name nil quoted))
1886 (tmp-name3 (tramp--test-make-temp-name nil quoted)) 1886 (tmp-name3 (tramp--test-make-temp-name 'local quoted)))
1887 (tmp-name4 (tramp--test-make-temp-name 'local quoted)) 1887 (dolist (source-target
1888 (tmp-name5 (tramp--test-make-temp-name 'local quoted))) 1888 `(;; Copy on remote side.
1889 1889 (,tmp-name1 . ,tmp-name2)
1890 ;; Copy on remote side. 1890 ;; Copy from remote side to local side.
1891 (unwind-protect 1891 (,tmp-name1 . ,tmp-name3)
1892 (progn 1892 ;; Copy from local side to remote side.
1893 (write-region "foo" nil tmp-name1) 1893 (,tmp-name3 . ,tmp-name1)))
1894 (copy-file tmp-name1 tmp-name2) 1894 (let ((source (car source-target))
1895 (should (file-exists-p tmp-name2)) 1895 (target (cdr source-target)))
1896 (with-temp-buffer 1896
1897 (insert-file-contents tmp-name2) 1897 ;; Copy simple file.
1898 (should (string-equal (buffer-string) "foo"))) 1898 (unwind-protect
1899 (should-error 1899 (progn
1900 (copy-file tmp-name1 tmp-name2) 1900 (write-region "foo" nil source)
1901 :type 'file-already-exists) 1901 (should (file-exists-p source))
1902 (copy-file tmp-name1 tmp-name2 'ok) 1902 (copy-file source target)
1903 (make-directory tmp-name3) 1903 (should (file-exists-p target))
1904 ;; This has been changed in Emacs 26.1. 1904 (with-temp-buffer
1905 (when (tramp--test-emacs26-p) 1905 (insert-file-contents target)
1906 (should-error 1906 (should (string-equal (buffer-string) "foo")))
1907 (copy-file tmp-name1 tmp-name3) 1907 (should-error
1908 :type 'file-already-exists)) 1908 (copy-file source target)
1909 (copy-file tmp-name1 (file-name-as-directory tmp-name3)) 1909 :type 'file-already-exists)
1910 (should 1910 (copy-file source target 'ok))
1911 (file-exists-p 1911
1912 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name3)))) 1912 ;; Cleanup.
1913 1913 (ignore-errors (delete-file source))
1914 ;; Cleanup. 1914 (ignore-errors (delete-file target)))
1915 (ignore-errors (delete-file tmp-name1)) 1915
1916 (ignore-errors (delete-file tmp-name2)) 1916 ;; Copy file to directory.
1917 (ignore-errors (delete-directory tmp-name3 'recursive))) 1917 (unwind-protect
1918 1918 (progn
1919 ;; Copy from remote side to local side. 1919 (write-region "foo" nil source)
1920 (unwind-protect 1920 (should (file-exists-p source))
1921 (progn 1921 (make-directory target)
1922 (write-region "foo" nil tmp-name1) 1922 (should (file-directory-p target))
1923 (copy-file tmp-name1 tmp-name4) 1923 ;; This has been changed in Emacs 26.1.
1924 (should (file-exists-p tmp-name4)) 1924 (when (tramp--test-emacs26-p)
1925 (with-temp-buffer 1925 (should-error
1926 (insert-file-contents tmp-name4) 1926 (copy-file source target)
1927 (should (string-equal (buffer-string) "foo"))) 1927 :type 'file-already-exists))
1928 (should-error 1928 (copy-file source (file-name-as-directory target))
1929 (copy-file tmp-name1 tmp-name4) 1929 (should
1930 :type 'file-already-exists) 1930 (file-exists-p
1931 (copy-file tmp-name1 tmp-name4 'ok) 1931 (expand-file-name (file-name-nondirectory source) target))))
1932 (make-directory tmp-name5) 1932
1933 ;; This has been changed in Emacs 26.1. 1933 ;; Cleanup.
1934 (when (tramp--test-emacs26-p) 1934 (ignore-errors (delete-file source))
1935 (should-error 1935 (ignore-errors (delete-directory target 'recursive)))
1936 (copy-file tmp-name1 tmp-name5) 1936
1937 :type 'file-already-exists)) 1937 ;; Copy directory to existing directory.
1938 (copy-file tmp-name1 (file-name-as-directory tmp-name5)) 1938 (unwind-protect
1939 (should 1939 (progn
1940 (file-exists-p 1940 (make-directory source)
1941 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name5)))) 1941 (should (file-directory-p source))
1942 1942 (write-region "foo" nil (expand-file-name "foo" source))
1943 ;; Cleanup. 1943 (should (file-exists-p (expand-file-name "foo" source)))
1944 (ignore-errors (delete-file tmp-name1)) 1944 (make-directory target)
1945 (ignore-errors (delete-file tmp-name4)) 1945 (should (file-directory-p target))
1946 (ignore-errors (delete-directory tmp-name5 'recursive))) 1946 ;; Directory `target' exists already, so we must use
1947 1947 ;; `file-name-as-directory'.
1948 ;; Copy from local side to remote side. 1948 (copy-file source (file-name-as-directory target))
1949 (unwind-protect 1949 (should
1950 (progn 1950 (file-exists-p
1951 (write-region "foo" nil tmp-name4 nil 'nomessage) 1951 (expand-file-name
1952 (copy-file tmp-name4 tmp-name1) 1952 (concat (file-name-nondirectory source) "/foo") target))))
1953 (should (file-exists-p tmp-name1)) 1953
1954 (with-temp-buffer 1954 ;; Cleanup.
1955 (insert-file-contents tmp-name1) 1955 (ignore-errors (delete-directory source 'recursive))
1956 (should (string-equal (buffer-string) "foo"))) 1956 (ignore-errors (delete-directory target 'recursive)))
1957 (should-error 1957
1958 (copy-file tmp-name4 tmp-name1) 1958 ;; Copy directory/file to non-existing directory.
1959 :type 'file-already-exists) 1959 (unwind-protect
1960 (copy-file tmp-name4 tmp-name1 'ok) 1960 (progn
1961 (make-directory tmp-name3) 1961 (make-directory source)
1962 ;; This has been changed in Emacs 26.1. 1962 (should (file-directory-p source))
1963 (when (tramp--test-emacs26-p) 1963 (write-region "foo" nil (expand-file-name "foo" source))
1964 (should-error 1964 (should (file-exists-p (expand-file-name "foo" source)))
1965 (copy-file tmp-name4 tmp-name3) 1965 (make-directory target)
1966 :type 'file-already-exists)) 1966 (should (file-directory-p target))
1967 (copy-file tmp-name4 (file-name-as-directory tmp-name3)) 1967 (copy-file
1968 (should 1968 source
1969 (file-exists-p 1969 (expand-file-name (file-name-nondirectory source) target))
1970 (expand-file-name (file-name-nondirectory tmp-name4) tmp-name3)))) 1970 (should
1971 (file-exists-p
1972 (expand-file-name
1973 (concat (file-name-nondirectory source) "/foo") target))))
1971 1974
1972 ;; Cleanup. 1975 ;; Cleanup.
1973 (ignore-errors (delete-file tmp-name1)) 1976 (ignore-errors (delete-directory source 'recursive))
1974 (ignore-errors (delete-file tmp-name4)) 1977 (ignore-errors (delete-directory target 'recursive))))))))
1975 (ignore-errors (delete-directory tmp-name3 'recursive))))))
1976 1978
1977(ert-deftest tramp-test12-rename-file () 1979(ert-deftest tramp-test12-rename-file ()
1978 "Check `rename-file'." 1980 "Check `rename-file'."
@@ -1983,111 +1985,105 @@ This checks also `file-name-as-directory', `file-name-directory',
1983 (let (quoted) 1985 (let (quoted)
1984 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) 1986 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
1985 (tmp-name2 (tramp--test-make-temp-name nil quoted)) 1987 (tmp-name2 (tramp--test-make-temp-name nil quoted))
1986 (tmp-name3 (tramp--test-make-temp-name nil quoted)) 1988 (tmp-name3 (tramp--test-make-temp-name 'local quoted)))
1987 (tmp-name4 (tramp--test-make-temp-name 'local quoted)) 1989 (dolist (source-target
1988 (tmp-name5 (tramp--test-make-temp-name 'local quoted))) 1990 `(;; Rename on remote side.
1989 1991 (,tmp-name1 . ,tmp-name2)
1990 ;; Rename on remote side. 1992 ;; Rename from remote side to local side.
1991 (unwind-protect 1993 (,tmp-name1 . ,tmp-name3)
1992 (progn 1994 ;; Rename from local side to remote side.
1993 (write-region "foo" nil tmp-name1) 1995 (,tmp-name3 . ,tmp-name1)))
1994 (rename-file tmp-name1 tmp-name2) 1996 (let ((source (car source-target))
1995 (should-not (file-exists-p tmp-name1)) 1997 (target (cdr source-target)))
1996 (should (file-exists-p tmp-name2)) 1998
1997 (with-temp-buffer 1999 ;; Rename simple file.
1998 (insert-file-contents tmp-name2) 2000 (unwind-protect
1999 (should (string-equal (buffer-string) "foo"))) 2001 (progn
2000 (write-region "foo" nil tmp-name1) 2002 (write-region "foo" nil source)
2001 (should-error 2003 (should (file-exists-p source))
2002 (rename-file tmp-name1 tmp-name2) 2004 (rename-file source target)
2003 :type 'file-already-exists) 2005 (should-not (file-exists-p source))
2004 (rename-file tmp-name1 tmp-name2 'ok) 2006 (should (file-exists-p target))
2005 (should-not (file-exists-p tmp-name1)) 2007 (with-temp-buffer
2006 (write-region "foo" nil tmp-name1) 2008 (insert-file-contents target)
2007 (make-directory tmp-name3) 2009 (should (string-equal (buffer-string) "foo")))
2008 ;; This has been changed in Emacs 26.1. 2010 (write-region "foo" nil source)
2009 (when (tramp--test-emacs26-p) 2011 (should (file-exists-p source))
2010 (should-error 2012 (should-error
2011 (rename-file tmp-name1 tmp-name3) 2013 (rename-file source target)
2012 :type 'file-already-exists)) 2014 :type 'file-already-exists)
2013 (rename-file tmp-name1 (file-name-as-directory tmp-name3)) 2015 (rename-file source target 'ok)
2014 (should-not (file-exists-p tmp-name1)) 2016 (should-not (file-exists-p source)))
2015 (should 2017
2016 (file-exists-p 2018 ;; Cleanup.
2017 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name3)))) 2019 (ignore-errors (delete-file source))
2018 2020 (ignore-errors (delete-file target)))
2019 ;; Cleanup. 2021
2020 (ignore-errors (delete-file tmp-name1)) 2022 ;; Rename file to directory.
2021 (ignore-errors (delete-file tmp-name2)) 2023 (unwind-protect
2022 (ignore-errors (delete-directory tmp-name3 'recursive))) 2024 (progn
2023 2025 (write-region "foo" nil source)
2024 ;; Rename from remote side to local side. 2026 (should (file-exists-p source))
2025 (unwind-protect 2027 (make-directory target)
2026 (progn 2028 (should (file-directory-p target))
2027 (write-region "foo" nil tmp-name1) 2029 ;; This has been changed in Emacs 26.1.
2028 (rename-file tmp-name1 tmp-name4) 2030 (when (tramp--test-emacs26-p)
2029 (should-not (file-exists-p tmp-name1)) 2031 (should-error
2030 (should (file-exists-p tmp-name4)) 2032 (rename-file source target)
2031 (with-temp-buffer 2033 :type 'file-already-exists))
2032 (insert-file-contents tmp-name4) 2034 (rename-file source (file-name-as-directory target))
2033 (should (string-equal (buffer-string) "foo"))) 2035 (should-not (file-exists-p source))
2034 (write-region "foo" nil tmp-name1) 2036 (should
2035 (should-error 2037 (file-exists-p
2036 (rename-file tmp-name1 tmp-name4) 2038 (expand-file-name (file-name-nondirectory source) target))))
2037 :type 'file-already-exists) 2039
2038 (rename-file tmp-name1 tmp-name4 'ok) 2040 ;; Cleanup.
2039 (should-not (file-exists-p tmp-name1)) 2041 (ignore-errors (delete-file source))
2040 (write-region "foo" nil tmp-name1) 2042 (ignore-errors (delete-directory target 'recursive)))
2041 (make-directory tmp-name5) 2043
2042 ;; This has been changed in Emacs 26.1. 2044 ;; Rename directory to existing directory.
2043 (when (tramp--test-emacs26-p) 2045 (unwind-protect
2044 (should-error 2046 (progn
2045 (rename-file tmp-name1 tmp-name5) 2047 (make-directory source)
2046 :type 'file-already-exists)) 2048 (should (file-directory-p source))
2047 (rename-file tmp-name1 (file-name-as-directory tmp-name5)) 2049 (write-region "foo" nil (expand-file-name "foo" source))
2048 (should-not (file-exists-p tmp-name1)) 2050 (should (file-exists-p (expand-file-name "foo" source)))
2049 (should 2051 (make-directory target)
2050 (file-exists-p 2052 (should (file-directory-p target))
2051 (expand-file-name (file-name-nondirectory tmp-name1) tmp-name5)))) 2053 ;; Directory `target' exists already, so we must use
2052 2054 ;; `file-name-as-directory'.
2053 ;; Cleanup. 2055 (rename-file source (file-name-as-directory target))
2054 (ignore-errors (delete-file tmp-name1)) 2056 (should-not (file-exists-p source))
2055 (ignore-errors (delete-file tmp-name4)) 2057 (should
2056 (ignore-errors (delete-directory tmp-name5 'recursive))) 2058 (file-exists-p
2057 2059 (expand-file-name
2058 ;; Rename from local side to remote side. 2060 (concat (file-name-nondirectory source) "/foo") target))))
2059 (unwind-protect 2061
2060 (progn 2062 ;; Cleanup.
2061 (write-region "foo" nil tmp-name4 nil 'nomessage) 2063 (ignore-errors (delete-directory source 'recursive))
2062 (rename-file tmp-name4 tmp-name1) 2064 (ignore-errors (delete-directory target 'recursive)))
2063 (should-not (file-exists-p tmp-name4)) 2065
2064 (should (file-exists-p tmp-name1)) 2066 ;; Rename directory/file to non-existing directory.
2065 (with-temp-buffer 2067 (unwind-protect
2066 (insert-file-contents tmp-name1) 2068 (progn
2067 (should (string-equal (buffer-string) "foo"))) 2069 (make-directory source)
2068 (write-region "foo" nil tmp-name4 nil 'nomessage) 2070 (should (file-directory-p source))
2069 (should-error 2071 (write-region "foo" nil (expand-file-name "foo" source))
2070 (rename-file tmp-name4 tmp-name1) 2072 (should (file-exists-p (expand-file-name "foo" source)))
2071 :type 'file-already-exists) 2073 (make-directory target)
2072 (rename-file tmp-name4 tmp-name1 'ok) 2074 (should (file-directory-p target))
2073 (should-not (file-exists-p tmp-name4)) 2075 (rename-file
2074 (write-region "foo" nil tmp-name4 nil 'nomessage) 2076 source
2075 (make-directory tmp-name3) 2077 (expand-file-name (file-name-nondirectory source) target))
2076 ;; This has been changed in Emacs 26.1. 2078 (should-not (file-exists-p source))
2077 (when (tramp--test-emacs26-p) 2079 (should
2078 (should-error 2080 (file-exists-p
2079 (rename-file tmp-name4 tmp-name3) 2081 (expand-file-name
2080 :type 'file-already-exists)) 2082 (concat (file-name-nondirectory source) "/foo") target))))
2081 (rename-file tmp-name4 (file-name-as-directory tmp-name3))
2082 (should-not (file-exists-p tmp-name4))
2083 (should
2084 (file-exists-p
2085 (expand-file-name (file-name-nondirectory tmp-name4) tmp-name3))))
2086 2083
2087 ;; Cleanup. 2084 ;; Cleanup.
2088 (ignore-errors (delete-file tmp-name1)) 2085 (ignore-errors (delete-directory source 'recursive))
2089 (ignore-errors (delete-file tmp-name4)) 2086 (ignore-errors (delete-directory target 'recursive))))))))
2090 (ignore-errors (delete-directory tmp-name3 'recursive))))))
2091 2087
2092(ert-deftest tramp-test13-make-directory () 2088(ert-deftest tramp-test13-make-directory ()
2093 "Check `make-directory'. 2089 "Check `make-directory'.