Auto-generating a commit message
Tags: commit, git, discuss, productivity
Published: 2020-06-09 10:41:32

---
title: Auto-generating a commit message
published: true
description: Asking for help and ideas on my new project
tags: commit, git, discuss, productivity
//cover_image: https://direct_url_to_image.jpg
---

> Asking for help and ideas on my new project.

## TL;DR

I am tired of writing commit messages which are bigger than the code changes and which could be programmatically and precisely generated. I am writing my own Python script as a pre-commit message hook. Does anyone know of an existing tool or script to do this?

- [MichaelCurrin/auto-commit-msg](https://github.com/MichaelCurrin/auto-commit-msg)

## Aim

I started a new personal project recently to automagically create a description commit message for me in one line.

I'll still write manual messages for important changes, but 80% of my commits are so small and frequent that writing a message feels tedious and adds friction. And the message that I end up writing by hand is usually something can be be written by a machine - but I usually simplify by using the filename rather than path or I don't bother saying how many files changed because it's too much effort.

## Research on existing tools

There are plenty of tools for _validating_ or _linting_ commit messages.

- [observing/pre-commit](https://github.com/observing/pre-commit)
- [legend80s/commit-msg-linter](https://github.com/legend80s/commit-msg-linter) (influenced by `pre-commit`)
- [Commit Message Lint](https://github.com/marketplace/commit-message-lint) Github Action to lint PRs.

I have found how to prefix a message with branch name - see [gist](https://gist.github.com/bartoszmajsak/1396344/97081e76ab275f5fe526347908503febd1340495).

If you want to manually configure a value like Jira ticket number in a text file in your repo, you can use that to prefill the commit message - see [Commit Message Template](https://github.com/MichaelCurrin/learn-to-code/blob/master/en/topics/version_control/Git/configure/commit_message_template.md) guide.

I've even found efforts to generate a commit message using machine learning.

- [On automated generation of commit messages from code differences](https://medium.com/@satnalikamayank12/on-automated-generation-of-commit-messages-from-code-differences-7ab205ae580)
- [Automatically Generating Commit Messages
from Diffs using Neural Machine Translation](https://arxiv.org/pdf/1708.09492.pdf) - see page 10 for the generated message.
- [On Automatically Generating Commit Messages via
Summarization of Source Code Changes](http://www.cs.wm.edu/~denys/pubs/SCAM14-ChangeScribe-CR.pdf)
- [Generating Commit Messages from Git Diffs](https://arxiv.org/pdf/1911.11690.pdf) using Neutral Machine Translation.

Though, these are based on more the content of the file diffs and the context of the code, rather than describing which files changed.

So I am having a hard time auto-generating a new message which captures the changes in one sentence in a high-level way that gives enough detail.

## Git hooks

Git provides "hooks" which are run on certain conditions. There are sample files in `.git/hooks/` when you setup a repo and you can rename one to remove `.sample` extension to make it active. Note - this is _not_ in version control, so you'll need to do more work to persist it and activate it on a fresh clone.

Check these resources:

- [githooks](https://linux.die.net/man/5/githooks) on the Linux man page
- [githooks.com/](http://githooks.com/)

There is a sample git hook file which looks like this:

- [prepare-commit-msg.sample](https://github.com/git/git/blob/master/templates/hooks--prepare-commit-msg.sample).

It provides logic for adding a multi-line list of files changed - see the commented `perl` section which removes the `#` comment symbol from part of the diff message. 

Example output is something like this:

```
My message

added:  README.md
modified: foo/baz.md
modified: foo/buzz.md
deleted: fizz.txt
```

This looks like the right mechanism to use, but the output is too long.


## What existing solutions can solve my need?

I want something more succinct (one line) and worded in a way a human would write. 

Are there any other tools out there that do this already? Can someone point me in the write direction or share what they made or found?

Especially if there are 20 files which were modified. Or more commonly for me, one line changed or one character changed in one or two files and explaining is the commit is of low value (and longer than the actual diff).


## My project

Planning and ideas so far on my new Auto Commit Msg project.

Here is my repo:

- [MichaelCurrin/auto-commit-msg](https://github.com/MichaelCurrin/auto-commit-msg)

The project is still in early development and probably going to be in Python. So far there's a spec in the Wiki and I have a minimal prototype in Bash which I haven't committed.


Example output of `status`.

```
$ git status --short
 M foo/baz.md
 M foo/buzz.md
```

When I commit with my tool, the commit message will be something like:

```
Update 2 files in foo/
```

Or something more complex:

```
Add 2 files in foo/ and delete 5 files in bar/
```

If `requirements.txt` or `Gemfile` or `package.json` changes:

```
chore: Update dependency file
```

Or `Create` or `Delete`.

If `_config.yml` changes:

```
chore: Update config
```

Or

```
style: Whitespace changes in fizz/buzz/foo.txt
```


## VS Code integration

Another thought - how can I prepare a commit message in VS Code easily?

This is still something I am looking into with VS Code settings (not fruitful) or using an extension, maybe writing my own.

The `prepare-commit-msg` hook works fine for command-line commits. But how do I make sure my auto message gets added to the message bar in VS Code's Git integration? Should it regenerate every second? Should it generate on `stage` action (in UI and command-line)? Should it generate a message after you press commit with an empty message and then preview the message in a pop-up? 

## Semantic commits

On a related idea - I am also working on adding semantic messages to the start of the commit where possible, which I mixed into examples above. Maybe it can controlled through a command or a flag where it's not possible for a script to tell the difference between a fix and a feature, but a chore or doc changes are easier to deduce.

```
feat: Message
fix: Message
chore: Message
docs: Message
```

## Conclusion

Thanks for reading. I hope I can get some ideas of existing projects to guide my approach, or to build on them.