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:
git track init
to tell the tool which Git repo to use to record commit messages.git track start
andgit track stop
to start/stop recording time.git track todo
to edit your TODO list.git track report
to see a simple report of the hours worked recently.
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.