2

At work we have several different commit messages that are used for every feature branch:

  • branchname initial
  • branchname ready for review
  • branchname passed review
  • branchname done
  • plus a few more that apply in special situations

Is there some way to make custom magit commands to pre-populate the commit message with the relevant text? Ideally it would be possible to add more actions to the *magit-commit-popup* buffer for these types of commits. If there's no way to add additional options in the commit popup, I'm open to other ideas. For example:

  1. Using yasnippets to store and retrieve the commit messages (I'm aware of this answer). However, this seems sort of inelegant.
  2. Writing elisp function(s) to call the magit internal functions with appropriate values. This might be a stretch for me, and anyway would be prone to breakage if magit changes.
1

I suggest using a prepare-commit-message git hook which inserts all of the possible status options as comments. The user can then simply uncomment the relevant status when writing their commit message.

That solution will work in general (not only in Magit).

The usage notes in .git/hooks/prepare-commit-msg.sample aren't as good as they could be, so I've included my own notes in this example:

#!/bin/sh
# Git hook (prepare-commit-msg) to insert the list of status options.

## General information on Git prepare-commit-msg hooks:
#
# The purpose of the hook is to edit the message file in place, and it is
# not suppressed by the --no-verify option. A non-zero exit means a failure
# of the hook and aborts the commit.
#
# This hook is invoked by git commit right after preparing the default log
# message, and before the editor is started.
#
# It takes one to three parameters:
#
# 1. The first is the name of the file that contains the commit log message.
#
# 2. The second is the source of the commit message, and can be:
#    - message:  -m or -F option was given
#    - template: -t option was given, or config option commit.template is set
#    - merge:    the commit is a merge or a .git/MERGE_MSG file exists
#    - squash:   .git/SQUASH_MSG file exists
#    - commit:   -c, -C or --amend option was given
#
#    For a simple 'git commit' command with no pre-existing message source
#    specified or implied, this second parameter is empty.
#
# 3. The third is a commit SHA-1 when source is 'commit'.
#
# If the exit status is non-zero, git commit will abort.

##############################################################################

file=$1
source=$2
hash=$3

# Only act if the user is creating/editing a new commit message.
if [ -n "${source}" ]; then
    exit 0
fi

branchname=$(git symbolic-ref -q HEAD)
branchname=${branchname##refs/heads/}
branchname=${branchname:-HEAD}

sed -i "1 i \\
# ${branchname} initial\\
# ${branchname} ready for review\\
# ${branchname} passed review\\
# ${branchname} done\\
" "${file}"

exit 0
1

FWIW a Magit-specific option along similar lines as the prepare-commit-message answer is:

;; Custom major mode for commits
(define-derived-mode my-git-commit-mode text-mode "Git commit"
  (save-match-data
    (when (save-excursion (re-search-forward "\\`[\n[:space:]]*#" nil :noerror))
      (let ((branchname (magit-get-current-branch))
            (options '("initial"
                       "ready for review"
                       "passed review"
                       "done")))
        (save-excursion
          (dolist (status options)
            (insert (format "# %s %s\n" branchname status))))))))

(setq git-commit-major-mode 'my-git-commit-mode)

I had initially written code along these lines for my own purposes, before changing to the hook-based approach.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.