DEV Community

James Jeremy Foong
James Jeremy Foong

Posted on Originally published at github.com

I Built a Git Hook That Makes Revert Commits Conventional

Git's default revert message is useful, but it does not fit nicely into a Conventional Commits history.

Given this commit:

feat(email): add send tool
Enter fullscreen mode Exit fullscreen mode

git revert generates:

Revert "feat(email): add send tool"
Enter fullscreen mode Exit fullscreen mode

I wanted:

revert(email): add send tool
Enter fullscreen mode Exit fullscreen mode

So I built conventional-revert-hook.

What it does

The hook uses Git's prepare-commit-msg hook. It runs after Git prepares a revert message and before the editor opens.

Revert "feat(email): add send tool"
Enter fullscreen mode Exit fullscreen mode

becomes:

revert(email): add send tool
Enter fullscreen mode Exit fullscreen mode

It only changes Git-generated revert messages. Normal commit messages pass through unchanged.

Why a shell script?

The tool does not need a runtime ecosystem.

  • No Node.js
  • No Python
  • No package manager
  • No project-specific configuration
  • POSIX shell only

Git and a POSIX shell are enough.

Installation

For a personal machine, global installation is the convenient option:

git clone https://github.com/jamesjfoong/conventional-revert-hook.git
cd conventional-revert-hook
./install-global.sh
Enter fullscreen mode Exit fullscreen mode

This installs one global prepare-commit-msg hook and applies it to current and future repositories on that machine.

For one repository only:

curl -fsSL https://github.com/jamesjfoong/conventional-revert-hook/releases/latest/download/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

The repository-local installer refuses to overwrite an existing hook.

Global installation changes Git's global core.hooksPath. Avoid it when using Husky or another hook manager that already owns your Git hooks.

Output styles

The default style keeps the original scope:

git config revert-hook.style scope
Enter fullscreen mode Exit fullscreen mode
revert(email): add send tool
Enter fullscreen mode Exit fullscreen mode

Plain style removes the scope:

git config revert-hook.style plain
Enter fullscreen mode Exit fullscreen mode
revert: add send tool
Enter fullscreen mode Exit fullscreen mode

The hook also supports a nested compatibility style:

git config revert-hook.style nested
Enter fullscreen mode Exit fullscreen mode
revert(feat(email)): add send tool
Enter fullscreen mode Exit fullscreen mode

The default scope style is the safest choice for Conventional Commit tooling. Some parsers reject nested parentheses.

Safety behavior

A Git hook can interfere with existing developer tooling, so the installers are deliberately conservative.

  • Existing repo-local hooks are not overwritten.
  • Existing global hook paths are not silently replaced.
  • Symlinks are rejected by the global installer.
  • The uninstaller removes only hooks carrying the project's marker.
  • The original commit body remains intact.
  • Non-revert commit messages remain unchanged.

Testing

The project has no test framework dependency. test.sh creates temporary Git repositories and exercises installation, overwrite protection, message rewriting, styles, fallback behavior, global installation, and cleanup.

./test.sh
Enter fullscreen mode Exit fullscreen mode

The test suite passes with:

All tests passed.
Enter fullscreen mode Exit fullscreen mode

Try it

Repository:

https://github.com/jamesjfoong/conventional-revert-hook

If you use it, open an issue with your Git hook setup and the style you prefer. Feedback is especially useful for integrations with existing hook managers.

Small tool. One annoying Git message fixed.

Top comments (0)