What if every commit message told a clear story without you lifting a finger?
Why commit-msg hook for message validation in Git? - Purpose & Use Cases
Imagine you and your team are working on a project, and everyone writes commit messages in their own style. Some messages are clear, others are vague or missing important details. When you try to understand the history later, it feels like reading a messy diary with no order.
Manually checking each commit message is slow and easy to forget. Mistakes slip through, causing confusion and wasted time when tracking changes or fixing bugs. It's like proofreading a long essay without any tools--tiring and error-prone.
The commit-msg hook automatically checks every commit message before it's saved. It makes sure messages follow rules you set, like including a ticket number or a clear description. This keeps your project history neat and easy to understand without extra effort.
git commit -m "fix stuff"git commit -m "PROJ-123: Fix login button alignment"It enables a clean, consistent project history that everyone can trust and understand instantly.
A team working on a website uses a commit-msg hook to require ticket IDs in messages. When a bug appears, they quickly find the related commit and fix it, saving hours of searching.
Manual commit messages can be inconsistent and confusing.
Commit-msg hooks automatically enforce message rules.
This leads to clearer project history and faster teamwork.
Practice
commit-msg hook in Git?Solution
Step 1: Understand the role of Git hooks
Git hooks are scripts that run at specific points in Git's workflow to automate tasks or checks.Step 2: Identify the function of the commit-msg hook
The commit-msg hook runs after a commit message is entered but before the commit is finalized, allowing validation of the message.Final Answer:
To check and validate the commit message before the commit is saved -> Option AQuick Check:
commit-msg hook = validate commit message [OK]
- Confusing commit-msg hook with pre-push or post-commit hooks
- Thinking it automatically pushes commits
- Assuming it modifies commit history
commit-msg hook executable on a Unix-like system?Solution
Step 1: Understand file permissions for hooks
Git hooks are scripts stored in the .git/hooks directory and must be executable to run.Step 2: Identify the correct command to make a file executable
The commandchmod +xadds execute permission to the file, enabling the hook to run.Final Answer:
chmod +x .git/hooks/commit-msg -> Option BQuick Check:
chmod +x = make executable [OK]
- Using chmod 000 which removes all permissions
- Trying git commands that don't exist for hooks
- Not setting executable permission, so hook won't run
commit-msg hook script snippet, what will happen if the commit message is empty?
#!/bin/sh if [ -z "$1" ]; then echo "Error: Commit message is empty." >&2 exit 1 fi
Solution
Step 1: Analyze the script condition
The script checks if the first argument$1is empty using[ -z "$1" ]. In the commit-msg hook,$1is the path to a temporary file containing the proposed commit message.Step 2: Understand Git's behavior
Since$1is the file path, it is never empty, so the condition[ -z "$1" ]is false. However, the script as written incorrectly checks the variable$1instead of the content of the file. To check if the commit message is empty, the script should check the content of the file, e.g.,if [ ! -s "$1" ]orif [ -z "$(cat $1)" ]. As is, the script will not block empty commit messages.Final Answer:
The commit will proceed without any message -> Option CQuick Check:
$1is file path, not content; checking it for emptiness is incorrect [OK]
- Thinking exit 1 allows commit to proceed
- Assuming the message is replaced automatically
- Confusing $1 with the commit message text instead of file path
commit-msg hook to reject messages shorter than 10 characters:
#!/bin/sh
MSG=$(cat "$1")
if [ ${#MSG} -lt 10 ]; then
echo "Commit message too short." >&2
exit 1
fi
But it does not block short messages. What is the likely problem?Solution
Step 1: Check the script logic
The script correctly reads the commit message and checks its length using ${#MSG} which is valid in sh/bash.Step 2: Consider common hook issues
If the hook is not executable, Git will ignore it and allow commits without running the script.Final Answer:
The hook script is not executable -> Option AQuick Check:
Non-executable hook = script not run [OK]
- Assuming ${#MSG} is invalid in shell
- Confusing file path with message content
- Using wrong test operators like -z for length comparison
PROJ-123: followed by a space and description. Which commit-msg hook snippet correctly validates this pattern?Solution
Step 1: Understand the required pattern
The commit message must start with 'PROJ-' followed by digits, a colon, a space, then some text.Step 2: Analyze each option's regex and logic
#!/bin/sh MSG=$(cat "$1") if ! echo "$MSG" | grep -qE '^PROJ-[0-9]+: .+'; then echo "Commit message must start with 'PROJ-<number>: '" >&2 exit 1 fi uses grep -qE with '^PROJ-[0-9]+: .+' and exits with error if pattern not matched, which is correct. #!/bin/sh MSG=$(cat "$1") if echo "$MSG" | grep -q '^PROJ-[0-9]+: .+'; then exit 1 fi exits on match (wrong logic). #!/bin/sh if [ -z "$1" ]; then echo "Empty message" >&2 exit 0 fi exits 0 on empty message (wrong). #!/bin/sh MSG=$(cat "$1") if echo "$MSG" | grep -qE '^PROJ-[a-z]+: .+'; then echo "Invalid ticket format" >&2 exit 1 fi checks for lowercase letters after PROJ- which is incorrect.Final Answer:
#!/bin/sh MSG=$(cat "$1") if ! echo "$MSG" | grep -qE '^PROJ-[0-9]+: .+'; then echo "Commit message must start with 'PROJ-<number>: '" >&2 exit 1 fi -> Option DQuick Check:
grep -qE '^PROJ-[0-9]+: .+' = valid pattern check [OK]
- Reversing logic: exiting on match instead of no match
- Using wrong regex for digits or colon
- Exiting with 0 on error conditions
Ready to prove it?
Pass the test and this pattern moves unknown
