Pedram's Web Blog

Things I Learned

Never Write Another Git Commit Message

|

Here’s a simple way to never write another git commit message again.

You will need SimonW’s llm installed:

  pip install llm 

And you will need to use of the many support LLMs. If you’re using OpenAI:

  llm keys set openai 

Then, create a template prompt:

  llm templates edit gitcommit 

Here’s the one I use, although I update it frequently:

  model: gpt4
system: >
  You will receive a git diff. Write a commit message as if you are a senior software engineering.
  Keep the commit messages brief, but informative. Use new lines to break apart long sentences.
  Type can be fix, feat, BREAKING CHANGE. Other types of commits are allowed, e.g. build:, chore:, ci:, docs:, style:, refactor:, perf:, test:, and others.

  There MUST be only one type and description line.
  Use this template:
    <type>[optional scope]: <description>

    [optional body]

  Examples:

  Commit message with description and breaking change footer:
    feat: allow provided config object to extend other configs

    BREAKING CHANGE: `extends` key in config file is now used for extending other config files

  Commit message with ! to draw attention to breaking change:
    feat!: send an email to the customer when a product is shipped

  Commit message with scope and ! to draw attention to breaking change:
    feat(api)!: send an email to the customer when a product is shipped

  Commit message with both ! and BREAKING CHANGE footer:
    chore!: drop support for Node 6

    BREAKING CHANGE: use JavaScript features not available in Node 6.

  Commit message with no body:
    docs: correct spelling of CHANGELOG

  Commit message with scope:
    feat(lang): add Polish language

  Commit message with multi-paragraph body and multiple footers:
    fix: prevent racing of requests

    Introduce a request id and a reference to latest request. Dismiss
    incoming responses other than from latest request.

    Remove timeouts which were used to mitigate the racing issue but are
    obsolete now.

prompt: >


  Diff: """$input""" 

Now all you need is a shell command. You can insert this into your .zshrc or .bashrc :

  gcllm() {
  GIT_DIR="$(git rev-parse --git-dir)"
  TEMPLATE="$GIT_DIR/COMMIT_EDITMSG_TEMPLATE"
  echo '--- DELETE THIS LINE TO SAVE ---' > "$TEMPLATE"
  git diff --cached -U1 --minimal -B --compact-summary --find-copies-harder -w  | head -n 1000 | llm -t gitcommit >> "$TEMPLATE"
  git commit --verbose --template="$TEMPLATE"
} 

Here’s a run down of how it works:

  • Find your .git directory to store the template file
  • Add a header to the template file, this must be deleted in order to save the commit, otherwise the commit aborts.
  • Get a diff of the staged files, and fetch only the first 1000 rows in order to prevent sending too many tokens to the LLM.
  • Pass the diff to the llm via the template and save to our template location following the header
  • Commit the changes using the template flag, which opens up your editor. If you do not save changes, it will abort the commit.