The policy at my new company is to prefix commit messages with the ID of the story they relate to. This week I tried doing an interactive rebase and came a little unstuck. Turns out that our use of hash symbols in commit messages upsets the interactive rebaser. Read on for the details…
We did something similar in my last job, where we used the prefixed branch names with the issue key of the Epic they related to in Jira. An “issue key” in Jira takes the form of
projectKey-issueNumber, so they might be something like
DEV-101. Working branches in git would, therefore, have names a bit like
Stories at my new place are kept in Pivotal Tracker, where issue IDs take the form of a hash symbol and a six-digit sequential number:
#101922, for instance. The result of the policy is that each commit message looks something like
#124182 Added a foo and removed a bar. This has worked pretty well in the month and a half that I’ve been working there so far.
As mentioned above, the problems started when I wanted to do an interactive rebase. I had made a silly spelling mistake a few of my most recent commits but luckily hadn’t pushed my changes yet. “Easy peasy”, thinks I, “just crack out a quick
git rebase -i HEAD~3 and away we go.” Up pops the interactive rebase in Vi and I merrily set to work
rewording my commits.
Imagine my disappointment when I was presented with:
Aborting commit due to empty commit message.
Could not amend commit after successfully picking 9d2958dbac8b64514652f4bc23fe952bf57fab4a... #001 Another commit, but with a typo
This is most likely due to an empty commit message
An empty commit message? But I gave it a new commit message… And then I am struck with the sudden recollection that git uses the hash symbol as its comment character. (D’oh!) My commit messages starting with hashes were being treated as comments, leaving nothing behind for git to use. Looking back, this is made obvious by the instruction lines at the bottom of the screen when performing an interactive rebase – they all start with a hash so that they are excluded from the rebase.
My disappointment had shifted to annoyance. Did our commit message scheme mean we could never do an interactive rebase?
Changing the comment character
After trying a few ways to escape the hashes, I stumbled on this Stackoverflow answer, which has a really easy fix:
- If needed, abort your current rebase with
git rebase --abort
- Change the comment character (in my case to a “$”) using
git config --global core.commentChar $
- Start your rebase again
Et voila! You’re now able to change those commit messages and can even leave in those pesky hashes.
A note on “auto”
The Stackoverflow answer I linked to above also mentions a feature in git that will choose a comment character automatically, based on the characters you use in commit messages.
git config --global core.commentChar auto
Sounds great right? Unfortunately, it only changes the comment character based on commits made after you turn it on; it doesn’t use your commit history to inform the choice.
To my mind, this is a great feature hobbled by poor execution. It seems like a feature that would be effective only if it were on by default:
- One group of people will simply avoid using hashes in commits because they are familiar with the consequences.
- Others (like us) will only realise they need to change the comment character when they need to do a rebase. It doesn’t make sense in this situation to add a new commit just to trigger the desired behaviour.
- A third group of people will consciously accept early on that they need to change the default comment character and will simply choose an alternative.
In other words, having this feature available as a non-default option helps virtually no-one. Since having it on by default would do nothing to harm any users, and would remove a pain point for some users, I can’t work out why this isn’t the case. Git isn’t famed for its usability, but to have a fix available and not to turn it on seems gratuitously user-hostile.