blob: c7fd666e9a4c013419eedfcd94861038e03ba14b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
;;; gitsum.el --- basic darcsum feelalike for Git
;; Copyright (C) 2008 Christian Neukirchen <purl.org/net/chneukirchen>
;; Licensed under the same terms as Emacs.
;; Version: 0.2
;; 04feb2008 +chris+
(easy-mmode-defmap gitsum-diff-mode-shared-map
'(("c" . gitsum-commit)
("u" . gitsum-undo)
("g" . gitsum-refresh))
"Basic keymap for `gitsum-diff-mode', bound to various prefix keys.")
(define-derived-mode gitsum-diff-mode diff-mode "gitsum"
"Git summary mode is for preparing patches to a Git repository.
This mode is meant to be activated by `M-x gitsum' or pressing `s' in git-status.
\\{gitsum-diff-mode-map}"
;; magic...
(lexical-let ((ro-bind (cons 'buffer-read-only gitsum-diff-mode-shared-map)))
(add-to-list 'minor-mode-overriding-map-alist ro-bind))
(setq buffer-read-only t))
(define-key gitsum-diff-mode-map (kbd "C-c C-c") 'gitsum-commit)
(define-key gitsum-diff-mode-map (kbd "C-/") 'gitsum-undo)
(define-key gitsum-diff-mode-map (kbd "C-_") 'gitsum-undo)
(define-key git-status-mode-map "s" 'gitsum)
;; Undo doesn't work in read-only buffers else.
(defun gitsum-undo ()
"Undo some previous changes.
Repeat this command to undo more changes.
A numeric argument serves as a repeat count."
(interactive)
(let ((inhibit-read-only t))
(undo)))
(defun gitsum-refresh ()
"Regenerate the patch based on the current state of the index."
(interactive)
(let ((inhibit-read-only t))
(erase-buffer)
(insert "# Directory: " default-directory "\n")
(insert "# Use n and p to navigate and k to kill a hunk. u is undo, g will refresh.\n")
(insert "# Edit the patch as you please and press 'c' to commit.\n\n")
(insert (shell-command-to-string "git diff"))
(set-buffer-modified-p nil)
(goto-char (point-min))))
(defun gitsum-commit ()
"Commit the patch as-is, asking for a commit message."
(interactive)
(shell-command-on-region (point-min) (point-max) "git apply --check --cached")
(let ((buffer (get-buffer-create "*gitsum-commit*")))
(shell-command-on-region (point-min) (point-max) "git apply --stat" buffer)
(with-current-buffer buffer
(goto-char (point-min))
(insert "\n")
(while (re-search-forward "^" nil t)
(replace-match "# " nil nil))
(goto-char (point-min)))
(log-edit 'gitsum-do-commit nil nil buffer)))
(defun gitsum-do-commit ()
"Perform the actual commit using the current buffer as log message."
(interactive)
(with-current-buffer log-edit-parent-buffer
(shell-command-on-region (point-min) (point-max)
"git apply --cached"))
(shell-command-on-region (point-min) (point-max) "git commit -F-"))
(defun gitsum ()
"Entry point into gitsum-diff-mode."
(interactive)
(switch-to-buffer (generate-new-buffer "*gitsum*"))
(gitsum-diff-mode)
(gitsum-refresh))
|