Ever scrolled through a Git repository's log and noticed how chaotic and unstructured the commit messages look? π¨ Writing a good commit message is often overlooked, but it significantly impacts the readability of your project.
A well written commit message is also a sign of respect to your colleagues and other developers as it saves time by trying to understand the context and purpose of changes π. These changes might seem simple to you at the moment of writing a commit message, but your future self and team will thank you if you take a moment to consider how you can make your commit message better, and you can use Git Hooks to help you with that.
What Are Git Hooks? π€
Git hooks are scripts that Git executes before or after events. Think of them as customizable, automatic actions that occur at specific phases of the Git process.
There are two types of Git hooks:
Client-side hooks: These run on your local machine. They're useful for operations like committing and merging.
Server-side hooks: These run on the server. They're great for tasks that happen after pushing changes, like continuous integration checks.
Structure of Commit Message π
To commit a message, the following command is used:
git commit -m <subject line> -m <body>
Subject line is there to summarize the changes in short and informative manner while the body is there to describe the changes in more detail.
But how exactly should the subject line and body look like? π
Subject Line
There are some conventions that are being used for the subject line, such as:
Maximum 50 Characters Long
Start with Capital Letter
Remove Punctuation
Use Imperative
Body
There are some conventions that are being used for the subject line, such as:
Wrap the Body at 72 Characters
Explain What and Why, Not How
In most cases, you can leave out details about how a change has been made. Code should be self-explanatory in this regard. Focus on explaining the reasons why you made the change - the way things worked before the change (and what was wrong with that), the way they work now, and why you decided to solve it the way you did.
Using Git Hooks for Commit Messages π
To ensure every commit message follows your custom rules, you can use the commit-msg
hook.
Setting Up commit-msg
Hook
Navigate to your Git repository on your local machine.
Find the
.git/hooks
directoryCreate a new file named
commit-msg
(no file extension) in the.git/hooks
directory.Edit this file to define the rules for your commit messages. Here's an example of a script for enforcing perfect commit message format:
#!/bin/sh
INPUT_FILE="$1"
TEMP_FILE=$(mktemp)
{
read -r subject
echo "$subject" | fold -sw 50
echo
while IFS= read -r line; do
echo "$line" | fold -sw 70
done
} < "$INPUT_FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$INPUT_FILE"
Make the script executable by running
chmod +x .git/hooks/commit-msg
from your terminal.Congrats! This
commit-msg
will now be executed each time you commit a message.
Here is the explanation of the script:
INPUT_FILE="$1"
- This line assigns the first argument passed to the script (
$1
) to a variable namedINPUT_FILE
. In the context of acommit-msg
hook, this argument is the path to a temporary file that contains the commit message.
TEMP_FILE=$(mktemp)
- This line creates a temporary file using
mktemp
command and assigns its path to the variableTEMP_FILE
. This temporary file is used to store the formatted commit message before it's moved back to replace the original commit message.
read -r subject
echo "$subject" | fold -sw 50
This command reads the first line from the
INPUT_FILE
(which is the subject line of the commit message) and stores it in the variablesubject
.Then it echoes the subject line and pipes it through
fold -sw 50
, which wraps the line at a maximum width of 50 characters. The-s
flag causesfold
to break lines at spaces (making the breaks occur between words when possible), and-w 50
sets the wrap width.The second
echo
command adds an empty line after the subject to separate the subject from the body of the commit message, adhering to good commit message practices.
while IFS= read -r line; do
echo "$line" | fold -sw 72
done
- Then starts a
while
loop that reads the rest of the commit message line by line.IFS=
(Input Field Separator) is set to nothing to prevent leading/trailing whitespace from being trimmed. Inside the loop, each line of the commit message body is echoed and piped throughfold -sw 72
to wrap at 72 characters. The loop continues until all lines of the commit message have been processed.
{ ... } < "$INPUT_FILE" > "$TEMP_FILE"
- The block is redirected to read from
INPUT_FILE
(the original commit message) and write the output (the formatted commit message) toTEMP_FILE
.
mv "$TEMP_FILE" "$INPUT_FILE"
- This command moves the
TEMP_FILE
(which now contains the formatted commit message) back toINPUT_FILE
, effectively replacing the original commit message with the formatted one.
Advantages of Using commit-msg
Hook
Consistency: Enforces a consistent commit message format
Automation: Saves time and mental energy by automating checks
Quality Assurance: Improves the overall quality of commit messages, making the project history more readable and useful
Conclusion
Git hooks, specifically the commit-msg
hook, offer a powerful way to enhance the quality of your project's commit messages. πͺπ» You ensure consistency of your commit messages and also help your team and future self to understand the changes done in the code. Remember, great commit messages are a sign of a thoughtful developer. ππ»