summaryrefslogtreecommitdiff
path: root/lisp/vc
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/vc')
-rw-r--r--lisp/vc/vc-git.el45
-rw-r--r--lisp/vc/vc.el46
2 files changed, 59 insertions, 32 deletions
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 8ffe41758ed..d63d755a287 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -373,8 +373,9 @@ in the order given by `git status'."
(defun vc-git-working-revision (_file)
"Git-specific version of `vc-working-revision'."
- (let (process-file-side-effects)
- (vc-git--rev-parse "HEAD")))
+ (let* ((process-file-side-effects nil)
+ (commit (vc-git--rev-parse "HEAD" t)))
+ (or (vc-git-symbolic-commit commit) commit)))
(defun vc-git--symbolic-ref (file)
(or
@@ -1638,7 +1639,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
(start-point (when branchp (vc-read-revision
(format-prompt "Start point"
(car (vc-git-branches)))
- (list dir) 'Git))))
+ (list dir) 'Git (car (vc-git-branches))))))
(and (or (zerop (vc-git-command nil t nil "update-index" "--refresh"))
(y-or-n-p "Modified files exist. Proceed? ")
(user-error (format "Can't create %s with modified files"
@@ -1677,11 +1678,15 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
;; does not (and cannot) quote.
(vc-git--rev-parse (concat rev "~1"))))
-(defun vc-git--rev-parse (rev)
+(defun vc-git--rev-parse (rev &optional short)
(with-temp-buffer
(and
- (vc-git--out-ok "rev-parse" rev)
- (buffer-substring-no-properties (point-min) (+ (point-min) 40)))))
+ (if short
+ (vc-git--out-ok "rev-parse" "--short" rev)
+ (vc-git--out-ok "rev-parse" rev))
+ (string-trim-right
+ (buffer-substring-no-properties (point-min) (min (+ (point-min) 40)
+ (point-max)))))))
(defun vc-git-next-revision (file rev)
"Git-specific version of `vc-next-revision'."
@@ -2028,19 +2033,23 @@ FILE can be nil."
(setq ok nil))))))
(and ok str)))
-(defun vc-git-symbolic-commit (commit)
- "Translate COMMIT string into symbolic form.
-Returns nil if not possible."
+(defun vc-git-symbolic-commit (commit &optional force)
+ "Translate revision string of COMMIT to a symbolic form.
+If the optional argument FORCE is non-nil, the returned value is
+allowed to include revision specifications like \"master~8\"
+\(the 8th parent of the commit currently pointed to by the master
+branch), otherwise such revision specifications are rejected, and
+the function returns nil."
(and commit
- (let ((name (with-temp-buffer
- (and
- (vc-git--out-ok "name-rev" "--name-only" commit)
- (goto-char (point-min))
- (= (forward-line 2) 1)
- (bolp)
- (buffer-substring-no-properties (point-min)
- (1- (point-max)))))))
- (and name (not (string= name "undefined")) name))))
+ (with-temp-buffer
+ (and
+ (vc-git--out-ok "name-rev" "--no-undefined" "--name-only" commit)
+ (goto-char (point-min))
+ (or force (not (looking-at "^.*[~^].*$" t)))
+ (= (forward-line 2) 1)
+ (bolp)
+ (buffer-substring-no-properties (point-min)
+ (1- (point-max)))))))
(defvar-keymap vc-dir-git-mode-map
"z c" #'vc-git-stash
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 14b149310c4..49bb7a27aad 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1926,6 +1926,13 @@ Return t if the buffer had changes, nil otherwise."
"History for `vc-read-revision'.")
(defun vc-read-revision (prompt &optional files backend default initial-input multiple)
+ "Query the user for a revision using PROMPT.
+All subsequent arguments are optional. FILES may specify a file
+set to restrict the revisions to. BACKEND is a VC backend as
+listed in `vc-handled-backends'. DEFAULT and INITIAL-INPUT are
+handled as defined by `completing-read'. If MULTIPLE is non-nil,
+the user may be prompted for multiple revisions. If possible
+this means that `completing-read-multiple' will be used."
(cond
((null files)
(let ((vc-fileset (vc-deduce-fileset t))) ;FIXME: why t? --Stef
@@ -1947,6 +1954,10 @@ Return t if the buffer had changes, nil otherwise."
answer)))))
(defun vc-read-multiple-revisions (prompt &optional files backend default initial-input)
+ "Query the user for multiple revisions.
+This is equivalent to invoking `vc-read-revision' with t for
+MULTIPLE. The arguments PROMPT, FILES, BACKEND, DEFAULT and
+INITIAL-INPUT are passed on to `vc-read-revision' directly."
(vc-read-revision prompt files backend default initial-input t))
(defun vc-diff-build-argument-list-internal (&optional fileset)
@@ -3287,10 +3298,11 @@ immediately after this one."
(apply #'vc-user-edit-command (apply old args))))))
(defcustom vc-prepare-patches-separately t
- "Non-nil means that `vc-prepare-patch' creates a single message.
-A single message is created by attaching all patches to the body
-of a single message. If nil, each patch will be sent out in a
-separate message, which will be prepared sequentially."
+ "Whether `vc-prepare-patch' should generate a separate message for each patch.
+If nil, `vc-prepare-patch' creates a single email message by attaching
+all the patches to the body of that message. If non-nil, each patch
+will be sent out in a separate message, and the messages will be
+prepared sequentially."
:type 'boolean
:safe #'booleanp
:version "29.1")
@@ -3308,7 +3320,7 @@ If nil, no default will be used. This option may be set locally."
(buffer &optional type description disposition))
(declare-function log-view-get-marked "log-view" ())
-(defun vc-default-prepare-patch (rev)
+(defun vc-default-prepare-patch (_backend rev)
(let ((backend (vc-backend buffer-file-name)))
(with-current-buffer (generate-new-buffer " *vc-default-prepare-patch*")
(vc-diff-internal
@@ -3325,15 +3337,21 @@ If nil, no default will be used. This option may be set locally."
;;;###autoload
(defun vc-prepare-patch (addressee subject revisions)
"Compose an Email sending patches for REVISIONS to ADDRESSEE.
-If `vc-prepare-patches-separately' is non-nil, SUBJECT will be used
-as the default subject for the message. Otherwise a separate
-message will be composed for each revision.
+If `vc-prepare-patches-separately' is nil, SUBJECT will be used
+as the default subject for the message (and it will be prompted
+for when called interactively). Otherwise a separate message
+will be composed for each revision, with SUBJECT derived from the
+invidividual commits.
When invoked interactively in a Log View buffer with marked
-revisions, these revisions will be used."
+revisions, those revisions will be used."
(interactive
- (let ((revs (or (log-view-get-marked)
- (vc-read-multiple-revisions "Revisions: ")))
+ (let ((revs (vc-read-multiple-revisions
+ "Revisions: " nil nil nil
+ (or (and-let* ((revs (log-view-get-marked)))
+ (mapconcat #'identity revs ","))
+ (and-let* ((file (buffer-file-name)))
+ (vc-working-revision file)))))
to)
(require 'message)
(while (null (setq to (completing-read-multiple
@@ -3357,7 +3375,8 @@ revisions, these revisions will be used."
'prepare-patch rev))
revisions)))
(if vc-prepare-patches-separately
- (dolist (patch patches)
+ (dolist (patch (reverse patches)
+ (message "Prepared %d patches..." (length patches)))
(compose-mail addressee
(plist-get patch :subject)
nil nil nil nil
@@ -3368,8 +3387,7 @@ revisions, these revisions will be used."
(insert-buffer-substring
(plist-get patch :buffer)
(plist-get patch :body-start)
- (plist-get patch :body-end)))
- (recursive-edit))
+ (plist-get patch :body-end))))
(compose-mail addressee subject nil nil nil nil
(mapcar
(lambda (p)