After switching to lazygit, the next obvious question was: can I make committing even faster? Turns out, yes, by letting Claude write the commit message for me.
The idea is simple. You stage your changes, press a key, and Claude reads the diff, generates a concise commit message, and drops you into the editor to review it before committing. No copy-pasting diffs into a chat window, no context switching. Just stage, press G, review, done.
This post is part of my terminal workflow series.
How it works
Lazygit supports custom commands: shell scripts bound to keys that run in a specific context. The flow looks like this:
- You stage files in lazygit Files panel (or the command grabs the unstaged diff as fallback)
- The custom command extracts the diff with
git diff --cached - The diff gets piped to
claude -p(Claude CLI) with a strict prompt that outputs only the commit message - The generated message is passed to
git commit -e -mso your editor opens with it pre-filled - You review, tweak if needed, and save to commit
The -e flag is important. It means you always get a chance to edit before committing. Claude is good, but you should still read what it wrote.
The lazygit config
Add this to your lazygit config.yml:
os: shell: "zsh" shellArg: "-c"customCommands: - key: "G" description: "AI commit message" context: "files" loadingText: "Generating commit message..." command: | DIFF=$(git diff --cached --diff-algorithm=minimal) if [ -z "$DIFF" ]; then DIFF=$(git diff --diff-algorithm=minimal) fi if [ -z "$DIFF" ]; then echo "No changes to commit" exit 1 fi MSG=$(echo "$DIFF" | claude -p "You are a commit message generator. Analyze the provided git diff and output ONLY the commit message, nothing else. Rules: Use imperative mood. Start with capital letter. No period at end. Max 50 chars. Be specific. Describe WHAT changed. Never use generic words alone. No conventional commit prefixes. Plain English." 2>/dev/null) if [ -n "$MSG" ]; then git commit -e -m "$MSG" fi output: terminalA few things worth noting about this config:
context: "files" means the command only works when you are in the Files panel, which is exactly where you would be when staging and committing.
The diff fallback: the command first tries git diff --cached (staged changes). If nothing is staged, it falls back to git diff (unstaged changes). This way the command works whether you have explicitly staged files or not.
--diff-algorithm=minimal keeps the diff concise, which matters because you are sending it to an LLM. Less noise, better commit messages.
The prompt is deliberately strict. No conventional commit prefixes (feat:, fix:), no period at the end, imperative mood, max 50 characters. This matches the classic Git commit message style. Adjust the prompt to your own conventions if you prefer something different.
output: terminal is needed because git commit -e opens your editor, which requires a terminal session.
The prompt matters
The quality of generated commit messages depends almost entirely on the prompt. Here is why I chose each rule:
Imperative mood (“Add feature” not “Added feature”): this is the Git convention. Your commit log reads as a series of instructions: “Apply this commit and it will add feature X.”
Max 50 characters: forces Claude to be concise. Without this, you get verbose descriptions like “Update the user authentication middleware to handle edge cases in token validation” instead of “Handle edge cases in auth token validation.”
No conventional commit prefixes: this is personal preference. I find feat:, fix:, chore: noisy in the log. If you use them, just update the prompt.
“Never use generic words alone”: without this rule, Claude loves to write things like “Update code” or “Fix bug.” The word “alone” is key. “Update” is fine as long as it says what was updated.
When it works best
This setup shines for small, focused commits, the kind you should be making anyway. Stage a file or two, let Claude describe the change, review, commit, move on.
It is less useful for large, multi-concern commits where the diff is huge and touches many unrelated things. But that is a sign you should be splitting your commit, not that the tool is broken.
Requirements
You need Claude Code (claude) installed and authenticated and lazygit. The command works with any terminal. I use Ghostty, but it is not terminal-specific.