my team members began talking prefixing our commit title with the type of commit. The idea being that with consistent prefixing, we can more scan the commit titles to get an overview of what that looks like.
We cribbed our initial list from Udacity Nanodegree Style Guide:
- feat
- A new feature
- fix
- A bug fix
- docs
- Changes to documentation
- style
- Formatting, missing semi colons, etc; no code change
- refactor
- Refactoring production code
- test
- Adding tests, refactoring test; no production code change
- chore
- Updating build tasks, package manager configs, etc; no production code change
Our proposal was that at the start of next sprint we’d adopt this pattern for one sprint and then assess. We also had a conversation about the fact that those “labels” consume precious space in the 50 character or so title.
So we adjusted our recommendation to use emojis. We established the following:
- 🎁
- feature (A new feature)
- 🐛
- bug fix (A bug fix)
- 📚
- docs (Changes to documentation)
- 💄
- style (Formatting, missing semi colons, etc; no code change)
- ♻️
- refactor (Refactoring production code)
- ☑️
- tests (Adding tests, refactoring test; no production code change)
- 🧹
- chore (Updating build tasks, package manager configs, etc; no production code change)
Which means we were only surrendering 2 characters instead of a possible 8 or so.
Given that we were going to be practicing this, I wanted to have Emacs prompt me to use this new approach.
The jf/version-control/valid-commit-title-prefixes
defines the glossary of emojis and their meanings:
(defvar jf/version-control/valid-commit-title-prefixes
'("🎁: feature (A new feature)"
"🐛: bug fix (A bug fix)"
"📚: docs (Changes to documentation)"
"💄: style (Formatting, missing semi colons, etc; no code change)"
"♻️: refactor (Refactoring production code)"
"☑️: tests (Adding tests, refactoring test; no production code change)"
"🧹: chore (Updating build tasks, package manager configs, etc; no production code change)")
"Team 💜 Violet 💜 's commit message guidelines on <2023-05-12 Fri>.")
I then added jf/git-commit-mode-hook
which is added as find-file-hook
This hook is fired anytime we find a file and load it into a buffer.
.
(cl-defun jf/git-commit-mode-hook (&key (splitter ":") (padding " "))
"If the first line is empty, prompt for commit type and insert it.
Add PADDING between inserted commit type and start of title. For
the `completing-read' show the whole message. But use the
SPLITTER to determine the prefix to include."
(when (and (eq major-mode 'text-mode)
(string= (buffer-name) "COMMIT_EDITMSG")
;; Is the first line empty?
(save-excursion
(goto-char (point-min))
(beginning-of-line-text)
(looking-at-p "^$")))
(let ((commit-type (completing-read "Commit title prefix: "
jf/version-control/valid-commit-title-prefixes nil t)))
(goto-char (point-min))
(insert (car (s-split splitter commit-type)) padding))))
(add-hook 'find-file-hook 'jf/git-commit-mode-hook)
The jf/git-commit-mode-hook
function delivers on the following two scenarios:
Given I am editing a commit message
When I start from an empty message
Then Emacs will prompt me to select the commit type
And will insert an emoji representing that type
Given I am editing a commit message
When I start from a non-empty message
Then Emacs will not prompt me to select the commit type
Conclusion
This function took about 20 minutes to write and helps me create habits around a new process. And if we agree to stop doing it, I’ll remove the hook (maybe keeping the function).
In this practice time, before we commit as a team to doing this, I am already appreciating the improved scanability of the various project’s short-logs. Further this prompt helps remind me to write small commits.
Also, in exploring how to do this function, I continue to think about how my text editor reflects my personal workflows and conventions.