Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject additional hints into `COMMIT_EDITMSG` during `git-commit`

The problem

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?

What I've tried

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.

like image 512
cyqsimon Avatar asked Sep 13 '25 21:09

cyqsimon


1 Answers

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.

like image 137
ElpieKay Avatar answered Sep 16 '25 12:09

ElpieKay