Commit Sounds

Playing a sound as you commit or push code can be a satisfying reward for a job well done and can help form a healthy atomic habit.

Commit Sounds
Photo by Pawel Czerwinski / Unsplash

Committing code regularly is a good habit to get into. If you also push your changes to a remote repository (on a branch where appropriate) as part of a closing out the day routine, it is a great way to share progress, safeguard your work from hardware failures and gives a sense of completion to the working day.

However, I’ve found that many developers really hate to share their work before they are “done” with the changes. This has led to issues where changes that had been in progress for several days began to block other members of the team. The developer making the changes was absent due to illness and this meant that the change remained in limbo while they were out. No one could pick up the task as they could not be certain what progress had already been made.

I am guilty of leaving code on my computer overnight myself. If you are working on a change right up to home time, the choice is often to just go home without committing or to stay a few minutes late – I rarely choose to do the latter! I want to build a habit that I close out my day, every day, by committing and pushing whatever changes I have made that are relevant to the feature or bug I’ve been working on.

Atomic Habit

This is the kind of Atomic Habit that James Clear wrote about in his book (you can see my review for more details). The change by itself is not going to rock the world, but it compounds up over time to make positive outcomes that go far beyond what is obvious.

A few things that spring to mind (beyond the obvious one mentioned above of a change stuck in limbo) are:

  • other team members can check progress, possibly even reviewing the changes and giving feedback early, or offering to help with the change
  • if your code changes are going to be visible before they are “done”, it may help to build better habits in writing cleaner code in the first place
  • committing as the last act of the day gives a sense of “I'm done” allowing you to switch off from work and not worry about things until the next day

Mind you, if something is really not ready for sharing it should probably not be committed or pushed. You don’t have to add every file to the commit, just the relevant changes. This means that it is important to allow sufficient time to double check what has been modified. Be careful not to commit a password that was entered in haste in a config file just to get an integration test to work. Write clean code and only commit appropriate changes.

Satisfying

So how can Atomic Habits help? James mentioned som laws in his book to help form good habits: make it obvious, make it attractive, make it easy and make it satisfying.

You can use a calendar reminder to make it obvious but even with this, I found I often simply ignored the reminder. It will only be easy if you don't have to go through a lot of spurious changes. I’m not sure how to make it attractive, but I did have an idea for making it satisfying. At least a little.

lots of happy cubes sitting on a plane surface.
Photo by Shubham Dhage / Unsplash

My idea is to play a sound clip after the code is committed successfully that is supposed to be a kind of reward for a job well done. There are many memes and soundbites out there that can be harnessed to give a well-done sound after committing.

The following is my solution for adding a commit hook that plays a random sound file from a certain folder. Download whatever files you think will make you happy or smile after hitting commit. My Mac has a set of sound files in /System/Library/Sounds/ so in the examples that follows I will use that as the source folder, but there are plenty of good sounds out there to play with.

Hooks

I’m using the hooks Git provides for this; most source control system have similar concepts. A hook is just a script that is run by Git before or after certain actions. For example, before committing a hook might run a linter, or after pushing code a script might update a ticketing system.

Coat hooks
Photo by Steve Johnson / Unsplash

Git looks for hook scripts in .git/hooks and each repository is generated with a few examples. Here are the contents of that folder:

$ ls .git/hooks/
applypatch-msg.sample		
post-update.sample		
pre-push.sample			
prepare-commit-msg.sample
commit-msg.sample		
pre-applypatch.sample		
pre-rebase.sample		
update.sample
fsmonitor-watchman.sample	
pre-commit.sample	
pre-receive.sample

There are plenty of samples there; removing the sample suffix will enable the script. We are interest in the scripts with two parts, which indicate when to run (e.g. pre or post) and the action to which it is associated (e.g. commit or patch). I’ll use the post commit hook to play the sound in the examples below.

Random Sounds

I want to play a different sound each time I commit something as I don’t want the sound to become stale. I can use the sort -R program in Linux to arrange the files in my sound folder with a random order. Then I just need to take a single file using tail -1 to play just that sound using afplay. The pipe, |, joins the programs together.

Here are the contents of post-commit that plays a random sound after each successful commit.

#!/bin/sh

cd /System/Library/Sounds/

ls |sort -R |tail -1 |while read file; do
  afplay $file > /dev/null 2>&1 &
done

The ampersand at the end of the line will play the sound in its own process, so that control comes back to the terminal or IDE immediately. Any output or error in the file is just being discarded into /dev/null. Thanks to this post for getting the command to play the sound – my contribution is to randomize the selection of the sound.

You could add this to any Git repository you want to get this for, but if, like me, you operate in many such repositories, you may want to set this up globally. The next section shows how to do this.

Note that Git hooks do not get committed by default, so if you have added them to a repository locally, additional steps (not covered here) are required to share with your team.

Global Sounds

Git checks configuration for the property core.hooksPath and if set will use this to find hooks instead of .git/hooks. This can be set globally as well as per repository.

First thing is to place the hook script outside any particular repository. For this example I’ve moved it to ~/Documents/code/git/hooks/.

Setting the configuration property at global level can be done with this command:

git config --global  --add core.hooksPath "~/Documents/code/git/hooks/"

Now no matter what repository I commit to, and using any means, such as the command line, IntelliJ or Sourcetree, I will get a random sound file played to congratulate me on a job well done.

Since I work from my home office, it is unlikely to cause anyone any offence to play a sound each time that I commit my work. If you use this idea try to be mindful of those who share your space. Personally I would love to hear a whole stream of commit sounds as the clock approaches home time, signifying that my whole team is closing off their days with a commit.

Now all I need to do is to come up with some decent soundbites to play.