emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r110330: Support git commit --amend/-


From: Dmitry Gutov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110330: Support git commit --amend/--signoff
Date: Tue, 02 Oct 2012 04:24:18 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110330
committer: Dmitry Gutov <address@hidden>
branch nick: trunk
timestamp: Tue 2012-10-02 04:24:18 +0400
message:
  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.
modified:
  lisp/ChangeLog
  lisp/vc/log-edit.el
  lisp/vc/vc-git.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-10-01 18:10:29 +0000
+++ b/lisp/ChangeLog    2012-10-02 00:24:18 +0000
@@ -1,3 +1,17 @@
+2012-10-01  Dmitry Gutov  <address@hidden>
+
+       * 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  <address@hidden>
 
        * emacs-lisp/eieio-opt.el (eieio-describe-class): Add filename

=== modified file 'lisp/vc/log-edit.el'
--- a/lisp/vc/log-edit.el       2012-09-30 03:30:25 +0000
+++ b/lisp/vc/log-edit.el       2012-10-02 00:24:18 +0000
@@ -341,7 +341,7 @@
 (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 @@
       (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 @@
                                   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)

=== modified file 'lisp/vc/vc-git.el'
--- a/lisp/vc/vc-git.el 2012-09-17 05:41:04 +0000
+++ b/lisp/vc/vc-git.el 2012-10-02 00:24:18 +0000
@@ -608,16 +608,52 @@
 (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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]