Add new file sy-git.el for easier commit logging from SXEmacs
authorSteve Youngs <steve@sxemacs.org>
Sun, 5 Jul 2015 05:27:23 +0000 (15:27 +1000)
committerSteve Youngs <steve@sxemacs.org>
Sun, 5 Jul 2015 05:27:23 +0000 (15:27 +1000)
* sy-git.el: New.

Signed-off-by: Steve Youngs <steve@sxemacs.org>
sy-git.el [new file with mode: 0644]

diff --git a/sy-git.el b/sy-git.el
new file mode 100644 (file)
index 0000000..30d112d
--- /dev/null
+++ b/sy-git.el
@@ -0,0 +1,174 @@
+;; 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