my $color_author = 'magenta';
-my $format = '%h' . '%x00' # abbreviated commit hash
+my $format = '%x00' # separator from --graph
+ . '%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 $!;
+my @cmd = ('git', 'log', '--graph', "--format=$format",
+ # use either given arguments or --all to list all commits
+ (scalar @ARGV) ? @ARGV : '--all');
+open my $fh, '-|', @cmd or die $!;
+
+my $pager = $ENV{PAGER};
+# Try to find an usable pager without searching $PATH.
+if (not defined $pager) {
+ foreach my $path (qw(/usr/bin/less /bin/less /usr/bin/more /bin/more)) {
+ next if not -x $path;
+
+ $pager = $path;
+ last;
+ }
+}
+# Use a pager if STDOUT is a terminal.
+if (-t STDOUT and defined $pager) {
+ open STDOUT, '|-', $pager or die $!;
+}
while (my $line = <$fh>) {
# History graph line.
}
# Commit line.
- $line =~ /^([ *|]+) (.+)\x00(.+)\x00(.+)\x00(.+)\x00(.*)$/ or die;
+ $line =~ /^([ *|.-]+)\x00(.+)\x00(.+)\x00(.+)\x00(.+)\x00(.*)$/
+ or die $line;
my $prefix = $1;
my $hash = colored($2, $color_hash);
my $date = POSIX::strftime('%Y-%m-%d', localtime($3));
my $message = $5;
my $refs = $6;
+ # Strip trailing whitespace.
+ $prefix =~ s/\s+$//;
# Color "graph".
$prefix =~ s/\|/colored($&, $color_graph)/ge;
- # Strip leading whitespace.
+ # Strip leading whitespace and braces.
$refs =~ s/^\s+//;
+ $refs =~ tr/()//d;
+
+ # Color refs.
+ $refs = join colored(', ', $color_ref_sep), map {
+ my $color;
+ if ($_ eq 'HEAD') {
+ $color = $color_ref_head;
+ } elsif (m{/}) {
+ $color = $color_ref_reference;
+ } else {
+ $color = $color_ref_branch;
+ }
+ colored($_, $color);
+ } split /, /, $refs;
if ($refs ne '') {
- $refs = ' ' . $refs;
+ $refs = ' '
+ . colored('(', $color_ref_sep)
+ . $refs
+ . colored(')', $color_ref_sep);
}
printf "%s %s %s %s%s %s\n",
}
close $fh or die $!;
+
+# Necessary for the redirection to a pager or the pager terminates after our
+# script finishes without displaying all data.
+if (defined $pager) {
+ close STDOUT or die $!;
+}