--- /dev/null
+;; sy-git.el --- A couple of nice git tools -*- Emacs-Lisp -*-
+
+;; Copyright (C) 2015 Steve Youngs
+
+;; Author: Steve Youngs <steve@sxemacs.org>
+;; Maintainer: Steve Youngs <steve@sxemacs.org>
+;; Created: <2015-07-05>
+;; Time-stamp: <Sunday Jul 5, 2015 15:17:44 steve>
+;; Homepage: http://git.sxemacs.org/slh
+;; Keywords: git, tools, convenience
+
+;; This file is part of SLH (Steve's Lisp Hacks).
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; This is the beginnings of some convenience tools to use with git
+;; from within SXEmacs.
+;;
+;; Presently, all that is here is a 'add-log' function that
+;; lets you write commit logs in a similar format to that of
+;; `add-change-log-entry'. It is globally bound to `C-x G a'.
+;; See: `sy-git-add-log-entry'.
+
+;;; Todo:
+;;
+;; o Implement a variation of `patch-to-change-log'
+;; o Make it possible to call `sy-git-add-log-entry' from a diff.
+
+;;; Code:
+(defun sy-git-check-hook (hook)
+ "Return non-nil when HOOK script exists and is usable.
+
+By \"usable\" we mean for `sy-git-add-log-entry'."
+ (let ((hookname (file-basename hook)))
+ (when (file-exists-p hook)
+ (with-temp-buffer
+ (insert-file-contents-literally hook)
+ (goto-char (point-min))
+ (cond
+ ((equal hookname "commit-msg")
+ (re-search-forward (regexp-quote "sed -i '/^#/d'") nil t))
+ ((equal hookname "post-commit")
+ (re-search-forward (regexp-quote "rm -f ${LOG}") nil t))
+ (t nil))))))
+
+(defun sy-git-add-log-entry (&optional newlog)
+ "*A wrapper for `add-change-log-entry'.
+
+Optional prefix argument, NEWLOG, forces a new log file to be
+created. Use this if you need to start over.
+
+To commit your changes with the log that this function creates use:
+
+ git commit -F ++log
+
+This function allows you to create git commit logs in a similar format
+to that used by `add-change-log-entry'. Some commented instructions
+are added to the top of the log which you should either delete yourself
+prior to committing, or have a hook do it automatically \(preferred\).
+
+Hooks:
+2 hooks will make using this function a lot simpler and automatic.
+A 'commit-msg' hook, and a 'post-commit' hook. They reside in
+'$repo/.git/hooks/'.
+
+Example commit-msg:
+
+ #!/bin/sh
+ # Delete lines beginning with '#'.
+ sed -i '/^#/d' \"$1\" || {
+ echo >&2 Commit aborted by commit-msg hook
+ exit 1
+ }
+ # End commit-msg
+
+Example post-commit:
+
+ #!/bin/sh
+ # Delete log file after successful commit.
+ LOG=$(git rev-parse --show-toplevel)/++log
+ [ -f ${LOG} ] && rm -f ${LOG}
+ # End post-commit
+
+"
+ (interactive "p")
+ (let* ((topd (substring (shell-command-to-string
+ "git rev-parse --show-toplevel") 0 -1))
+ (logfile (expand-file-name "++log" topd))
+ (hookd (paths-construct-path `(,topd ".git" "hooks")))
+ (msg-hook (expand-file-name "commit-msg" hookd))
+ (commit-hook (expand-file-name "post-commit" hookd))
+ (add-log-full-name (substring (shell-command-to-string
+ "git config user.name") 0 -1))
+ (add-log-mailing-address (substring (shell-command-to-string
+ "git config user.email") 0 -1))
+ (add-log-keep-changes-together t)
+ (header (concat
+ (format-time-string "%Y-%m-%d")
+ " "
+ add-log-full-name " <"
+ add-log-mailing-address ">\n"))
+ (newhead
+ (concat
+ "# Copyright -- to fool `add-change-log-entry'
+### Instructions:
+#
+# Put your short one-line summary on the first blank line after these.
+# Make sure that there is a blank line between your summary and the rest
+# of your changes log.
+#
+###"
+ (if (sy-git-check-hook msg-hook)
+ "\n# Lines beginning with '#' will be automatically deleted."
+ "\n# You MUST delete these lines before committing.")
+ (unless (sy-git-check-hook commit-hook)
+ "\n# No post-commit hook. Manually delete this log after you commit.")
+ "\n###"))
+ )
+ (and current-prefix-arg ; User wants to start over
+ (file-exists-p logfile)
+ (ignore-errors
+ (delete-file logfile)))
+ ;; It is possible that the logfile is gone but the buffer is still
+ ;; active
+ (and (not (file-exists-p logfile))
+ (buffer-live-p (find-buffer-visiting logfile))
+ (kill-buffer (find-buffer-visiting logfile)))
+ (with-current-buffer (find-file-noselect logfile)
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "^# Copyright" (point-at-eol) t)
+ (replace-match "Copyright"))))
+ (add-change-log-entry nil logfile t nil)
+ (save-excursion
+ (goto-char (point-min))
+ (delete-matching-lines (regexp-quote header))
+ (when (re-search-forward "^Copyright" (point-at-eol) t)
+ (replace-match "# Copyright"))
+ (goto-char (point-min))
+ (unless (search-forward newhead nil t)
+ (insert newhead "\n\n\n")))))
+
+
+(global-set-key [(control x) G a] #'sy-git-add-log-entry)
+
+(provide 'sy-git)
+;;; sy-git.el ends here