From 97de6ae2b6e63a94768f982c09268e42f92344a9 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 18 Jul 2025 14:53:43 +0100 Subject: [PATCH] VC: Tighten up switching branches * lisp/vc/vc.el: Require backend 'create-tag' functions to prompt for the starting point of the branch. (vc-retrieve-tag, vc-switch-branch): Accept empty NAME only when not switching branches: it doesn't make sense to switch to the current branch. Plain 'C-x v r' can still be used to check out the latest revisions on the current branch. (cherry picked from commit 0ac1fe8d73ba83164c564bc579f3387d39856f31) --- lisp/vc/vc.el | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index e591f527be2..dc18c048ffb 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -488,11 +488,14 @@ ;; ;; Attach the tag NAME to the state of the working copy. This ;; should make sure that files are up-to-date before proceeding with -;; the action. DIR can also be a file and if BRANCHP is specified, +;; the action. DIR can also be a file and if BRANCHP is non-nil, ;; NAME should be created as a branch and DIR should be checked out -;; under this new branch. The default implementation does not -;; support branches but does a sanity check, a tree traversal and -;; assigns the tag to each file. +;; under this new branch. Where it makes sense with the underlying +;; VCS, should prompt for a branch or tag from which to start/fork the +;; new branch, with completion candidates including all the known +;; branches and tags of the repository. The default implementation +;; does not support branches but does a sanity check, a tree traversal +;; and assigns the tag to each file. ;; ;; - retrieve-tag (dir name update) ;; @@ -3001,6 +3004,7 @@ locked files at or below DIR (but if NAME is empty, locked files are allowed and simply skipped). If BRANCHP is non-nil (interactively, the prefix argument), switch to the branch and check out and update the files to their version on that branch. +In this case NAME may not be empty. This function runs the hook `vc-retrieve-tag-hook' when finished." (interactive (let* ((granularity @@ -3014,16 +3018,16 @@ This function runs the hook `vc-retrieve-tag-hook' when finished." ;; file-in-directory-p inside vc-resynch-buffers-in-directory. (expand-file-name (vc-root-dir)) (read-directory-name "Directory: " default-directory nil t)))) - (list - dir - (vc-read-revision (format-prompt - (if current-prefix-arg - "Switch to branch" - "Tag name to retrieve") - "latest revisions") - (list dir) - (vc-responsible-backend dir)) - current-prefix-arg))) + (list dir + (vc-read-revision (if current-prefix-arg + "Switch to branch: " + (format-prompt "Tag name to retrieve" + "latest revisions")) + (list dir) + (vc-responsible-backend dir)) + current-prefix-arg))) + (unless (or (not branchp) (and name (not (string-empty-p name)))) + (user-error "Branch name required")) (let* ((backend (vc-responsible-backend dir)) (update (when (vc-call-backend backend 'update-on-retrieve-tag) (yes-or-no-p "Update any affected buffers? "))) @@ -3041,7 +3045,6 @@ This function runs the hook `vc-retrieve-tag-hook' when finished." ;;;###autoload (defun vc-switch-branch (dir name) "Switch to the branch NAME in the directory DIR. -If NAME is empty, it refers to the latest revision of the current branch. Interactively, prompt for DIR only for VCS that works at file level; otherwise use the root directory of the current buffer's VC tree. Interactively, prompt for the NAME of the branch. @@ -3056,11 +3059,10 @@ Uses `vc-retrieve-tag' with the non-nil arg `branchp'." (if (eq granularity 'repository) (expand-file-name (vc-root-dir)) (read-directory-name "Directory: " default-directory nil t)))) - (list - dir - (vc-read-revision (format-prompt "Switch to branch" "latest revisions") - (list dir) - (vc-responsible-backend dir))))) + (list dir + (vc-read-revision "Switch to branch: " + (list dir) + (vc-responsible-backend dir))))) (vc-retrieve-tag dir name t)) ;; Miscellaneous other entry points -- 2.39.5