akuszyk.com

A blog about software engineering, collaboration, and--occasionally--Emacs.

View on GitHub

Tracking time and TODOs using Git

I like to keep track of the time I spend working so that I know if I’ve spent too, long or not enough time, at my desk each week. I also like to keep a simple list of things that I need to do that might fall outside of my normal work task management flow (e.g GitHub issues).

In the past have used MyHours for time tracking and Trello for task management. However, I’ve found both of these platforms have drawbacks for my needs.

When it comes to time tracking, MyHours (or any similar GUI-based system) requires one to manually remember to start and stop tracking time. This means it’s constantly something one has to be mindful of, and it’s easy to get it wrong. Systems like this are also generally quite complicated–they’re designed for people who need to track time across multiple workstreams, and who also might need to generate invoices off the back of them. My needs are simple–I just want to know how much time I’ve spent working each week, and ideally I want this integrated into my existing workflow.

Trello is a fantastic task management system, but it’s also very complicated if you just need a simple list of things to do. It’s not at your fingertips in a terminal, and it’s not co-located with other work/task tracking tools that I use. I want something simpler.

Git as a time tracker

It occured to me that time tracking could easily be achieved using the commit history of a Git repository. It already tracks the timestamps of commits, so all you really need to do is something like this:

git commit --allow-empty -m "start"

The --allow-empty flag means you don’t need to commit the contents of any files to the history, and can just use Git to record a message.

Git as a task tracker

A similar approach can be used for keeping track of a TODO list, although I wanted to maintain a list that I could update as I went–a bit like a file. However, I didn’t want to have to update a file and then commit changes to the Git history–I just wanted to use the same technique as above to record a rolling TODO list in my commit messages. This is relatively straightforward, with:

git commit --allow-empty --reuse-message <commit-sha>

If the commit referenced by commit-sha is the previous TODO entry, then this command will effectively create a new Git commit that re-uses the commit message of the previous commit.

Turning these ideas into a tool

Both of these approaches need a way to identify start/stop events and TODO entries in the commit history, without confusing the two or getting muddled up. That’s pretty easy using a simple pattern for the commit messages.

For example, to start tracking time I execute:

git commit --allow-empty -m "hours:start"

And to stop tracking time I execute:

git commit --allow-empty -m "hours:stop"

I do a similar thing for TODO entries:

git commit --allow-empty --reuse-message $(git log --oneline | grep 'TODOs' | head -n 1 | awk '{print $1}') --date "$(date)"
git commit --amend --allow-empty

Here, I --reuse-message to re-use the previous TODO message (which has TODO in it), and also update the date to $(date) (otherwise the date on the commit would be the same as the original commit.

Introducing git track

After a bit of experimenting, I wrapped up these ideas into a simple Git extension: git track. It’s still in it’s early stages, but you can see it (and use it) on GitHub.

Using git track is as simple as:

Integrating git track into my life

The real benefit of using git track comes from the fact that I no longer need to manually use a UI to keep track of my hours.

In the morning, I run a start.sh script that starts my mail client, Slack, etc. and also runs git track start.

To lock my screen, I use this script:

git track stop
i3lock -n
git track start

This means that whenever I lock my screen I automatically stop tracking time, and when I unlock it I start again.

And, at the end of the day, I have an end-of-day.sh script which simply:

git track stop
poweroff

It’s not rocket science, but it makes my life easier! I hope you find it useful too.