From fb5cb413c28e73fafa296c962cf92b25e0e78dc1 Mon Sep 17 00:00:00 2001 From: yoctocell Date: Mon, 4 Jan 2021 23:05:34 +0100 Subject: Add wrapper for 'git-format-patch' This lets the user generate patches and automatically compses an email for each patch. * git-email.el (git-email-format-patch-default-args): (git-email-format-patch-extra-args): (git-email-format-patch): --- git-email.el | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'git-email.el') diff --git a/git-email.el b/git-email.el index c5ee138..441a097 100644 --- a/git-email.el +++ b/git-email.el @@ -37,9 +37,6 @@ ;;; TODO: ;; * Add proper syntax highlighting to diffs in the message buffer. -;; -;; * Add wrapper for 'git format-patch' that automatically marks the -;; the newly generated patch files. ;;; Code: @@ -73,6 +70,17 @@ in you git config. If the variable is not set, the 'to' address will be empty." :group 'git-email :type '(symbol)) +(defcustom git-email-format-patch-default-args "" + "Default arguments to give to 'git format-patch'." + :type 'string + :group 'git-email) + +(defcustom git-email-format-patch-extra-args + '("--cover-letter" "--thread" "--output-directory" "--signoff" "--to") + "List of arguments to display in `git-email-format-patch'." + :type '(string) + :group 'git-email) + (defun git-email--extract-header (header) "Extract HEADER from current buffer." (goto-char (point-min)) @@ -146,6 +154,46 @@ If no marks are found, return the filename at point." (git-email--compose-email file) (run-hooks 'git-email-post-compose-email-hook)))) +;;;###autoload +(defun git-email-format-patch (&optional args) + "Format and send patch(es) using 'git format-patch'. +With optional ARGS (\\[universal-argument]) you can specify extra +arguments to give to 'git format-patch'. By default, the +arguments in `git-email-format-patch-default-args' will be used." + (interactive "P") + (let* ((default-directory (cdr (project-current))) + (revs (split-string (shell-command-to-string + "git log --format='%h %d %s'") + "\n")) + ;; Sort the candidates correctly. + ;; See https://emacs.stackexchange.com/a/41808. + (sorted-revs + (lambda (string pred action) + (if (eq action 'metadata) + '(metadata (display-sort-function . identity) + (cycle-sort-function . identity)) + (complete-with-action + action revs string pred)))) + (rev (substring (completing-read "Revision: " sorted-revs) 0 7)) + ;; Extra arguments. + (args (if args + (apply + #'concat (mapcar + (lambda (a) (concat a " ")) + (list (completing-read-multiple + "Args: " + git-email-format-patch-extra-args)))) + git-email-format-patch-default-args)) + ;; List of patches generated, the last element is an empty string + ;; so remove it. Reverse the list so we edit the cover letter first. + (files (nreverse (butlast (split-string (shell-command-to-string + (concat "git format-patch " args " " rev)) + "\n"))))) + (dolist (file files) + (run-hooks 'git-email-pre-compose-email-hook) + (git-email--compose-email file) + (run-hooks 'git-email-post-compose-email-hook)))) + (defun git-email--remove-subject (header) "Remove HEADER if it is the subject." (not (string-equal (symbol-name (car header)) "subject"))) -- cgit v1.2.3