vc-rename-file: Fix case of directory with only untracked files

* lisp/vc/vc.el (vc-rename-file): Don't call into the backend if
moving a directory containing only untracked files.
* test/lisp/vc/vc-tests/vc-tests.el (vc-test--rename-directory):
New test for this case.
This commit is contained in:
Sean Whitton 2026-04-15 17:59:10 -04:00
parent 324e5b4177
commit 5045394694
2 changed files with 28 additions and 5 deletions

View file

@ -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)

View file

@ -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