"O" key-binding calls "git format-patch" from within magit. Formatted
patches may optionally be opened in mail-mode buffers to be mailed from
within Emacs.
---
magit-key-mode.el | 46 ++++++++++++++++++++++++++++++++++++++--
magit.el | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/magit-key-mode.el b/magit-key-mode.el
index 563a395..11fd093 100644
--- a/magit-key-mode.el
+++ b/magit-key-mode.el
@@ -237,8 +237,50 @@
("-h" "Use histogram diff algorithm" "--histogram")
("-b" "Ignore whitespace changes" "--ignore-space-change")
("-w" "Ignore all whitespace" "--ignore-all-space")
- ("-W" "Show surrounding functions" "--function-context"))
- ))
+ ("-W" "Show surrounding functions" "--function-context")))
+
+ (format-patch
+ (man-page "git-format-patch")
+ (actions
+ ("f" "Format patch" magit-format-patch)
+ ("e" "Open patch(es) in mail buffers" magit-format-patch-as-message))
+ ;; The following switches and arguments are not used because they
+ ;; don't seem that commonly useful to me (maybe I'm wrong).
+ ;;
+ ;; ("-n" "use [PATCH n/m] even with a single patch" "--numbered")
+ ;; ("-N" "use [PATCH] even with multiple patches" "--no-numbered")
+ ;; ("=a" "attach the patch (Boundary)" "--attach=" read-from-minibuffer)
+ ;; ("=I" "inline the patch (Boundary)" "--inline=" read-from-minibuffer)
+ ;; ("=T" "enable message threading, styles: shallow, deep"
+ ;; "--thread=" read-from-minibuffer)
+ (switches
+ ("-s" "print patches to standard out" "--stdout")
+ ("-S" "add Signed-off-by:" "--signoff")
+ ("-C" "generate a cover letter" "--cover-letter")
+ ("-n" "use simple number sequence for output file names"
+ "--numbered-files")
+ ("-k" "don't strip/add [PATCH]" "--keep-subject")
+ ("-B" "don't output binary diffs" "--no-binary")
+ ("-i" "don't include a patch matching a commit upstream"
+ "--ignore-if-in-upstream")
+ ("-p" "show patch format instead of default (patch + stat)" "--no-stat"))
+ (arguments
+ ("=o" "store resulting files in <dir>" "--output-directory="
+ read-directory-name)
+ ("=v" "mark the series as Nth re-roll" "--reroll-count="
+ read-number)
+ ("=P" "Use [<prefix>] instead of [PATCH]" "--subject-prefix="
+ read-from-minibuffer)
+ ("=N" "start numbering patches at <n> instead of 1" "--start-number="
+ read-number)
+ ("=S" "Signature" "--signature=" read-from-minibuffer)
+ ("=h" "add email header" "--add-header=" read-from-minibuffer)
+ ("=t" "add To: header" "--to=" read-from-minibuffer)
+ ("=c" "add Cc: header" "--cc=" read-from-minibuffer)
+ ("=f" "set From address to <ident>" "--from=" read-from-minibuffer)
+ ("=r" "make first mail a reply to <message-id>" "--in-reply-to="
+ read-from-minibuffer)))
+ )
"Holds the key, help, function mapping for the log-mode.
If you modify this make sure you reset `magit-key-mode-keymaps'
to nil.")
diff --git a/magit.el b/magit.el
index 163878d..b7cf553 100644
--- a/magit.el
+++ b/magit.el
@@ -924,6 +924,7 @@ face inherit from `default' and remove all other
attributes."
(define-key map (kbd "t") 'magit-tag)
(define-key map (kbd "l") 'magit-log)
(define-key map (kbd "o") 'magit-submodule-update)
+ (define-key map (kbd "O") 'magit-format-patch)
(define-key map (kbd "B") 'undefined))
(t
(define-key map (kbd "c") 'magit-key-mode-popup-committing)
@@ -938,6 +939,7 @@ face inherit from `default' and remove all other
attributes."
(define-key map (kbd "t") 'magit-key-mode-popup-tagging)
(define-key map (kbd "l") 'magit-key-mode-popup-logging)
(define-key map (kbd "o") 'magit-key-mode-popup-submodule)
+ (define-key map (kbd "O") 'magit-key-mode-popup-format-patch)
(define-key map (kbd "B") 'magit-key-mode-popup-bisecting)))
(define-key map (kbd "$") 'magit-display-process)
(define-key map (kbd "E") 'magit-interactive-rebase)
@@ -2999,6 +3001,67 @@ With a prefix argument, kill the buffer instead."
,@(unless magit-status-verbose-untracked
'("--directory"))))))
+;;; Format Patches and Send Messages
+(defun magit-mail-from-patch (patches)
+ (require 'sendmail)
+ (let* ((headers-end (or (string-match "^$" patches)
+ (error "missing patch delimiter")))
+ (patch-end (string-match "^From " patches headers-end))
+ (patch (substring patches 0 patch-end))
+ (marker 0)
+ headers)
+ ;; collect email fields for transfer to the mail buffer
+ (while (string-match "^\\([[:alpha:]]+\\): \\([^\n]+\\)"
+ patch marker)
+ (setf marker (match-end 0))
+ (push (cons (intern (downcase (match-string 1 patch)))
+ (match-string 2 patch))
+ headers))
+ ;; open the mail buffer with collected fields
+ (mail nil
+ (cdr (assoc 'to headers))
+ (cdr (assoc 'subject headers))
+ (cdr (assoc 'in-reply-to headers))
+ (cdr (assoc 'cc headers))
+ nil
+ ;; after sending send any subsequent messages
+ (when patch-end
+ `(((lambda (buf)
+ ;; set as not modified to avoid user prompt
+ (pop-to-buffer buf)
+ (set-buffer-modified-p nil)) "*mail*")
+ (magit-mail-from-patch ,(substring patches patch-end)))))
+ (mail-text)
+ (save-excursion (insert (substring patch headers-end)))
+ ;; use this instead of `mail-send-and-exit' to keep this buffer on top
+ (when patch-end
+ (local-set-key (kbd "C-c C-c") 'mail-send))))
+
+(defun magit-format-patch (&optional as-message)
+ "Format Patches and write to disk or view in magit."
+ (interactive "P")
+ (let* ((since (magit-read-rev-with-default "since: "))
+ (output (apply #'magit-git-string "format-patch"
+ (append magit-custom-options (list since)))))
+ (cond
+ (as-message (magit-mail-from-patch output))
+ ((member "--stdout" magit-custom-options)
+ (with-current-buffer (find-file-noselect (magit-git-dir "FORMAT_PATCH"))
+ (funcall (if (functionp magit-server-window-for-commit)
+ magit-server-window-for-commit
+ 'switch-to-buffer)
+ (current-buffer))
+ (delete-region (point-min) (point-max))
+ (insert output)
+ (goto-char (point-min))))
+ (t (message "%s" output)))))
+
+(defun magit-format-patch-as-message ()
+ "Format Patches and open the results in a message buffer."
+ (interactive)
+ (cl-pushnew "--stdout" magit-custom-options)
+ (magit-format-patch 'as-message))
+
;;; Diffs and Hunks
(defvar magit-diff-context-lines 3)
--
1.8.4
--
---
You received this message because you are subscribed to the Google Groups
"magit" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.