Nice GIT status page

date: Wed Sep 02 2020

I like to see the progress I make with my projects - or see remaining skeletons of the side projects that didn’t make it because I lost interest. However I like the github commit calendar, so It had to look a bit nice. Turned out it was quite easy - which I like. Check out git-cal. Download from this site or install from your distro. For my a simple xbps-install git-cal worked, however I couldn’t find git-cal in debian based distro’s. Than again, it’s a perl script (as is git) so it should not be to hard. The added script is a basic bash script so no complexity there.

Sample page: for this page Sample page dropped when moving to linux containers. Will return if I can find some time.

I found one issue which I could not figure out. Although git-cal generates correctly on a terminal and ansi2html translates this to <pre> text the calendar still does not render correctly on windows machines. Than again, it does on Linux and Mac, so who cares ;-)

So; prerequisites

  • a webserver, I use nginx, and decide where you want the pages in your site; my setup is accepting user directories, so I will put the resulting pages into ~git/public_html
  • a local git server (duh)
  • install git-cal (see above)
  • bash script for converting terminal output into html. Get it here


  • adjust git-call to your likings, eg change color or as I did add branch as option (see below)
  • create update_html script and add to crontab

Adjust git-cal to your likings

This is pretty straightforward, since it’s a script and easily readable. Eg search for colors if you would like to adjust the colors. I added a --branch option to be able to generate a git-call from the branch with the most recent commit. Therefore I copied git-call to /usr/local/bin/git-call and edited the following:

$ diff /sbin/git-cal /usr/local/bin/git-cal
< my ( $help, $period, $use_ascii, $use_ansi, $use_unicode, $format, $author, $filepath );
> my ( $help, $period, $use_ascii, $use_ansi, $use_unicode, $format, $author, $branch, $filepath );
<     'author=s'    => \$author
>     'author=s'    => \$author,
>     'branch=s'    => \$branch
>     $command .= qq{ "$branch"} if $branch;

update-html script

I have git user running a crontab every hour to run this script. Since git is configured to use git-shell updating crontab via root: crontab -u git -e

# crontab for user GIT
4 * * * * ~/git-shell-commands/update_html
4 4 * * 0 rm -rf ~/public_html/*; ~/git-shell-commands/update_html '90.days.ago'

This will run every our checking for recent updates within 1hr window (the default in the script) and clean up and regenerate all within the last 90 days every week (in order to shift the calendar ;-0)

And finally the script itself. The script checks for:

  • any projects updated within the given time frame
  • finds the branch with the latest commit
  • and generates: git calender, git branches,git last diff, and the git log (limited to 90 days)
    The script is filtering Author email (actually everything after first-name, but verify this anyway if you don’t want your email address online)

mkdir -p $BD

umask 022

for i in *.git */*.git
  cd ~/$i
  LB=`git for-each-ref --count=1 --sort=-committerdate refs/heads/ --format='%(refname:short)'`
  if [ -n "$(git log $LB --all --since=$DAYS)" ]; then
    mkdir -p `dirname ${FO}`
    ( echo "${i^^} - branch : ${LB^^}"; echo; echo;
      echo "== Git Calendar =="; echo; /usr/local/bin/git-cal --branch=$LB --period=-6; echo; echo;
      echo "== Git merged branches == "; d=`git for-each-ref --sort=-committerdate refs/heads/ --merged=HEAD --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - (%(color:green)%(committerdate:relative)%(color:reset))'`; echo "${d:="  none"}"; echo
      echo "== Git unmerged branches =="; d=`git for-each-ref --sort=-committerdate refs/heads/ --no-merged=HEAD --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - (%(color:green)%(committerdate:relative)%(color:reset))'`; echo "${d:="  none"}"; echo; echo
      echo "== Git lastdiff =="; echo; git show -M -D $LB --color  -- . ':!package-lock.json' ':!static/global.css'| sed 's/\(Author: \w*\)\(.*\)/\1/'; echo; echo;
      echo "== Git log (upto 90days ago) =="; echo; git log $LB --max-count=90 --since '90.days.ago' --color --graph --stat --all | sed 's/\(Author: \w*\)\(.*\)/\1/'
     ) | /usr/local/bin/ --bg=dark > ${FO}.html
     touch -d `git log $LB -1 --format=%cI` ${FO}.html

# auto cleanup
find $BD -atime +90 -delete

exit 0

Done, hourly project updates and weekly full resync for all open projects!