Fix renaming whole directories with Mercurial

* lisp/vc/vc-hg.el (vc-hg-rename-file): Use 'hg mv --after'.
* test/lisp/vc/vc-tests/vc-tests.el (vc-test--rename-directory):
New test.
This commit is contained in:
Sean Whitton
2026-04-15 10:06:48 -04:00
parent 0ea1c0d831
commit 43f0da207e
2 changed files with 70 additions and 3 deletions

View File

@@ -1189,10 +1189,13 @@ Should be called with DEFAULT-DIRECTORY equal to the repository root."
(file-error nil)))
(vc-hg-command nil 0 files "remove" "--after" "--force"))
;; Modeled after the similar function in vc-bzr.el
(defun vc-hg-rename-file (old new)
"Rename file from OLD to NEW using `hg mv'."
(vc-hg-command nil 0 (expand-file-name new) "mv"
;; Do the rename ourselves then update hg. Otherwise only registered
;; files are moved. ('git mv' moves both registered and unregistered
;; files which seems more useful.)
(rename-file old new)
(vc-hg-command nil 0 (expand-file-name new) "mv" "--after"
(expand-file-name old)))
(defun vc-hg-register (files &optional _comment)

View File

@@ -624,6 +624,54 @@ This checks also `vc-backend' and `vc-responsible-backend'."
(ignore-errors
(run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--rename-directory (backend)
"Check the rename-file action for directories."
(ert-with-temp-directory tempdir
(let ((vc-handled-backends `(,backend))
(default-directory
(file-name-as-directory
(expand-file-name
(make-temp-name "vc-test") temporary-file-directory)))
(process-environment process-environment)
vc-test--cleanup-hook)
(vc--fix-home-for-bzr tempdir)
(unwind-protect
(progn
;; Cleanup.
(add-hook
'vc-test--cleanup-hook
(let ((dir default-directory))
(lambda () (delete-directory dir 'recursive))))
;; Create empty repository.
(make-directory default-directory)
(vc-test--create-repo-function backend)
(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))
(new-dir (expand-file-name "dir2/" default-directory))
(new-name1 (expand-file-name "foo" new-dir))
(new-name2 (expand-file-name "bar" new-dir)))
(make-directory tmp-dir)
(write-region "foo" nil tmp-name1 nil 'nomessage)
(write-region "bar" nil tmp-name2 nil 'nomessage)
;; Register TMP-NAME1 but *not* TMP-NAME2.
(vc-register `(,backend
(,(file-relative-name tmp-name1
default-directory))))
(vc-rename-file (directory-file-name tmp-dir)
(directory-file-name new-dir))
(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))))
;; Save exit.
(ignore-errors
(run-hooks 'vc-test--cleanup-hook))))))
(defvar vc-hg-global-switches)
(defmacro vc-test--with-author-identity (backend &rest body)
@@ -1222,7 +1270,23 @@ This checks also `vc-backend' and `vc-responsible-backend'."
',(intern
(format "vc-test-%s01-register" backend-string))))))
(skip-unless (memq ',backend '(Git Hg)))
(vc-test--checkin-patch ',backend))))))
(vc-test--checkin-patch ',backend))
(ert-deftest
,(intern (format "vc-test-%s10-rename-directory" backend-string)) ()
,(format "Check `vc-rename-file' with directories for the %s backend."
backend-string)
(skip-unless
(ert-test-passed-p
(ert-test-most-recent-result
(ert-get-test
',(intern
(format "vc-test-%s01-register" backend-string))))))
;; See vc-test-*-rename-file regarding CVS and Mtn.
;; SVN requires all files to rename are registered but we want
;; to test a mix of registered and unregistered files in this test.
(skip-when (memq ',backend '(CVS SVN Mtn)))
(vc-test--rename-directory ',backend))))))
(provide 'vc-tests)
;;; vc-tests.el ends here