When I run git commit
without -m
, git launches a commit message editor with some hints, something like this:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# new file: bar
#
I often find myself running git log --oneline -n 10
before committing, just to see what the commit messages look like so I can write in a similar style. So it would be great if this information is injected into the commit message editor as additional hints. Something like this would be ideal:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# new file: bar
#
# Last 10 commits:
# bbbbbbb (HEAD -> master) Another commit
# aaaaaaa Initial commit
#
What is the proper way to do this?
Naturally I thought of git hooks, in particular prepare-commit-msg
. This is what I wrote:
#!/usr/bin/env bash
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
# Show last 10 (max) commits
echo '# Last 10 commits:' >> "$COMMIT_MSG_FILE"
git log --oneline -n 10 --decorate=short | sed 's/^/# /' >> "$COMMIT_MSG_FILE"
echo '#' >> "$COMMIT_MSG_FILE"
This mostly works fine except for one thing - it doesn't work fine. While this info is now injected as hints correctly when running git commit
, it also has the unintended side effect of breaking commands like git cherry-pick
and git rebase
. For example, if I have a commit that looks like this:
ccccccc Add baz
And I try to git cherry-pick ccccccc
, it turns into this instead:
ddddddd Add baz # Last 10 commits: # bbbbbbb (HEAD -> master) Another commit # aaaaaaa Initial commit #
As you can see, the hints I inserted are not interpreted correctly without an interactive editor and clobber the commit message instead. Obviously this is not what I want. I did try to investigate whether I can use the script arguments to only inject hints in interactive mode, but it's not obvious how to do that or whether it's possible.
The behavior is controlled by --cleanup=$mode or the configuration variable commit.cleanup.
git commit --cleanup=strip
# Or
git -c commit.cleanup=strip commit
With strip
, the commentary is removed no matter the commit message is edited or not.
With default
, the commentary is removed if the commit message is edited, and not removed if it's not edited.
strip
Strip leading and trailing empty lines, trailing whitespace, commentary and collapse consecutive empty lines.
whitespace
Same as strip except #commentary is not removed.
default
Same as strip if the message is to be edited. Otherwise whitespace.
So, I think you can use git config --global commit.cleanup strip
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With