Commit-editmsg | FHD |
Great commits tell a story. They explain why a change was made, not just what changed. Good commit bodies might contain multiple paragraphs, bullet points, Signed-off-by trailers, or references to issue trackers. Trying to format this in a shell is a nightmare.
The COMMIT-EDITMSG file is not just static text. Git provides a hook system—scripts that run at specific points in the commit lifecycle. The most important hook for our keyword is the commit-msg hook.
Located at .git/hooks/commit-msg (or in a shared template), this script runs after you have edited the COMMIT-EDITMSG file but before Git creates the commit. COMMIT-EDITMSG
Why is this revolutionary? Because you can programmatically validate or modify the commit message.
If you exit the editor without saving, or if the commit message is empty after stripping comments, Git aborts with: Great commits tell a story
Aborting commit due to empty commit message.
Open a new terminal, navigate to a Git repository, and run git commit without any arguments. Your editor will open, and you will see 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 main
# Your branch is up to date with 'origin/main'.
#
# Changes to be committed:
# modified: src/main.py
# new file: src/utils.py
#
# Changes not staged for commit:
# modified: README.md
#
# Untracked files:
# temp.log
#
This is the default template. Notice a few critical features: Open a new terminal, navigate to a Git
The COMMIT_EDITMSG file is the only place where you can seamlessly write a multi-line, detailed commit message without using shell escape sequences or awkward string quoting.
You can also create a template file that Git will automatically copy into .git/COMMIT_EDITMSG every time you run git commit. This is great for team standards.
Set a global template:
git config --global commit.template ~/.gitmessage.txt
Now create ~/.gitmessage.txt:
# <subject> (max 50 chars)
# |<---- 50 chars ---->|
#
# <body> (wrap at 72 chars, explain what and why, not how)
# |<---- 72 chars ---->|
#
# Issue: #<number>
# Signed-off-by: <your name>