Hint: this article is tested on GNU/Linux and should also work on mac systems by slightly changing the directories used.

Table of contents

The complete script of this article can be found on github.

The problem

Nobody loves tracking time. Especially not developers. When a developer is in “creation mode”, track of time is lost. Tracking time frequently is a huge loss of focus and productivity.

Tracking time once a day is difficult as well because the details often get lost. Especially when project-hopping or working on many issues, it is often impossible to recall how much time has been exactly spent on what.

Like most developers, I love git and I use it for everything. My projects, meeting notes, even my personal to-do and grocery shopping list has a git repository. So I want to track every git command that I run, with:

  1. Current time
  2. Current directory
  3. Git command
  4. Sorted in one file per day

The solution

The plan is to create a wrapper for the git executable. Most IDEs and git GUIs will use the git executable from $PATH. So if that one is wrapped, it should cover most things.

For one, the real git executable needs to be found. This, will probably be in /usr/bin/git. It can be found by typing which git

$ which git
/usr/bin/git

It is important to know how $PATH works. The directories of $PATH are separated by directory-separators (usually :). To find an executable, the system will iterate through the directories and take the first executable that it can find with the given name.

Usually, the highest priority should be /usr/local/sbin, which is, the local scripts (like the future git wrapper) directory. To override the existing git executable, the wrapper must therefore be in /usr/local/sbin.

#!/bin/bash

GIT="/usr/bin/git"

On GNU/Linux, the logging directory is /var/log. Here, the best practice is to create one folder per application and put the log files inside that folder.

Since git does not run as root, the folder needs to be writable for whatever user runs git. In my case, more than one person is using git on the machine. Therefore, I decided to use a 777 chmod. Depending on how many users use the machine and where the file is stored, another option would be to simply change the ownership of the directory.

$ sudo mkdir /var/log/gitwrapper
$ sudo chmod 777 /var/log/gitwrapper

The logfile can then be defined in the script.

LOGFILE="/var/log/gitwrapper/`date +%Y-%m-%d`-actions.log"

It would also be possible to put one log file per user in each user’s home directory. But in my situation, I chose to have a global one in /var/log.

If git is run for the first time in a day, the daily file must be first created

# If the logfile doesn't exist yet, create
if [ ! -f $LOGFILE ]; then
	touch $LOGFILE	
fi

After that, the complete git command and the current directory can be saved into the log file

echo `date '+%Y-%m-%d %H:%M:%S'`	`pwd`	$@ >> $LOGFILE

The most important part, is to pass all arguments to the actual, predefined git executable:

$GIT "$@"

The scripts needs to be called git, be marked as executable and saved in /usr/local/sbin or to a higher priority location of $PATH according to your system.

$ chmod +x git
$ sudo mv git /usr/local/sbin

Evert action done in the repositories should now be tracked accordingly:

2018-03-19 10:20:52 /home/fish/Documents/projects/daccurso add .
2018-03-19 10:21:33 /home/fish/Documents/projects/daccurso commit -m css changes
2018-03-19 10:22:49 /home/fish/Documents/projects/daccurso push

Now, every git command is tracked in a log file.