diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 3cae49c0b60..344e1c012ac 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -5080,11 +5080,13 @@ called from Lisp with optional argument OK-IF-ALREADY-EXISTS non-nil." (vc-backend old)))) ;; The rename commands for several VCS (at least Bzr, Git and ;; Mercurial) will fail if asked to move a directory containing - ;; only untracked files. + ;; only untracked files. So skip calling into the backend if OLD + ;; is a directory and we walk through the entirety of it without + ;; finding any VC-managed files. (unless (and dirp - (all (lambda (x) - (memq (cadr x) '(ignored unregistered))) - (vc-dir-status-files old (list old) backend))) + (catch 'done + (vc-file-tree-walk old (lambda (_) (throw 'done nil))) + t)) (vc-call-backend backend 'rename-file old new))) (vc-file-clearprops old) (vc-file-clearprops new) diff --git a/test/lisp/vc/vc-tests/vc-tests.el b/test/lisp/vc/vc-tests/vc-tests.el index ca3b62ee9e8..732ef12fbdc 100644 --- a/test/lisp/vc/vc-tests/vc-tests.el +++ b/test/lisp/vc/vc-tests/vc-tests.el @@ -671,7 +671,9 @@ This checks also `vc-backend' and `vc-responsible-backend'." (should-not (file-exists-p tmp-name1)) (should-not (file-exists-p tmp-name2)) (should (file-exists-p new-name1)) - (should (file-exists-p new-name2))) + (should (vc-registered new-name1)) + (should (file-exists-p new-name2)) + (should-not (vc-registered new-name2))) ;; Test only unregistered files. (let* ((tmp-dir (expand-file-name "dir3/" default-directory)) @@ -684,9 +686,26 @@ This checks also `vc-backend' and `vc-responsible-backend'." (vc-rename-file (directory-file-name tmp-dir) (directory-file-name new-dir)) (should-not (file-exists-p tmp-name)) + (should (file-exists-p new-name)) + (should-not (vc-registered new-name))) + + ;; Test only registered files. + + (let* ((tmp-dir (expand-file-name "dir5/" default-directory)) + (tmp-name (expand-file-name "foo" tmp-dir)) + (new-dir (expand-file-name "dir6/" default-directory)) + (new-name (expand-file-name "foo" new-dir))) + (make-directory tmp-dir) + (write-region "foo" nil tmp-name nil 'nomessage) + (vc-register `(,backend + (,(file-relative-name tmp-name + default-directory)))) + + (vc-rename-file (directory-file-name tmp-dir) + (directory-file-name new-dir)) (should-not (file-exists-p tmp-name)) (should (file-exists-p new-name)) - (should (file-exists-p new-name)))) + (should (vc-registered new-name)))) ;; Save exit. (ignore-errors