#!/usr/bin/perl

# tig-like git log output. Used when tig is not available or broken.

# Copyright (C) 2013  Simon Ruderich
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


use strict;
use warnings;

use POSIX ();
use Term::ANSIColor qw(colored);


my $color_graph         = 'yellow';
my $color_hash          = 'cyan';
my $color_ref_sep       = 'cyan';
my $color_ref_head      = 'cyan bold';
my $color_ref_branch    = 'green bold';
my $color_ref_reference = 'red bold';
my $color_author        = 'magenta';


my $format = '%h'  . '%x00' # abbreviated commit hash
           . '%at' . '%x00' # author date
           . '%an' . '%x00' # author name
           . '%s'  . '%x00' # subject
           . '%d';          # ref names
my $cmd = "git log --all --graph --format='$format'";
open my $fh, '-|', $cmd or die $!;

while (my $line = <$fh>) {
    # History graph line.
    if ($line =~ m{^([|/\\_ ]+)$}) {
        print colored($line, $color_graph);
        next;
    }

    # Commit line.
    $line =~ /^([ *|]+) (.+)\x00(.+)\x00(.+)\x00(.+)\x00(.*)$/ or die;
    my $prefix  = $1;
    my $hash    = colored($2, $color_hash);
    my $date    = POSIX::strftime('%Y-%m-%d', localtime($3));
    my $author  = colored($4, $color_author);
    my $message = $5;
    my $refs    = $6;

    # Color "graph".
    $prefix =~ s/\|/colored($&, $color_graph)/ge;

    # Strip leading whitespace.
    $refs =~ s/^\s+//;

    printf "%s %s %s %s %s %s\n",
           $prefix, $hash, $date, $author, $message, $refs;
}

close $fh or die $!;
