Backend
I Built a Git Hook That Makes Revert Commits Conventional
James Jeremy Foong DEV Community
1 views
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
git revert generates:
Revert "feat(email): add send tool"
I wanted:
revert(email): add send tool
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"
becomes:
revert(email): add send tool
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
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
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
revert(email): add send tool
Plain style removes the scope:
git config revert-hook.style plain
revert: add send tool
The hook also supports a nested compatibility style:
git config revert-hook.style nested
revert(feat(email)): add send tool
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
The test suite passes with:
All tests passed.
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.
Read original: https://dev.to/jamesjf7/i-built-a-git-hook-that-makes-revert-commits-conventional-13i6
← Previous
Agentic Accessibility - Can AI help us ship more accessible code?
Next →
Apple shipped a foldable iPhone. Safari still can't tell you it folded.
Related
From 4.2s to 380ms: debugging latency in a high availability infrastructure setup
Backend
0
DEV Community
What is the best way to manage a PHP project?
Backend
0
DEV Community
I rented three servers, told nobody, and watched the internet break in anyway
Backend
0
Dev.to (EN Zone)
A Spreadsheet Was Running a Process We Called Automated
Backend
2
Dev.to (EN Zone)
Comments0
No comments yet — be the first