Оvercommit - convenient Git hook manager

Voldemar Duletskiy, Ruby developer, Evrone, Moscow Ruby Meet-up 6 report
01 August 2017   1985

Dynamic, open source programming language with a focus on simplicity and productivity, it has an elegant syntax that is natural to read and easy to write.

Hello Ruby fans! Today we will talk about Overcommit - the convenient management of git-hooks.

Imagine that you have a small project with a micro-team of three or four people, including the manager. Deadline is near, but you cannot lower the quality of the code. You don't wanna use CI and there are no extra money for it.

What is hooks and where are they located?

It is the scripts that are executed at certain event. You can view all existing hooks by running the following command:

ls -la .git/hooks

You will see this listing:

-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 commit-msg
-rwxr-xr-x   1 voldemar  staff  3755 28 июн 16:39 overcommit-hook
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 post-checkout
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 post-commit
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 post-merge
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 post-rewrite
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 pre-commit
-rwxr-xr-x   1 voldemar  staff   673  2 Jun 14:37 pre-commit.sh
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 pre-push
-rwxr-xr-x   1 voldemar  staff  3755 28 Jun 16:39 pre-rebase

Hook is an executable file, which can content anything, including the Ruby code.

Why it is cool?

  • You can put linters like rubocop to the pre-commit hooks. It will not allow you to commit substandard code
  • You can hang up rspec to the pre-push hooks, and if the tests are dropped - cancel code sending
  • If you are already actively using hooks - you don't need to drag them from one repository to another, they all lie in .ovecommit.yml in a convenient format

Ruby static code analyzer, based on the community Ruby style guide

If you suffer from dispersion and you are sick of messages from your CI that tests have dropped again, or the ruby-cop found a million syntactic violations (or your colleagues in the code-review process). If you are an experienced developer, a good set of hooks seriously discourages young developers and reduces your code-review time. 



gem 'overcommit'

Execude from the consol:

bundle exec overcommit --install

 Now let's edit .overcommit.yml file

    enabled: true
    command: ['bin/bundle', 'exec', 'rubocop', '-R']
    on_warn: fail
    enabled: true
    command: ['bin/bundle', 'exec', 'haml-lint', 'app/views/']
    on_warn: fail
    enabled: true
    command: ['bin/bundle', 'exec', 'scss-lint']
    include: 'app/assets/**/*.scss'
    on_warn: fail

    enabled: true

We can see here that the launch of the rubocop scripts is describled in nice forman. haml-linter, sccs-linter and tests runs just before the commit.

In order to enforce hook running this should be executed:

bundle exec overcommit -R

Now, with every attempt to commit something, checks will be performed firstly.


Underwater rocks

If there are a lot of tests or they are dropping randomly - if you already have a habit to brew coffee while test runs, it's better to chop the hook responsible for running the tests. If they fall randomly - fix the tests at last, damn it.

Integration with Rubymine - I have serious problems with the integration of Overcommit and Rubymine

Continuous Integration

The practice of merging all developer working copies to a shared mainline several times a day

Overcommit and CI integration - if you still decide to connect CI, then most likely it already provides validation for the code. Often, their rules don't match and you have to adjust the settings, for example Rubocop under CI, or vice versa.

You can skip hooks by running git commit --no-verify


Overcommit is an excellent utility for maintaining a project in good shape for small teams. It will allow you not to grab your head every time after creating a pool of the requester with exclamations "Damn, I forgot to use rubocop again!" or "Damn, all the tests fell!".

M. Schirp: "I personally feel no big love for Ruby"

Interview with Markus Schirp, creator of the popular tool Ruby Mutation Testing and related gems and speaker at Ruby Russia 2018
19 September 2018   284

Markus Schirp is entrepreneur and post Ruby freelance developer and consultant, "exorcist of dynamic language." The creator of the popular tool Ruby Mutation Testing and related gems. DataMapper and ROM core team alumni, speaker at Ruby Russia.

Markus Schirp
Markus Schirp

The first question is about Mutant. What’s the main things about it? What your speech will be about, at Ruby Russia?

I will present the backstory of the Mutation Testing tool Mutant. The idea is to make the audience familiar with the key concepts of this tool. The audience will be made aware about the different levels of coverage, their meaning and value.

It will shed some light on some areas of the Ruby language which people are typically content with but shouldn't. Because Ruby language is often basically a fancy way to shoot yourself in the foot.

What’s the story of development of Mutant?

It’s actually myself getting hooked up on a project called DataMapper, and its next iteration DataMapper 2 that later turned into ROM. The project lead Dan Kubb to write a Relational Algebra library called axiom to back these new developments. And he wrote this axiom library with a strategy he calls ‘Developing with Constraints’. Featuring lots of metric tools and Mutation Testing.

The mutation testing tool of that time, was called Heckle and had various operational and conceptual flaws. At one specific moment I was like “Skrew it, I will not even attempt to fix Heckle. Let’s just write a new one and address all the Mutation Testing scaling problems we have in DataMapper 2”

This was 5 or 6 years ago, mutant went through several iterations meanwhile. All of these iterations where not driven by my own desire to write open source but by need of commercial projects I was contracting to. So the development of mutant is driven by my consulting activities.

Each time I go into a new Ruby project, I feel a need to be sure about a specific piece of code. And Mutant is the tool I use for this.

So, commercial clients want to use Mutant?

Yes, a sign of this is that all the features you see are the common features commercial clients requested over the last years. There are some features that are not in the public version, because the client did not give me the right to put them into the open source. But sometimes client says: “No problem if someone will benefit from this” which I really like.

At the moment I’ve left DataMapper 2 I’ve never wrote a feature just for fun. Just side effects of the commercial use.

I personally feel no big “love” for Ruby language, it’s just a tool for me. Mutant is a way to make Ruby more efficient. Mutant is hard to get start with but then it helps you a lot. This learning curve is something to address.

It’s totally OK. When you use a free gem...haha!

95% of free gems are just a hobby side projects. They are not ready for commercial use. The authors make them out of their personal interest. And I do not blame them for this.

I advise development teams in a commercial background to be aware of this property when pulling stuff from RubyGems.

I’ve only read the README file of Mutant at GitHub. But I really don’t understand what I should do.

That’s the reason I have to spend some time writing the readme or spend some time writing a more entry level documentation.

I was silent in the community for like 3 years for private reasons. I got two more kids and I moved to a different country.

Ruby Russia is the first time I’ve accepted an opportunity to speak again. I want to use the time I spend on preparing the talk and the worksop as material source for more documentation.

You will start to prepare it now, right?   

I’ve started, but I’ve started backwards. I did not start with the slides, instead I’ve created the workshop material. Working myself backwards to the slides.

The idea is to have the workshop based on a real world example taken from an open source project that uses rails and rspec.

As far as I understand, you’re using another programming language instead of Ruby.

That’s not really true. I use Ruby a lot but only if there is a commercial reason to do so. And this reason typically only exists when rescuing legacy applications that are about to collapse under their own code weight.

In such a scenario one cannot go in and simply replace Ruby in one big step. Incremental refactoring / strangling of the Ruby code is my main work. And during this process I have my hands at Ruby a lot, and here Mutant is my main tool to anchor refactoring / change cycles.

What languages do you prefer also?

Mostly Haskell. To me currently it’s at the optimum equilibrium between production usability and work to achieve a correct program that has business value.

The Haskell Type checker can guarantee many properties already, properties I’d have to fight for hard in Ruby.

There are also some great other languages, or language extensions upcoming. Dependent types will push “correctness after passing the type checker” to the next level.

Do you think Ruby and Rails have future?

Ruby and Rails have a perceived low entry bar helps people to get to the point of having a business. As long as people think Ruby and Rails have this property there is a future.

So, a little heretic statement but Rails deterministically produces applications which cannot grow anymore because of inherent complexity, language and framework choices. But its okay to buy into that tech debt if you have a business reason to do so. Just have a payment plan ready.

Yes, sure. What do you think about Rust?

Conceptually, I really like it. But I have not use it a lot right now. I had no real reason as the projects I’m on could not play out its strength, compared to other choices I had.

I’m doing backend development mostly. Or let’s name it “mass RPC with domain logic”. Here it’s more important I can guarantee a specific program is correct and secondarily efficient. Rust is computationally very efficient, but to be efficient it requires to manage more low level details by hand. This takes time I better spend on optimizing the high level IO pattern (grouping RPCs, minimizing round trips etc, verifying transactional properties, ...) before I optimize the individual primitive via a language that gives me tight control to do so.

If I were on a more computation heavy subject, like a video codec: Rust would be the tool I choose.

And the last question. What can you advise for a newbie programmers?

As a new programmer, find a pet project and align this pet project with non programming interest of yours to keep engaged for a long enough till learning programming has a positive return of investment.

Very interesting! And maybe it's working, haha!

Haha, yes, that’s how I got started.

Great advice! Thank you for the interview! Will see you at Ruby Russia.

Meet Markus and ask a question in person at Ruby Russia 2018!

Questions were asked by Mikhail Morgunov, developer from Evrone.