diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 3a7bb5b2170..3cae49c0b60 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -5075,10 +5075,17 @@ called from Lisp with optional argument OK-IF-ALREADY-EXISTS non-nil." (unless (memq state '(up-to-date edited added)) (error "Please %s files before moving them" (if (stringp state) "check in" "update"))))) - (vc-call-backend (if dirp - (vc-responsible-backend old) - (vc-backend old)) - 'rename-file old new) + (let ((backend (if dirp + (vc-responsible-backend old) + (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. + (unless (and dirp + (all (lambda (x) + (memq (cadr x) '(ignored unregistered))) + (vc-dir-status-files old (list old) backend))) + (vc-call-backend backend 'rename-file old new))) (vc-file-clearprops old) (vc-file-clearprops new) ;; Move the actual file (unless the backend did it already) diff --git a/test/lisp/vc/vc-tests/vc-tests.el b/test/lisp/vc/vc-tests/vc-tests.el index 77e77ededfb..ca3b62ee9e8 100644 --- a/test/lisp/vc/vc-tests/vc-tests.el +++ b/test/lisp/vc/vc-tests/vc-tests.el @@ -651,6 +651,7 @@ This checks also `vc-backend' and `vc-responsible-backend'." (make-directory default-directory) (vc-test--create-repo-function backend) + ;; Test mix of registered and unregistered files. (let* ((tmp-dir (expand-file-name "dir1/" default-directory)) (tmp-name1 (expand-file-name "foo" tmp-dir)) (tmp-name2 (expand-file-name "bar" tmp-dir)) @@ -670,7 +671,22 @@ 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 (file-exists-p new-name2))) + + ;; Test only unregistered files. + (let* ((tmp-dir (expand-file-name "dir3/" default-directory)) + (tmp-name (expand-file-name "foo" tmp-dir)) + (new-dir (expand-file-name "dir4/" default-directory)) + (new-name (expand-file-name "foo" new-dir))) + (make-directory tmp-dir) + (write-region "foo" nil tmp-name nil 'nomessage) + + (vc-rename-file (directory-file-name tmp-dir) + (directory-file-name new-dir)) + (should-not (file-exists-p tmp-name)) + (should-not (file-exists-p tmp-name)) + (should (file-exists-p new-name)) + (should (file-exists-p new-name)))) ;; Save exit. (ignore-errors