Building a local Git hook with Python is great, but if you want others on your
team (or across multiple repos) to use it, you’ll want to package it as a
reusable command-line tool. In this article, we’ll turn our AI-powered Git hook
into a proper Python CLI application that can be installed via pip
, executed
from anywhere, and easily integrated into .git/hooks
.
Why Package It?
Benefits of packaging your Git hook logic as a CLI:
- Portable: Easily share across teams or projects
- Customizable: Let users configure behavior via CLI flags or config files
- Maintainable: Update via PyPI or GitHub release
- Composable: Can be used as a standalone tool or Git hook
Step 1: Project Structure
Here’s how we’ll organize the CLI package:
ai_git_hooks/
├── ai_git_hooks/
│ ├── __init__.py
│ ├── cli.py
│ ├── diff_utils.py
│ ├── openai_utils.py
│ └── config.py
├── pyproject.toml
├── README.md
└── setup.cfg
We’ll use Click for CLI handling and
setuptools
to package it.
Install dependencies:
pip install click openai gitpython
Step 2: Core Logic Modules
diff_utils.py
from git import Repo
def get_staged_diff(repo_path="."):
repo = Repo(repo_path)
return repo.git.diff('--cached')
openai_utils.py
import openai
import os
openai.api_key = os.getenv("OPENAI_API_KEY")
def analyze_diff(diff: str) -> str:
prompt = f"""
You are an experienced software engineer. Review the following Git diff for
potential issues. Be concise.
{diff}
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content.strip()
Step 3: CLI Interface with Click
cli.py
import click
from ai_git_hooks.diff_utils import get_staged_diff
from ai_git_hooks.openai_utils import analyze_diff
@click.group()
def cli():
pass
@cli.command()
def review():
"""Review staged Git changes with OpenAI"""
diff = get_staged_diff()
if not diff.strip():
click.echo("No staged changes found.")
return
feedback = analyze_diff(diff)
click.echo("--- AI Review ---")
click.echo(feedback)
if __name__ == '__main__':
cli()
This defines a CLI with a single review
command. Run it like:
ai-git-hooks review
Step 4: Packaging with pyproject.toml
pyproject.toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "ai-git-hooks"
version = "0.1.0"
description = "AI-powered Git hooks with OpenAI and Python"
authors = [
{ name="Scott Hebert", email="your@email.com" }
]
readme = "README.md"
requires-python = ">=3.8"
dependencies = ["click", "openai", "gitpython"]
[project.scripts]
ai-git-hooks = "ai_git_hooks.cli:cli"
setup.cfg
(optional for metadata)
[metadata]
license_files = LICENSE
Install your package locally:
pip install -e .
Now the ai-git-hooks
command is available globally.
Step 5: Integrate with Git Hooks
You can now use this CLI inside your .git/hooks/pre-commit
:
#!/bin/sh
ai-git-hooks review
if [ $? -ne 0 ]; then
echo "❌ Commit blocked by AI review."
exit 1
fi
Make it executable:
chmod +x .git/hooks/pre-commit
Optional Enhancements
- Config file support (e.g.,
.ai-git-hooks.toml
) for repo-level customization - Multiple review modes: security, style, performance
- Auto-commit message generation as a separate command
- Verbose vs. silent modes for CI-friendly output
- Installer script for teams: bootstraps config and hook integration
Conclusion
By packaging your AI Git hook logic as a proper CLI tool, you unlock a more powerful, scalable, and user-friendly way to integrate LLM-powered automation into your development process. It's reusable, shareable, and just the beginning of what you can build in the age of AI-assisted coding.
Ready to take the next step? Let’s build a downloadable template repo for this CLI tool to help others get started quickly. Or, want to keep building out intelligent Git hooks? Check out more on Slaptijack