Logging Git commits with doing
If you don’t use git and you’re not interested in command line logging, move along, nothing to see here. I promise this won’t go on forever, unlike my PopClip obsession.
I decided that commit messages in my local Git repositories would make a pretty good way to easily keep my doing
file up to date without double effort. You can run commands automatically when creating a commit using hooks. In this case, the post-commit
hook.
Edit .git/hooks/post-commit
in your repository with this:
#!/bin/bash
git log --pretty=format:"%s @${PWD##*/}%n%b" -1 HEAD | doing done
Then, chmod a+x .git/hooks/post-commit
.
doing
accepts input on STDIN, so you can pipe other commands directly to it. This one outputs the last commit message (the one you just wrote) with a format string that includes just the subject, a tag based on the name of the folder at the root of the repository, and any body of the post on a new line.
On time tracking
I’m going to talk a little more about time tracking with doing soon, after I take a break from this profitless project for a while. For now:
With the current version you can run doing today -t
and have it calculate the difference between start and finish for all entries with a @done(date) tag (which you can create for the last entry with doing done
at any time). This works with any of the show
commands as well.
doing --totals
will collect all the times and total them, as well as totals for common tags in the output. The totals are included at the end of the command output. Thus, if I tag all of my Marked-related entries with @marked, I can see at the end of the day exactly how much time I spent working on it vs. things tagged @writing or such.
Time tracking commit messages
The entry created by the Git hook will be marked @done with the current date. Since this will be the same as the timestamp, it will show up as an empty time when running doing show -t
(or --totals
). If you want to backdate the start date for time tracking purposes, you’d have to come up with a way to pass a --back "amount"
to the doing done
command. There are a couple of possibilities:
First, you could use the timestamp of the previous commit and assume that you’ve been working on the same repo since:
#!/bin/bash
git log --pretty=format:"%s @${PWD##*/}%n%b" -1 HEAD | doing done --back "$(git log --pretty=format:%ar -2 HEAD|tail -n 1)"
This has the drawback of the first commit always being dated since the last time you were working on the project. You could do some math before the commit and make sure it was in the last 3 hours, otherwise output it without the --back
:
#!/bin/bash
timenow=`date '+%s'`
lastcommit=`git log --pretty=format:%at -2 HEAD|tail -n 1`
if [[ $(($timenow - $lastcommit)) -lt 9000 ]]; then
git log --pretty=format:"%s @${PWD##*/}%n%b" -1 HEAD | doing done --back "$(git log --pretty=format:%ar -2 HEAD|tail -n 1)"
else
git log --pretty=format:"%s @${PWD##*/}%n%b" -1 HEAD | doing done
fi
Second, you could include a time specifier in the commit message and use a commit-hook
instead, having the hook strip the extra info out before it commits it.
I haven’t nailed down how I want to handle that yet. I’m using the first option right now, but the latter option seems the most useful, really.
Global hooks
You can make this hook default for repos. To make a global hook that installs when running git init
:
mkdir -p ~/.git_template/hooks
git config --global init.templatedir '~/.git_template'
git init --template ~/.git_template
touch ~/.git_template/hooks/post-commit
chmod a+x ~/.git_template/hooks/post-commit
Edit the new post-commit hook file with the script above. You can now run git init --template ~/.git_template
to include the hook with new repositories. You can do this in existing repos to add the hook, too, assuming you don’t already have a post-commit hook.
In ~/.gitconfig:
[alias]
init = init --template /Users/username/.git_template
Now, any time you run git init
, your hook will be included in the repo.
Also, the image at the beginning of the post is from an evening at Zizzle Karaoke in Vegas with the Engadget crew. Fond memories.