1 ;; sy-git.el --- A couple of nice git tools -*- Emacs-Lisp -*-
3 ;; Copyright (C) 2015 Steve Youngs
5 ;; Author: Steve Youngs <steve@sxemacs.org>
6 ;; Maintainer: Steve Youngs <steve@sxemacs.org>
7 ;; Created: <2015-07-05>
8 ;; Time-stamp: <Sunday Jul 5, 2015 15:17:44 steve>
9 ;; Homepage: http://git.sxemacs.org/slh
10 ;; Keywords: git, tools, convenience
12 ;; This file is part of SLH (Steve's Lisp Hacks).
14 ;; Redistribution and use in source and binary forms, with or without
15 ;; modification, are permitted provided that the following conditions
18 ;; 1. Redistributions of source code must retain the above copyright
19 ;; notice, this list of conditions and the following disclaimer.
21 ;; 2. Redistributions in binary form must reproduce the above copyright
22 ;; notice, this list of conditions and the following disclaimer in the
23 ;; documentation and/or other materials provided with the distribution.
25 ;; 3. Neither the name of the author nor the names of any contributors
26 ;; may be used to endorse or promote products derived from this
27 ;; software without specific prior written permission.
29 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
30 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 ;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
38 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
39 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 ;; This is the beginnings of some convenience tools to use with git
44 ;; from within SXEmacs.
46 ;; Presently, all that is here is a 'add-log' function that
47 ;; lets you write commit logs in a similar format to that of
48 ;; `add-change-log-entry'. It is globally bound to `C-x G a'.
49 ;; See: `sy-git-add-log-entry'.
53 ;; o Implement a variation of `patch-to-change-log'
54 ;; o Make it possible to call `sy-git-add-log-entry' from a diff.
57 (defun sy-git-check-hook (hook)
58 "Return non-nil when HOOK script exists and is usable.
60 By \"usable\" we mean for `sy-git-add-log-entry'."
61 (let ((hookname (file-basename hook)))
62 (when (file-exists-p hook)
64 (insert-file-contents-literally hook)
65 (goto-char (point-min))
67 ((equal hookname "commit-msg")
68 (re-search-forward (regexp-quote "sed -i '/^#/d'") nil t))
69 ((equal hookname "post-commit")
70 (re-search-forward (regexp-quote "rm -f ${LOG}") nil t))
73 (defun sy-git-add-log-entry (&optional newlog)
74 "*A wrapper for `add-change-log-entry'.
76 Optional prefix argument, NEWLOG, forces a new log file to be
77 created. Use this if you need to start over.
79 To commit your changes with the log that this function creates use:
83 This function allows you to create git commit logs in a similar format
84 to that used by `add-change-log-entry'. Some commented instructions
85 are added to the top of the log which you should either delete yourself
86 prior to committing, or have a hook do it automatically \(preferred\).
89 2 hooks will make using this function a lot simpler and automatic.
90 A 'commit-msg' hook, and a 'post-commit' hook. They reside in
96 # Delete lines beginning with '#'.
97 sed -i '/^#/d' \"$1\" || {
98 echo >&2 Commit aborted by commit-msg hook
106 # Delete log file after successful commit.
107 LOG=$(git rev-parse --show-toplevel)/++log
108 [ -f ${LOG} ] && rm -f ${LOG}
113 (let* ((topd (substring (shell-command-to-string
114 "git rev-parse --show-toplevel") 0 -1))
115 (logfile (expand-file-name "++log" topd))
116 (hookd (paths-construct-path `(,topd ".git" "hooks")))
117 (msg-hook (expand-file-name "commit-msg" hookd))
118 (commit-hook (expand-file-name "post-commit" hookd))
119 (add-log-full-name (substring (shell-command-to-string
120 "git config user.name") 0 -1))
121 (add-log-mailing-address (substring (shell-command-to-string
122 "git config user.email") 0 -1))
123 (add-log-keep-changes-together t)
125 (format-time-string "%Y-%m-%d")
127 add-log-full-name " <"
128 add-log-mailing-address ">\n"))
131 "# Copyright -- to fool `add-change-log-entry'
134 # Put your short one-line summary on the first blank line after these.
135 # Make sure that there is a blank line between your summary and the rest
136 # of your changes log.
139 (if (sy-git-check-hook msg-hook)
140 "\n# Lines beginning with '#' will be automatically deleted."
141 "\n# You MUST delete these lines before committing.")
142 (unless (sy-git-check-hook commit-hook)
143 "\n# No post-commit hook. Manually delete this log after you commit.")
146 (and current-prefix-arg ; User wants to start over
147 (file-exists-p logfile)
149 (delete-file logfile)))
150 ;; It is possible that the logfile is gone but the buffer is still
152 (and (not (file-exists-p logfile))
153 (buffer-live-p (find-buffer-visiting logfile))
154 (kill-buffer (find-buffer-visiting logfile)))
155 (with-current-buffer (find-file-noselect logfile)
157 (goto-char (point-min))
158 (when (re-search-forward "^# Copyright" (point-at-eol) t)
159 (replace-match "Copyright"))))
160 (add-change-log-entry nil logfile t nil)
162 (goto-char (point-min))
163 (delete-matching-lines (regexp-quote header))
164 (when (re-search-forward "^Copyright" (point-at-eol) t)
165 (replace-match "# Copyright"))
166 (goto-char (point-min))
167 (unless (search-forward newhead nil t)
168 (insert newhead "\n\n\n")))))
171 (global-set-key [(control x) G a] #'sy-git-add-log-entry)
174 ;;; sy-git.el ends here