Logging Git commits with doing

[Tweet : nvALT]

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:


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:


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:


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)"
    git log --pretty=format:"%s @${PWD##*/}%n%b" -1 HEAD | doing done

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:

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.