Commit Sounds
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.
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.
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.