Open-source project
sds/overcommit avatar
sds/overcommit

sds/overcommit: a Git hook manager written in Ruby

A fully configurable and extendable Git hook manager

4,004 stars286 forksRubyMIT

At a glance

What is it?
Overcommit installs and configures Git hooks across repositories, with a YAML config file checked into source control. It is a Ruby gem, MIT licensed, and best suited to teams already running Ruby tooling.
Who is it for?
Adopt sds/overcommit if your repositories already run Ruby tooling and you want hook configuration committed alongside the code that the hooks check. Skip it if your contributors do not have a Ruby runtime, or if you want a single hook runner shared with non-Ruby projects.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem: Git hooks live outside version control

Git hooks are per-clone files under .git/hooks. Git does not track that directory, so a hook written on one machine does not travel with the repository. Teams work around this with shell scripts that copy hooks around, or with documentation telling new contributors what to install. Both approaches drift.

Overcommit addresses that by storing hook configuration in the repository and installing a dispatcher into .git/hooks. The README frames the project as a tool to manage and configure Git hooks, with two properties that matter: support for a wide variety of hooks usable across multiple repositories, and the ability to define hooks specific to a repository which are stored in source control. The second property is the one that changes daily work, because it means the hook definition is reviewed in the same pull request as the code it validates.

The audience is narrow but real: Ruby shops, and any team willing to install a Ruby gem on developer machines and CI runners. If your project has no Ruby in it at all, you are adding a runtime dependency to get hook management.

How Overcommit dispatches hooks and reads .overcommit.yml

The repository layout shows the shape of the system. There is a config/ directory holding default hook configuration, a lib/ directory with the implementation, a libexec/ directory, a bin/ directory with the executable, a template-dir/ used for the Git template mechanism, and a .overcommit.yml at the repository root that configures Overcommit's own hooks. The README's table of contents lists hook categories by Git event: CommitMsg, PostCheckout, PostCommit, PostMerge, PostRewrite, PreCommit, PrePush and PreRebase.

So the data flow is: Git fires a hook event, the installed dispatcher reads .overcommit.yml, resolves which hooks apply to that event and to the files in play, runs them, and aggregates results into a pass or fail. Hooks are grouped into categories, and the README documents an ALL hook that applies across categories. Concurrency is a documented configuration concern, which implies hooks in a run are not necessarily executed one at a time.

Two configuration details are worth knowing before you write anything. The gemfile option controls which gem versions are available during hook runs, which matters if you use Bundler, since a hook invoking a linter needs the same gem set your project uses. The plugin directory option lets hooks live outside the gem. There is also signature verification, with a documented way to disable signature checking, which suggests Overcommit treats hook configuration as something that can be tampered with.

The README carries one explicit warning in its PreCommit section: pre-commit hooks cannot have side effects. That is a real design boundary. A pre-commit hook that rewrites files or touches the index will not behave the way a naive author expects, and Overcommit states the constraint rather than working around it.

Installing the gem and running your first hook

The README recommends an environment where gem install works without sudo, and suggests a Ruby version manager such as rbenv or rvm. Requirements state Ruby 2.6 or newer, with best effort on Windows.

The install is a single gem command:

bash
gem install overcommit

Then, in a repository, the README's example creates a project, initializes Git, and installs the hooks:

bash
mkdir important-project
cd important-project
git init
overcommit --install

After that, hooks run automatically when the matching Git event fires. To see what is available in the current repository, use the list flag:

bash
overcommit --list-hooks

To run the pre-commit checks manually against every tracked file, rather than waiting for a commit, the README documents this flag:

bash
overcommit --run

There is also a diff mode that runs the pre-commit hook against changed files relative to a reference, written in the README as --diff <ref>. If you want Overcommit in every repository you clone from now on, the README gives a shell export that points Git at Overcommit's template directory:

bash
export GIT_TEMPLATE_DIR="$(overcommit --template-dir)"

Expect the first run to be the slow one. Each enabled hook may shell out to a separate executable, and the README warns that most hooks display a warning if a required executable is unavailable, which means a missing dependency shows up as a warning rather than a hard stop.

Skipping, disabling and the escape hatches you will actually use

Every hook system needs an exit, and Overcommit provides three with different scopes. The SKIP environment variable takes a hook name and excludes it for one command:

bash
SKIP=RuboCop git commit

The ONLY variable inverts that, running a whitelist instead:

bash
ONLY=RuboCop git commit

Setting required to true in a hook's configuration defeats SKIP for that hook. The README says you will see a warning that the hook is required and the hook will still run. That is the right default for a check you consider non-negotiable, and it is also the setting most likely to cause friction during an incident when someone needs to commit a fix immediately.

The third escape is total. Setting OVERCOMMIT_DISABLE turns hooks off for a scripted git invocation:

bash
OVERCOMMIT_DISABLE=1 ./my-custom-script

Color output is controlled separately through OVERCOMMIT_COLOR, which accepts 0 to disable it, useful when hook output is being captured into a log where escape sequences are noise.

The README does not document a rollback path for a hook that has already been committed to the repository. Uninstall is documented as removing hooks and restoring what was backed up, but the README is silent on what happens when a broken hook configuration is already on main and every contributor pulls it.

Where Overcommit is the wrong tool

The dependency model is the sharpest limitation. Overcommit itself is a Ruby gem, and the README is direct that some hooks have third-party dependencies, naming scss_lint as an example for SCSS files. The README's guidance is that you must ensure your development environment already has those dependencies installed. Overcommit orchestrates; it does not bundle the linters it invokes.

That has a practical consequence for polyglot repositories. A Python or Go project can use Overcommit, but every contributor and every CI image now needs Ruby 2.6 or newer purely to run the hook dispatcher. For a small team that already ships a Ruby service, that cost is zero. For a Go monorepo with no Ruby anywhere, it is a new runtime in the critical path of every commit.

The pre-commit side-effect warning is the second boundary. If your workflow depends on a pre-commit step that formats files in place and stages the result, Overcommit's documented constraint says that is not how pre-commit hooks should behave here. Move that work to a different stage or a different tool.

Finally, the README does not describe a hosted or centralized mode. Configuration lives in the repository. There is no server component described, so any expectation of central policy enforcement across an organization is not supported by what the README documents.

Compared with pre-commit, and the maintenance picture

The closest alternative in shape is pre-commit, which solves the same problem of version-controlled hook configuration but is written in Python and installs hooks as isolated environments per hook. The difference in approach matters more than the feature list. pre-commit manages each hook's environment for you and fetches hook repositories by revision, so a linter version is pinned in the config. Overcommit expects the dependency to exist in your environment, with the gemfile option available to control gem versions during hook runs when you use Bundler. If your team is Ruby-native, Overcommit's model matches how you already install tooling. If your team is Python-native, pre-commit's model removes a class of environment problems that Overcommit leaves to you.

On maintenance: the repository is not archived. The most recent release listed is v0.73.0 on 2026-09-06, following v0.72.0 on 2026-08-01 and v0.71.0 on 2026-06-10. Three releases in roughly three months is a steady cadence, and the last push to the default branch was on 2026-09-06.

Licensing is MIT, per the repository's MIT-LICENSE file. MIT is permissive: it allows use, modification and redistribution with the licence text retained. This is not legal advice, and if you redistribute Overcommit inside a product, have someone check how you handle attribution notices. The practical implication for most teams is minimal, since you are installing a gem rather than vendoring it.

Editorial conclusion

Adopt sds/overcommit if your repositories already run Ruby tooling and you want hook configuration committed alongside the code that the hooks check. Skip it if your contributors do not have a Ruby runtime, or if you want a single hook runner shared with non-Ruby projects. Verify first that Ruby 2.6 or newer is available on every machine that will commit, and that each third-party executable your enabled hooks call is present, since the README notes most hooks only warn when a required executable is missing.

Frequently asked questions

What does overcommit mean in this context?

In this context it is the name of a Ruby gem that manages and configures Git hooks. You install it with gem install overcommit and then run overcommit --install in a repository to install the hooks.

How do I get sds/overcommit running on Linux?

The README targets Ruby 2.6 or newer on *nix, with best effort on Windows. Install the gem without sudo, using a version manager such as rbenv or rvm, then run overcommit --install inside the repository.

How do I skip a hook in Overcommit?

Put the hook's name in the SKIP environment variable, for example SKIP=RuboCop git commit. If you prefer a whitelist, use ONLY instead. A hook configured with required set to true will warn and run anyway.

How do I turn Overcommit off for a single git command?

Set the OVERCOMMIT_DISABLE environment variable for that command, as in OVERCOMMIT_DISABLE=1 ./my-custom-script. Color output is controlled separately with OVERCOMMIT_COLOR.

Does Overcommit install itself into every repository I clone?

Only if you set it up that way. The README documents exporting GIT_TEMPLATE_DIR to the output of overcommit --template-dir, which makes Git use Overcommit's directory as the template for new .git directories.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sds/overcommit on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sds-overcommit.svg)](https://hysenlabs.com/projects/sds-overcommit)