This Python Script Judges My Git Commits. Brutally.
Tired of meaningless commit messages and messy diffs? I built a Python script that critiques my commits like a grumpy senior dev — and…

It doesn’t sugarcoat. It doesn’t care. It just roasts my code — line by line.
This Python Script Judges My Git Commits. Brutally.
Tired of meaningless commit messages and messy diffs? I built a Python script that critiques my commits like a grumpy senior dev — and it’s made me a better coder.
There’s something sacred about a good Git commit.
A clear message, a focused change, a diff that tells a coherent story. It’s the kind of thing that makes future-you — and your teammates — breathe a sigh of relief.
But for years, my commits were chaotic.
Vague messages like fix stuff
, unrelated changes bundled together, even commented-out debugging lines I forgot to remove.
So I built a Python script to call me out on all of it.
It’s brutal, opinionated, and doesn’t let anything slide.
And honestly? It’s made me a better developer.
Why Your Git Commits Deserve More Respect
Most developers treat Git commits like a chore.
Just type something — anything — and push.
But good commits are more than just snapshots of your code. They are:
- Documentation for your future self.
- Context for your teammates.
- Stories of how your code evolved.
Messy commit histories make debugging harder, code reviews painful, and onboarding slower.
If your git log
reads like a crime scene, you’re not alone.
That’s why I automated the judgment process.
What This Script Actually Does
At its core, this Python script inspects the current Git commit before it gets saved.
It hooks into your Git workflow and acts like a relentless reviewer who’s seen too much bad code.
Here’s what it checks:
Commit Message Quality
- Is the message too short?
- Does it use vague verbs like “update”, “change”, or “fix” without context?
- Is it written in imperative mood (e.g., “Add unit tests” not “Added unit tests”)?
- Does it start with a capital letter and avoid trailing periods?
Diff Hygiene
- Are there commented-out lines?
- Is there any leftover
print()
orconsole.log()
for debugging? - Are unrelated files changed together?
- Are there too many lines changed in one commit? (a red flag for unfocused commits)
File-Level Sanity Checks
- Did you accidentally commit
.env
,.log
, or.DS_Store
? - Did you modify lock files unnecessarily?
If anything fails, it prints a savage review like:
🔥 Commit Rejected 🔥
Reason: Your message says "Updated stuff". Be honest—what did you *really* do?
Tip: Use imperative tone and add context. Example: "Refactor API error handling"
Also: You left 3 commented-out lines in utils.py. Clean up after yourself.
Try again when you’re ready to commit like a pro.
Under the Hood: How It Works
The script uses a combination of Git hooks and Python magic.
1. Pre-Commit Hook
Git allows you to define scripts in a .git/hooks/
directory that run automatically before commits.
I created a pre-commit
hook that triggers my Python judge script.
2. Python Script Breakdown
Here’s a simplified version of the core logic:
import re
import subprocess
import sys
def get_commit_msg():
result = subprocess.run(['git', 'log', '-1', '--pretty=%B'], capture_output=True, text=True)
return result.stdout.strip()
def get_diff():
result = subprocess.run(['git', 'diff', '--cached'], capture_output=True, text=True)
return result.stdout
def has_commented_code(diff):
return bool(re.search(r'^\+.*#', diff, re.MULTILINE))
def has_prints(diff):
return bool(re.search(r'^\+.*print\(', diff, re.MULTILINE))
def check_commit_message(msg):
if len(msg) < 10:
return "Commit message too short."
if re.match(r'^(Updated|Changed|Fixed)', msg, re.IGNORECASE):
return "Avoid vague verbs like 'updated'."
if not msg[0].isupper():
return "Start your message with a capital letter."
if msg.endswith('.'):
return "Don’t end commit messages with a period."
return None
def main():
msg = get_commit_msg()
diff = get_diff()
problems = []
msg_issue = check_commit_message(msg)
if msg_issue:
problems.append(msg_issue)
if has_commented_code(diff):
problems.append("Commented-out code detected.")
if has_prints(diff):
problems.append("Debug print statements still present.")
if problems:
print("🔥 Commit Rejected 🔥\n")
for p in problems:
print("Reason:", p)
sys.exit(1)
if __name__ == "__main__":
main()
You can expand this with linters, AI summaries, or integration with tools like pre-commit
.
What Happened When I Actually Started Using It
The first week was humbling.
I thought my commits were decent — but the script called me out every time.
- It flagged vague messages I didn’t realize were useless.
- It caught junk I’d left behind in diffs.
- It made me rethink when to split large changes into smaller, meaningful commits.
Now, my git log
reads more like a story than a mess:
Add retry logic to payment processor
Refactor user session handling
Remove unused auth helper
Fix broken test in billing_test.py
It’s not perfect, but it’s clear, focused, and intentional.
Why This Matters More Than Ever
As codebases grow and teams scale, your commit history becomes a shared language.
A sloppy commit is like mumbling during a presentation — people can follow, but it’s painful.
This script enforces:
- Discipline: Every commit is a checkpoint, not a dumpster.
- Communication: Good messages reduce the need for back-and-forth in PRs.
- Professionalism: You come across as someone who cares about your craft.
Want to Try It Yourself?
Here’s how to get started:
- Save the Python script above as
judge_commit.py
in your project. - Create a
pre-commit
file inside.git/hooks/
with this content:
#!/bin/bash
python3 judge_commit.py
- Make it executable:
chmod +x .git/hooks/pre-commit
- Commit something terrible — and enjoy the roast.
You can also expand this into a proper pre-commit
config or GitHub action.
Final Thoughts
Writing clean code isn’t just about functions and files — it’s about communication.
Your Git history is a mirror of your development habits.
Let it reflect someone who thinks clearly, commits intentionally, and respects the team (and future-you).
Sometimes, we all need a little tough love.
Code reviewers might be kind — your Python script won’t be. And that’s exactly the point.