Commit 9f7b98f8 authored by Dmitry Gutov's avatar Dmitry Gutov
Browse files

Support git commit --amend/--signoff

* lisp/vc/log-edit.el (log-edit-font-lock-keywords): Allow hyphens in
header names.
(log-edit-toggle-header): New function.
(log-edit-extract-headers): Accept function values in HEADERS alist.

* lisp/vc/vc-git.el (vc-git-log-edit-toggle-signoff): New function.
(vc-git-log-edit-toggle-amend): New function.
(vc-git-log-edit-toggle-signoff): New function.
(vc-git-log-edit-mode): New major mode.
(vc-git-log-edit-mode-map): Keymap for it.
(vc-git-checkin): Handle "Amend" and "Sign-Off" headers.
parent 81550bf4
2012-10-01 Dmitry Gutov <dgutov@yandex.ru>
* vc/vc-git.el (vc-git-log-edit-toggle-signoff): New function.
(vc-git-log-edit-toggle-amend): New function.
(vc-git-log-edit-toggle-signoff): New function.
(vc-git-log-edit-mode): New major mode.
(vc-git-log-edit-mode-map): Keymap for it.
(vc-git-checkin): Handle "Amend" and "Sign-Off" headers.
* vc/log-edit.el (log-edit-font-lock-keywords): Allow hyphens in
header names.
(log-edit-toggle-header): New function.
(log-edit-extract-headers): Accept function values in HEADERS alist.
2012-10-01 David Engster <deng@randomsample.de>
 
* emacs-lisp/eieio-opt.el (eieio-describe-class): Add filename
......
......@@ -341,7 +341,7 @@ automatically."
(defvar log-edit-font-lock-keywords
;; Copied/inspired by message-font-lock-keywords.
`((log-edit-match-to-eoh
(,(concat "^\\(\\([[:alpha:]]+\\):\\)" log-edit-header-contents-regexp)
(,(concat "^\\(\\([[:alpha:]-]+\\):\\)" log-edit-header-contents-regexp)
(progn (goto-char (match-beginning 0)) (match-end 0)) nil
(1 (if (assoc-string (match-string 2) log-edit-headers-alist t)
'log-edit-header
......@@ -900,14 +900,44 @@ Rename relative filenames in the ChangeLog entry as FILES."
(insert "\n"))
log-edit-author))
(defun log-edit-toggle-header (header value)
"Toggle a boolean-type header in the current buffer.
If the value of HEADER is VALUE, clear it. Otherwise, add the
header if it's not present and set it to VALUE. Then make sure
there is an empty line after the headers. Return t if toggled
on, otherwise nil."
(let ((val t)
(line (concat header ": " value "\n")))
(save-excursion
(save-restriction
(rfc822-goto-eoh)
(narrow-to-region (point-min) (point))
(goto-char (point-min))
(if (re-search-forward (concat "^" header ":"
log-edit-header-contents-regexp)
nil t)
(if (setq val (not (string= (match-string 1) value)))
(replace-match line t t)
(replace-match "" t t nil 1))
(insert line)))
(rfc822-goto-eoh)
(delete-horizontal-space)
(unless (looking-at "\n")
(insert "\n")))
val))
(defun log-edit-extract-headers (headers comment)
"Extract headers from COMMENT to form command line arguments.
HEADERS should be an alist with elements of the form (HEADER . CMDARG)
associating header names to the corresponding cmdline option name and the
result is then a list of the form (MSG CMDARG1 HDRTEXT1 CMDARG2 HDRTEXT2...).
where MSG is the remaining text from STRING.
If \"Summary\" is not in HEADERS, then the \"Summary\" header is extracted
anyway and put back as the first line of MSG."
HEADERS should be an alist with elements (HEADER . CMDARG)
or (HEADER . FUNCTION) associating headers to command line
options and the result is then a list of the form (MSG ARGUMENTS...)
where MSG is the remaining text from COMMENT.
FUNCTION should be a function of one argument that takes the
header value and returns the list of strings to be appended to
ARGUMENTS. CMDARG will be added to ARGUMENTS followed by the
header value. If \"Summary\" is not in HEADERS, then the
\"Summary\" header is extracted anyway and put back as the first
line of MSG."
(with-temp-buffer
(insert comment)
(rfc822-goto-eoh)
......@@ -923,8 +953,10 @@ anyway and put back as the first line of MSG."
nil t)
(if (eq t (cdr header))
(setq summary (match-string 1))
(push (match-string 1) res)
(push (or (cdr header) (car header)) res))
(if (functionp (cdr header))
(setq res (nconc res (funcall (cdr header) (match-string 1))))
(push (match-string 1) res)
(push (or (cdr header) (car header)) res)))
(replace-match "" t t)))
;; Remove header separator if the header is empty.
(widen)
......
......@@ -608,16 +608,52 @@ The car of the list is the current branch."
(defun vc-git-unregister (file)
(vc-git-command nil 0 file "rm" "-f" "--cached" "--"))
(declare-function log-edit-mode "log-edit" ())
(declare-function log-edit-toggle-header "log-edit" (header value))
(declare-function log-edit-extract-headers "log-edit" (headers string))
(defun vc-git-log-edit-toggle-signoff ()
"Toggle whether to add the \"Signed-off-by\" line at the end of
the commit message."
(interactive)
(log-edit-toggle-header "Sign-Off" "yes"))
(defun vc-git-log-edit-toggle-amend ()
"Toggle whether this will amend the previous commit.
If toggling on, also insert its message into the buffer."
(interactive)
(when (log-edit-toggle-header "Amend" "yes")
(goto-char (point-max))
(unless (bolp) (insert "\n"))
(insert (with-output-to-string
(vc-git-command
standard-output 1 nil
"log" "--max-count=1" "--pretty=format:%B" "HEAD")))))
(defvar vc-git-log-edit-mode-map
(let ((map (make-sparse-keymap "Git-Log-Edit")))
(define-key map "\C-c\C-s" 'vc-git-log-edit-toggle-signoff)
(define-key map "\C-c\C-e" 'vc-git-log-edit-toggle-amend)
map))
(define-derived-mode vc-git-log-edit-mode log-edit-mode "Log-Edit/git"
"Major mode for editing Git log messages.
It is based on `log-edit-mode', and has Git-specific extensions.")
(defun vc-git-checkin (files _rev comment)
(let ((coding-system-for-write vc-git-commits-coding-system))
(apply 'vc-git-command nil 0 files
(nconc (list "commit" "-m")
(log-edit-extract-headers '(("Author" . "--author")
("Date" . "--date"))
comment)
(list "--only" "--")))))
(cl-flet ((boolean-arg-fn
(argument)
(lambda (value) (when (equal value "yes") (list argument)))))
(apply 'vc-git-command nil 0 files
(nconc (list "commit" "-m")
(log-edit-extract-headers
`(("Author" . "--author")
("Date" . "--date")
("Amend" . ,(boolean-arg-fn "--amend"))
("Sign-Off" . ,(boolean-arg-fn "--signoff")))
comment)
(list "--only" "--"))))))
(defun vc-git-find-revision (file rev buffer)
(let* (process-file-side-effects
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment