Overcommitting With Focus
By: Gideon Caller
Tags: Git, Programming, Productivity, Legacy Code, Cli

When we need to make changes to legacy code with no tests we often encounter the chicken and the egg problem. On one hand, in order to refactor the code, we need tests but on the other hand, if we want to add tests we need to refactor it first. When this happens we usually just make the changes and hope everything goes well. Is there anything we can do to increase our confidence while refactoring legacy code with no tests?

Enter Overcommitting

It turns out there is something we can do and it’s called Overcommitting. The idea is to rely on Git by constantly committing along the way (we can think of it as leaving behind a trail of breadcrumbs). This gives us the ability to “go back in time” in case we realize we’ve made an error (we can also Git bisect if we’re not sure when things went south).

How Does it Work?

Nicolas does a good job of describing the process of Overcommitting so I’ll just try to briefly summarize it:

Commit every 2 minutes. We want this to be as fast as possible so we don’t invest time in the commit messages (it’ll get squashed later anyway).

Interactively rebase every 30 minutes to squash the temporary commits. We do this in order to not be overwhelmed by the number of commits.

It’s important to remember that one of the ideas behind Overcommitting is to maintain focus. If we feel like 2 minutes is too short (because we’re barely making changes) we can lengthen the commit intervals or shorten the intervals if it’s too long. The same is also true for the squash intervals.

Keeping the Focus

When I was experimenting with Overcommitting, one thing that bothered me was the constant commit interrupts. It’s hard to focus on the task when we’re constantly interrupted by the need to commit. This made me wonder if I could somehow reduce the number of interrupts.

Automate the Disturbing Stuff

I decided that the best course of action is to automate the frequent commits. I was much less bothered by the longer squash intervals so I didn’t feel the need to automate them. Here are two very simple zsh/bash one-liners I used to not have to worry about the commit intervals:

Commit Until Next Squash

The idea here is to stop auto committing once we reach the squash phase

for i in {1..15}; do git commit -au -m "wip"; sleep 120; done

Note that:

We run for 2 minutes ( sleep 120 ) intervals 15 times.

) intervals 15 times. We only commit tracked files. If we want to include untracked files we can use -a instead of -au .

instead of . The content of the commit message is irrelevant which is why we chose “wip”.

Never Stop Committing

We run auto committing until we explicitly stop it

watch -n 120 git commit -au -m "wip"

What I usually do is run the git commit -au -m "wip" once and then just run watch -n 120 !! which makes watch run the last command. Another thing I tend to do is run the auto-commit in a small Tmux pane so I can watch over the automatic commits.

Summary

Overcommitting is simple yet handy. It provides some safety when we’re working on legacy code that has no tests. I also find it useful:

When I’m evaluating a problem.

When I’m spiking myself through some code.

Because it forces me to focus on the task at hand.

Making Overcommitting automatic is so simple that it’s a crime to not use it. Try it 🙂

As always, feel free to leave me feedback. I highly appreciate it.