A gem to install and manage a configurable (but opinionated) set of Git hooks. Originally written for use at Causes.
In addition to supporting global hooks, it also allows teams to define plugins
specific to a repository (installed in the .githooks directory).
Read more about overcommit on our engineering blog.
The overcommit is installed as a binary via rubygems:
gem install overcommit
You can then run the overcommit command to install hooks into repositories:
mkdir important-project
cd important-project
git init
overcommit .
overcommit also accepts a handful of arguments, which can be enumerated by
running overcommit --help.
At Causes, we install all of the hooks via the
--all flag. In absence of this flag, you will be given the default template.
For more information, try overcommit --list-templates.
Some of the lints have third-party dependencies. For example, to lint your SCSS files, you're going to need our scss-lint gem:
gem install scss-lint
Other useful utilities include jshint, which can be installed via npm:
npm install -g jshint
There are two types of hooks installed by this utility. post-checkout,
post-merge, and prepare-commit-msg are all simple shell scripts rolled by
hand for use at Causes. We think other people may find them useful.
The second, more interesting type is the Ruby-based, extensible checks. These
are currently pre-commit and commit-msg. These are used for checking the
validity of the code to be committed and checking the content of the commit
message, respectively.
You can see the various sub-hooks available in the lib/overcommit/plugins
directory:
>> tree lib/overcommit/plugins
lib/overcommit/plugins
βββ commit_msg
βΒ Β βββ change_id.rb
βΒ Β βββ hard_tabs.rb
βΒ Β βββ release_note.rb
βΒ Β βββ russian_novel.rb
βΒ Β βββ single_line_subject.rb
βΒ Β βββ text_width.rb
βΒ Β βββ trailing_period.rb
βββ pre_commit
βββ author_name.rb
βββ causes_email.rb
βββ coffee_lint.rb
βββ css_linter.rb
βββ haml_style.rb
βββ haml_syntax.rb
βββ js_console_log.rb
βββ js_syntax.rb
βββ python_flake8.rb
βββ restricted_paths.rb
βββ ruby_style.rb
βββ ruby_syntax.rb
βββ scss_lint.rb
βββ test_history.rb
βββ whitespace.rb
βββ yaml_syntax.rb
Most of them are straightforward lints, with an easter egg or two thrown in for good measure. Because some of these are Causes-specific (for instance, we insert a 'Change-Id' at the end of each commit message for Gerrit code review), the default installation will skip loading some of these checks.
Out of the box, overcommit comes with a set of hooks that enforce a variety of
styles and lints. However, some hooks only make sense in the context of a given
repository.
At Causes, for example, we have a repository for managing our Chef cookbooks. Inside this repository, we have a few additional lints we run before commits are pushed:
>> tree .githooks
.githooks
βββ pre_commit
βββ berksfile_source.rb
βββ cookbook_version.rb
βββ food_critic.rb
food_critic.rb contains a subclass of HookSpecificCheck that runs
Foodcritic against the cookbooks about to
be committed (if any).
The meat of it looks like this:
module Overcommit::GitHook
class FoodCritic < HookSpecificCheck
include HookRegistry
COOKBOOKS = 'cookbooks'
@@options = { :tags => %w[~readme ~fc001] }
def run_check
begin
require 'foodcritic'
rescue LoadError
return :stop, 'run `bundle install` to install the foodcritic gem'
end
changed_cookbooks = modified_files.map do |file|
file.split('/')[0..1].join('/') if file.start_with? COOKBOOKS
end.compact.uniq
linter = ::FoodCritic::Linter.new
review = linter.check(changed_cookbooks, @@options)
return (review.warnings.any? ? :bad : :good), review
end
end
endIn addition to the Ruby-based plugin system, overcommit also ships with a few
handy shell scripts:
-
post-checkoutrunsctagsafter checkouts to aid in tag-based navigation. We use this in combination with Vim by adding.git/tagsto thetagsconfiguration:set tags=.git/tags,.tags -
post-mergechecks for updated submodules and prompts you to update them. -
prepare-commit-msgsets up your commit message to include additional author information and note submodule changes when updating.
If you'd like to remove the hooks from a repository, just pass the --uninstall
flag:
overcommit --uninstall important-project
Pull requests and issues are welcome. New features should ship with tests so that we can avoid breaking them in the future.
Released under the MIT License.


