emacs-devel
[Top][All Lists]
Advanced

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

Re: support for git commit --amend/--signoff


From: Dan Nicolaescu
Subject: Re: support for git commit --amend/--signoff
Date: Sat, 19 Jun 2010 02:38:46 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>> We could have a log-edit-extra-flags function that computes a set of
>> extra flags, and pass those flags to vc-git-checkin.
>
> If amend is triggered from a new command (like vc-amend), then there's no
> need for any special support in log-edit.  We could easily store the
> relevant info in log-edit-callback or in vc-specific
> buffer-local variables.

The problem with that is that vc-amend does not integrate very well
with C-x v v and it is very Git specific, and given the reluctance of
some other VCs to change history, it does not seem that it will be
generalized.
More, it does not solve the problem of --signoff (which might be adopted by 
other VCs).

Here's a solution that takes care of all problems and it is extensible.
I adds one line to log-edit.el and two to vc.el.
vc-git-log-edit-get-extra-flags-function does the work in vc-git.el



=== modified file 'lisp/vc/log-edit.el'
--- lisp/vc/log-edit.el 2010-06-12 17:14:43 +0000
+++ lisp/vc/log-edit.el 2010-06-16 17:37:47 +0000
@@ -189,6 +189,7 @@ when this variable is set to nil.")
 (defvar log-edit-callback nil)
 (defvar log-edit-diff-function nil)
 (defvar log-edit-listfun nil)
+(defvar log-edit-get-extra-flags-function nil)
 
 (defvar log-edit-parent-buffer nil)
 

=== modified file 'lisp/vc/vc.el'
--- lisp/vc/vc.el       2010-06-11 19:09:57 +0000
+++ lisp/vc/vc.el       2010-06-16 19:09:37 +0000
@@ -1398,7 +1406,9 @@ Runs the normal hooks `vc-before-checkin
           ;; vc-checkin-switches, but 'the' local buffer is
           ;; not a well-defined concept for filesets.
           (progn
-            (vc-call-backend backend 'checkin files rev comment)
+            (vc-call-backend backend 'checkin files rev comment
+                            (when log-edit-get-extra-flags-function
+                              (funcall log-edit-get-extra-flags-function)))
             (mapc 'vc-delete-automatic-version-backups files))
           `((vc-state . up-to-date)
             (vc-checkout-time . ,(nth 5 (file-attributes file)))

=== modified file 'lisp/vc/vc-annotate.el'
=== modified file 'lisp/vc/vc-bzr.el'
=== modified file 'lisp/vc/vc-git.el'
--- lisp/vc/vc-git.el   2010-06-11 19:09:57 +0000
+++ lisp/vc/vc-git.el   2010-06-16 18:10:00 +0000
@@ -550,13 +550,65 @@ or an empty string if none."
 
 (declare-function log-edit-extract-headers "log-edit" (headers string))
 
-(defun vc-git-checkin (files rev comment)
+(defvar vc-git-log-edit-signoff nil)
+
+(defvar vc-git-log-edit-amend nil)
+
+(defun vc-git-log-edit-toggle-signoff ()
+  (interactive)
+  (setq vc-git-log-edit-signoff (not vc-git-log-edit-signoff)))
+
+(defun vc-git-log-edit-toggle-amend ()
+  (interactive)
+  (unless vc-git-log-edit-amend
+    (vc-git-command (current-buffer) 1 nil
+                   "log" "--max-count=1" "--pretty=format:%s" "HEAD"))
+  (setq vc-git-log-edit-amend (not vc-git-log-edit-amend)))
+
+(defvar vc-git-log-edit-map
+  (let ((map (make-sparse-keymap "Git-Log-Edit"))
+       (menu-map (make-sparse-keymap)))
+
+    ;; FIXME: Are these key bindings OK?
+    (define-key map "\C-c\C-s" 'vc-git-log-edit-toggle-signoff)
+    (define-key map "\C-c\C-m" 'vc-git-log-edit-toggle-amend)
+
+    ;; FIXME: This does not work.  And it would be better if we could
+    ;; add items to the Log-Edit menu.
+    (define-key map [menu-bar vc-git-log-edit] (cons "Git-Log-Edit" menu-map))
+    (define-key menu-map [ts]
+      '(menu-item "Signoff" vc-git-log-edit-toggle-signoff
+                 :help "Toggle signoff"
+                 :button (:toggle . vc-git-log-edit-signoff)))
+    (define-key menu-map [ta]
+      '(menu-item "Amend" vc-git-log-edit-toggle-amend
+                 :help "Toggle amend, insert old log when turning it on"
+                 :button (:toggle . vc-git-log-edit-amend)))
+    map))
+
+(define-derived-mode vc-git-log-edit-mode log-edit-mode "*VC-log*"
+  "Major mode for editing Git log messages.
+It is based on `log-edit-mode', it has Git specific extensions."
+  (set (make-local-variable 'log-edit-get-extra-flags-function)
+       'vc-git-log-edit-get-extra-flags-function)
+  (make-local-variable 'vc-git-log-edit-signoff)
+  (make-local-variable 'vc-git-log-edit-amend))
+
+(defun vc-git-log-edit-get-extra-flags-function ()
+  (let (result)
+    (when vc-git-log-edit-amend
+      (push "--amend" result))
+    (when vc-git-log-edit-signoff
+      (push "--signoff" result))))
+
+(defun vc-git-checkin (files rev comment &optional extra-flags)
   (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)
+                 extra-flags
                   (list "--only" "--")))))
 
 (defun vc-git-find-revision (file rev buffer)




reply via email to

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