]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve prompting for git stashes
authorSean Whitton <spwhitton@spwhitton.name>
Tue, 29 Oct 2024 11:55:08 +0000 (19:55 +0800)
committerEshel Yaron <me@eshelyaron.com>
Fri, 1 Nov 2024 13:17:27 +0000 (14:17 +0100)
* lisp/vc/vc-git.el (vc-git-stash-read): New DEFAULT-MOST-RECENT
optional argument.  Use format-prompt.  Signal user-error
immediately if there are no stashes.  Rewrite docstring.
(vc-git-stash-show, vc-git-stash-apply, vc-git-stash-pop)
(vc-git-stash-delete): Drop trailing ": " from prompts.
(vc-git-stash-pop): Pass non-nil DEFAULT-MOST-RECENT to
vc-git-stash-read.

(cherry picked from commit 90ffe8a36b16801eaf0ca9b0ffca07156cf3c26d)

lisp/vc/vc-git.el

index 7a7646fa3126138bf217ee72beed828f2a85a63e..68e2c885dc8b2fcdc53d4ab95d2c14ca881e125d 100644 (file)
@@ -2202,21 +2202,29 @@ In other modes, call `vc-deduce-fileset' to determine files to stash."
 (defvar vc-git-stash-read-history nil
   "History for `vc-git-stash-read'.")
 
-(defun vc-git-stash-read (prompt)
-  "Read a Git stash.  PROMPT is a string to prompt with."
-  (let ((stash (completing-read
-                 prompt
-                 (split-string
-                  (or (vc-git--run-command-string nil "stash" "list") "") "\n" t)
-                 nil :require-match nil 'vc-git-stash-read-history)))
-    (if (string-equal stash "")
-        (user-error "Not a stash")
-      (string-match "^stash@{[[:digit:]]+}" stash)
-      (match-string 0 stash))))
+(defun vc-git-stash-read (prompt &optional default-most-recent)
+  "Prompt the user, with PROMPT, to select a git stash.
+PROMPT is passed to `format-prompt'.  If DEFAULT-MOST-RECENT is non-nil,
+then the most recently pushed stash is the default selection."
+  (if-let* ((stashes
+             (split-string (vc-git--run-command-string nil
+                                                       "stash" "list")
+                           "\n" t)))
+      (let* ((default (and default-most-recent (car stashes)))
+             (prompt (format-prompt prompt default))
+             (stash (completing-read prompt stashes
+                                     nil :require-match nil
+                                     'vc-git-stash-read-history
+                                     default)))
+        (if (string-equal stash "")
+            (user-error "Not a stash")
+          (string-match "^stash@{[[:digit:]]+}" stash)
+          (match-string 0 stash)))
+    (user-error "No stashes")))
 
 (defun vc-git-stash-show (name)
   "Show the contents of stash NAME."
-  (interactive (list (vc-git-stash-read "Show stash")))
+  (interactive (list (vc-git-stash-read "Show stash")))
   (vc-setup-buffer "*vc-git-stash*")
   (vc-git-command "*vc-git-stash*" 'async nil
                   "stash" "show" "--color=never" "-p" name)
@@ -2227,19 +2235,21 @@ In other modes, call `vc-deduce-fileset' to determine files to stash."
 
 (defun vc-git-stash-apply (name)
   "Apply stash NAME."
-  (interactive (list (vc-git-stash-read "Apply stash")))
+  (interactive (list (vc-git-stash-read "Apply stash")))
   (vc-git-command "*vc-git-stash*" 0 nil "stash" "apply" "-q" name)
   (vc-resynch-buffer (vc-git-root default-directory) t t))
 
 (defun vc-git-stash-pop (name)
   "Pop stash NAME."
-  (interactive (list (vc-git-stash-read "Pop stash: ")))
+  ;; Stashes are commonly popped off in reverse order, so pass non-nil
+  ;; DEFAULT-MOST-RECENT to `vc-git-stash-read'.
+  (interactive (list (vc-git-stash-read "Pop stash" t)))
   (vc-git-command "*vc-git-stash*" 0 nil "stash" "pop" "-q" name)
   (vc-resynch-buffer (vc-git-root default-directory) t t))
 
 (defun vc-git-stash-delete (name)
   "Delete stash NAME."
-  (interactive (list (vc-git-stash-read "Delete stash")))
+  (interactive (list (vc-git-stash-read "Delete stash")))
   (vc-git-command "*vc-git-stash*" 0 nil "stash" "drop" "-q" name)
   (vc-resynch-buffer (vc-git-root default-directory) t t))