git-graph: do not count renames as huge additions and deletions
[u/fanf2/git-graph.git] / git-graph
CommitLineData
cce87900
TF
1#!/usr/bin/perl
2
3use warnings;
4use strict;
5
6use Getopt::Long qw{:config gnu_getopt posix_default};
37fadc81 7use POSIX;
cce87900
TF
8use Term::ReadKey;
9
10$0 =~ s{^.*/([^/]+)$}{$1};
11
cce87900
TF
12my %opt;
13GetOptions(\%opt, qw{
37fadc81 14 cancel|c
ebb589a0 15 height|h=i
37fadc81
TF
16 overlay|o
17 stack|s
dcf5f346 18 width|w=i
cb209060
TF
19}) or do {
20 print STDERR <<END;
21usage: git-graph [options]
22 -c | --cancel +/- counts cancel out
23 -o | --overlay +/- counts are overlaid as # (default)
24 -s | --cancel +/- counts are stacked
25 --height [n] Set height of graph
26 -h [n] (height of terminal is default)
27 --width [n] Set horizontal scale
28 -w [n] (fit to width of terminal by default)
29END
30 exit 1;
31};
cce87900 32
22e04a63 33$opt{overlay} = 1 unless $opt{cancel} or $opt{stack};
cce87900 34
37fadc81 35my @terminal = GetTerminalSize;
c562dc48 36my $width = $terminal[0] - 11;
ebb589a0 37my $height = $opt{height} // $terminal[1] - 2;
37fadc81 38
cce87900
TF
39my %add;
40my %del;
41
42my $addmax = 0;
43my $delmax = 0;
44my $canmax = 0;
45
c562dc48
TF
46my $date;
47
dc5e876a 48for (qx{git log --find-renames --shortstat --pretty=format:%ct --since='$height days ago'}) {
c562dc48
TF
49 next if m{^\s*$};
50 if (m{^(\d{10})\n$}) {
51 $date = int ($1 / 86400);
52 next;
53 }
54 m{^\ \d+\ files?\ changed
55 (?:,\ (\d+)\ insertion[s()+]+)?
56 (?:,\ (\d+)\ deletion[s()-]+)?$}x
57 or die "$0: bad stats $_";
cce87900
TF
58 my ($add,$del) = ($1 || 0, $2 || 0);
59 $add{$date} += $add;
60 $del{$date} += $del;
61 $addmax = $add{$date} if $addmax < $add{$date};
62 $delmax = $del{$date} if $delmax < $del{$date};
bceb4717 63 my $can = abs $add{$date} - $del{$date};
cce87900
TF
64 $canmax = $can if $canmax < $can;
65}
66
dcf5f346
TF
67my $max = $opt{width} ? $opt{width} :
68 $opt{cancel} ? $canmax :
cce87900
TF
69 $opt{stack} ? $addmax + $delmax :
70 $addmax > $delmax ? $addmax : $delmax;
cce87900
TF
71my $scale = $width / $max;
72
37fadc81
TF
73my $today = int (time / 86400);
74
75for my $date ($today - $height .. $today) {
d419a729
TF
76 my $add = 0;
77 my $del = 0;
78 my $mod = 0;
37fadc81
TF
79 $add{$date} //= 0;
80 $del{$date} //= 0;
d419a729 81 if ($opt{cancel} or $opt{overlay}) {
cce87900
TF
82 if ($add{$date} > $del{$date}) {
83 $add = $add{$date} - $del{$date};
cce87900
TF
84 } else {
85 $del = $del{$date} - $add{$date};
cce87900
TF
86 }
87 }
88 if ($opt{overlay}) {
d419a729
TF
89 $mod = $add{$date} < $del{$date} ?
90 $add{$date} : $del{$date};
cce87900
TF
91 }
92 if ($opt{stack}) {
93 $add = $add{$date};
94 $del = $del{$date};
cce87900 95 }
37fadc81
TF
96 my $greg = strftime "%b %d %w", localtime $date * 86400;
97 $greg =~ s{(\d)$}{substr "sMTWTFs", $1, 1}e;
dcf5f346 98 my $line = sprintf "$greg \e[33m%s\e[32m%s\e[31m%s\e[0m\n",
37fadc81
TF
99 "#" x ($mod && 1 + $mod * $scale),
100 "+" x ($add && 1 + $add * $scale),
101 "-" x ($del && 1 + $del * $scale);
698ba7ee 102 if (length $line > $width + 30) {
dcf5f346
TF
103 $line = sprintf "## %d ##\e[32m++ %d ++\e[31m-- %d --\e[0m\n",
104 $mod, $add, $del;
105 $line = "$greg \e[33m" . "#"x($width + 16 - length $line) . $line;
106 }
107 print $line;
cce87900 108}
cb4ff77a 109printf " \e[33m#\e[0m <- %-8.1f %s %8d ->\n",
bceb4717 110 1/$scale, " " x ($width - 25), $max;