From 692004921f5b37059e82eb8eb115aa50387e4fcd Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 7 Apr 2019 10:48:42 -0400 Subject: [PATCH 1/6] Add .editorconfig and file-mode directives [minor] This is to make it easier for others to contribute. --- .editorconfig | 13 +++++++++++++ git-log-compact | 2 ++ 2 files changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1910c85 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = tab +trim_trailing_whitespace = true +indent_size = 4 +end_of_line = LF + +[*.md] +indent_style = space + +[README] +indent_style = space diff --git a/git-log-compact b/git-log-compact index 870e76c..4d8d455 100755 --- a/git-log-compact +++ b/git-log-compact @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# -*- mode: perl -*- # git-log-compact.pl -- compact git log --oneline alternative with dates, times and initials # Copyright (C) 2015,2016 Kyle J. McKay . All rights reserved. @@ -462,3 +463,4 @@ NOBREAKNEEDED: } close LOG; close OUT; +# vi: set ft=perl: # From 45e23022167e7146e9601539b6d22c05ca41192b Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 7 Apr 2019 13:08:30 -0400 Subject: [PATCH 2/6] Added --pager configuration option This way you can skip the call to `git var GIT_PAGER` if the user has set `--pager` in `log-compact.defaults`. --- README | 56 ++++++++++++++++++++++++++----------------------- git-log-compact | 12 ++++++++--- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/README b/README index 680f90e..3a689a3 100644 --- a/README +++ b/README @@ -191,72 +191,76 @@ In addition to allowing all the normal `git log` options except for `--notes`, `--format` and `--pretty` (`--oneline` is allowed and silently ignored), the following additional options may be utilized: - * `--seconds` + * `--seconds` include seconds in the time (i.e. HH:MM:SS instead of just HH:MM) - * `--minutes` - include minutes but not seconds in the time (i.e. HH:MM not HH:MM:SS) + * `--minutes` + include minutes but not seconds in the time (i.e. HH:MM not HH:MM:SS) This is the default - * `--no-times` + * `--no-times` omit the time field entirely - * `--two-initials` - only show at most two initials instead of the usual three + * `--two-initials` + only show at most two initials instead of the usual three This is the default if `--initials=author,committer` or `--initials=committer,author` is used. - * `--three-initials` - show at most three initials + * `--three-initials` + show at most three initials This is the default unless `--initials=author,committer` or `--initials=committer,author` is used. - * `--no-initials` + * `--no-initials` omit the initials field entirely - * `--commit-message` + * `--commit-message` when using `--walk-reflogs` show commit message not reflog message - * `--author-date` - force use of author dates and times + * `--author-date` + force use of author dates and times The default is to use committer dates and times unless `--author-date-order` is in effect. This option forces author dates and times to always be used and overrides `--committer-date`. - * `--committer-date` - force use of committer dates and times + * `--committer-date` + force use of committer dates and times The default is to use committer dates and times if `--date-order` or `--topo-order` is in effect or `--author-date-order` is NOT in effect. This option forces committer dates and times to always be used and overrides a previous `--author-date` option. - * `--initials=author` - show author initials + * `--initials=author` + show author initials This is the default behavior - * `--initials=committer` + * `--initials=committer` show committer initials instead of author initials - * `--initials=author,committer` - show author and commiter initials separated by a `/` + * `--initials=author,committer` + show author and commiter initials separated by a `/` This changes the initials width default from three to two. - * `--initials=committer,author` - show commiter and author initials separated by a `/` + * `--initials=committer,author` + show commiter and author initials separated by a `/` This changes the initials width default from three to two. - * `--time-zone=zone` - set the TZ environment variable to `zone` + * `--time-zone=zone` + set the TZ environment variable to `zone` This is an alterative to setting TZ before running `git log-compact` and will affect the time zone dates and times are displayed in. - * `--weekday` + * `--weekday` show the weekday with the date - * `--no-weekday` - do not show the weekday with the date + * `--no-weekday` + do not show the weekday with the date This is the default behavior + * `--pager=PAGER` + pass output through PAGER + Default is the output of `git var GIT_PAGER`. + In addition to the above options, color output is controlled as normal for `git log` with the addition of `color.log-compact.date`, `color.log-compact.time` and `color.log-compact.initials` config options diff --git a/git-log-compact b/git-log-compact index 4d8d455..f7bbb89 100755 --- a/git-log-compact +++ b/git-log-compact @@ -37,6 +37,7 @@ usage: git%slog-compact [] [] [[--] ...] --time-zone= Set TZ environment variable to --weekday Show the weekday with the date --no-weekday Do not show the weekday with the date (default) + --pager= Use (default `git var GIT_PAGER`) other log options See `git help log` for more information @@ -45,8 +46,8 @@ Default colors for dates, times and initials may be changed by setting `color.log-compact.initials` config values. Dates and times are shown in the local time zone if TZ is not set in the environment and the `--time-zone` option has not been used. Default options may be set in the -`log-compact.defaults` config value and they will be treated as though they were -listed first in the command line options list (e.g. +`log-compact.defaults` config value and they will be treated as though they +were listed first in the command line options list (e.g., `git config log-compact.defaults "--abbrev=8 --seconds"`) USAGE @@ -164,6 +165,7 @@ sub get_defaults { system("git rev-parse --git-dir >/dev/null") == 0 or exit(1); my ($usemark, $usegraph, $usereflog, $useboundary, $useleftright, $usecherry, $setusecolor, $usecolor, $usecad); +my ($setpager, $pager); my @args = (); my $lastwasgrep; my $dateopt = "%ct"; @@ -304,6 +306,10 @@ foreach my $arg (get_defaults(), @ARGV) { $usegraph = 1; } elsif ($arg =~ /^(--grep|--grep-reflog|-S|-G)$/) { $nextisgrep = 1; + } elsif ($arg =~ /^--pager=(.+)$/) { + $setpager = 1; + $pager = $1; + next; } elsif ($arg eq "--") { $sawdashdash = 1; } @@ -334,7 +340,7 @@ if ($usecolor) { } my $decopt = ""; $decopt = "$autocolor%d" if use_decorate; -my $pager = qx(git var GIT_PAGER); +$pager = qx(git var GIT_PAGER) unless $setpager; defined($pager) and chomp $pager; $ENV{LESS} = "-FRX" unless exists $ENV{LESS}; $ENV{LV} = "-c" unless exists $ENV{LV}; From 984d732124d9087cb564ce1e4d1fdcdd99386b13 Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 7 Apr 2019 13:41:37 -0400 Subject: [PATCH 3/6] Added --default-colors option This option, when specified, means we don't have to run `git config --get-color`, which greatly reduces the time spent in qx() (aka CORE:backtick in Devel::NYTProf). - Added command-line option - Added a copy of Term::ANSIColor::Simple, which has compatible licensing - Updated the copy to remove implicit reset (`ESC [0m`) and add an explicit reset sub Also: - Updated the copyright notice to include "and contributors" - Added a contributors list to the README --- README | 11 ++++ git-log-compact | 162 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 164 insertions(+), 9 deletions(-) diff --git a/README b/README index 3a689a3..419235a 100644 --- a/README +++ b/README @@ -261,6 +261,11 @@ silently ignored), the following additional options may be utilized: pass output through PAGER Default is the output of `git var GIT_PAGER`. + * `--default-colors` + use the default colors on ANSI terminals. + This speeds things up because it means git-log-compact doesn't have + to run `git config --get-color` several times. + In addition to the above options, color output is controlled as normal for `git log` with the addition of `color.log-compact.date`, `color.log-compact.time` and `color.log-compact.initials` config options @@ -270,3 +275,9 @@ Furthermore, default options may be set in the `log-compact.defaults` config value and they will be treated as though they appeared at the very beginning of the `git log-compact` command line option list (e.g. `git config log-compact.defaults "--abbrev=8 --seconds"`). + +Contributors +------------ + + * Kyle J. McKay + * Christopher White diff --git a/git-log-compact b/git-log-compact index f7bbb89..0944372 100755 --- a/git-log-compact +++ b/git-log-compact @@ -2,11 +2,15 @@ # -*- mode: perl -*- # git-log-compact.pl -- compact git log --oneline alternative with dates, times and initials -# Copyright (C) 2015,2016 Kyle J. McKay . All rights reserved. +# Copyright (C) 2015-2019 Kyle J. McKay and contributors. +# All rights reserved. # License GPL v2 -# Version 1.0 +{ +package main; + +our $VERSION = '1.1'; use 5.008; use strict; @@ -38,6 +42,8 @@ usage: git%slog-compact [] [] [[--] ...] --weekday Show the weekday with the date --no-weekday Do not show the weekday with the date (default) --pager= Use (default `git var GIT_PAGER`) + --default-colors Use the default colors for ANSI terminals. + Speeds up git-log-compact considerably. other log options See `git help log` for more information @@ -164,7 +170,7 @@ sub get_defaults { } system("git rev-parse --git-dir >/dev/null") == 0 or exit(1); -my ($usemark, $usegraph, $usereflog, $useboundary, $useleftright, $usecherry, $setusecolor, $usecolor, $usecad); +my ($usemark, $usegraph, $usereflog, $useboundary, $useleftright, $usecherry, $setusecolor, $usecolor, $defaultcolors, $usecad); my ($setpager, $pager); my @args = (); my $lastwasgrep; @@ -310,6 +316,9 @@ foreach my $arg (get_defaults(), @ARGV) { $setpager = 1; $pager = $1; next; + } elsif ($arg =~ /^--default-colors$/) { + $defaultcolors = 1; + next; } elsif ($arg eq "--") { $sawdashdash = 1; } @@ -330,13 +339,24 @@ my $color = "never"; my ($hashcolor, $datecolor, $timecolor, $initialscolor, $autocolor) = ("", "", "", "", ""); $usecolor = 1 if !$setusecolor && system("git", "config", "--get-colorbool", "color.diff") == 0; if ($usecolor) { + # Make a color + local *c = sub { + my $c = MY::Term::ANSIColor::Simple->new(''); + $c->$_ foreach @_; + return "$c"; + }; $color = "always"; - $autocolor = "%C(auto)"; - $hashcolor= qx(git config --get-color color.diff.commit "yellow"); - $datecolor= qx(git config --get-color color.log-compact.date "bold blue"); - $timecolor= qx(git config --get-color color.log-compact.time "green") if $timeformat; - $initialscolor = qx(git config --get-color color.log-compact.initials "red") if $iw; - $resetcolor = qx(git config --get-color "" "reset"); + $autocolor= "%C(auto)"; + $hashcolor= ($defaultcolors && c('yellow')) || + qx(git config --get-color color.diff.commit "yellow"); + $datecolor= ($defaultcolors && c(qw(bold blue))) || + qx(git config --get-color color.log-compact.date "bold blue"); + $timecolor= ($defaultcolors && c('green')) || + qx(git config --get-color color.log-compact.time "green") if $timeformat; + $initialscolor = ($defaultcolors && c('red')) || + qx(git config --get-color color.log-compact.initials "red") if $iw; + $resetcolor = ($defaultcolors && c('reset')) || + qx(git config --get-color "" "reset"); } my $decopt = ""; $decopt = "$autocolor%d" if use_decorate; @@ -469,4 +489,128 @@ NOBREAKNEEDED: } close LOG; close OUT; + +} #package main + +############################################################################ + +BEGIN { # A modification of Term::ANSIColor::Simple, which is licensed under the + # same terms as Perl itself. Therefore, it can be relicensed GPLv2 along + # with the rest of this code. POD is omitted. + # sub reset() has been added, and implicit reset has been removed. +package MY::Term::ANSIColor::Simple; + +use strict; +use warnings; + +use parent qw/Exporter/; +our @EXPORT = qw/color/; +our @EXPORT_OK = qw/c/; + +our $VERSION = "0.10"; + +use overload + '""' => sub { shift->{string} }; + +my %effects = ( + 'bold' => 1, + 'dark' => 2, + 'faint' => 2, + 'underline' => 4, + 'underscore' => 4, + 'blink' => 5, + 'reverse' => 7, + 'concealed' => 8, + ); + +my %colors = ( + 'black' => 30, + 'red' => 31, + 'green' => 32, + 'yellow' => 33, + 'blue' => 34, + 'magenta' => 35, + 'cyan' => 36, + 'white' => 37, + + 'bright_black' => 90, + 'bright_red' => 91, + 'bright_green' => 92, + 'bright_yellow' => 93, + 'bright_blue' => 94, + 'bright_magenta' => 95, + 'bright_cyan' => 96, + 'bright_white' => 97, + ); + +my %grounds = ( + 'on_black' => 40, + 'on_red' => 41, + 'on_green' => 42, + 'on_yellow' => 43, + 'on_blue' => 44, + 'on_magenta' => 45, + 'on_cyan' => 46, + 'on_white' => 47, + + 'on_bright_black' => 100, + 'on_bright_red' => 101, + 'on_bright_green' => 102, + 'on_bright_yellow' => 103, + 'on_bright_blue' => 104, + 'on_bright_magenta' => 105, + 'on_bright_cyan' => 106, + 'on_bright_white' => 107, + ); + +my %all = (%effects, %colors, %grounds); +my @colors_keys = keys %colors; +my $colors_num = scalar @colors_keys; + +while ( my ($color, $code) = each %all ) { + no strict 'refs'; + *{__PACKAGE__ . '::' . $color} = sub { + my $self = shift; + $self->{string} = "\e[${code}m" . $self->{string}; # no implicit reset + return $self; + }; +} + +sub reset { # explicit reset required + my $self = shift; + $self->{string} .= "\e[0m"; + return $self; +} + +sub new { + my ($class, $string) = @_; + return bless +{ string => $string }, $class; +} + +sub c { + my ($string) = @_; + return __PACKAGE__->new($string); +} + +sub color { + my ($string) = @_; + return __PACKAGE__->new($string); +} + +sub rainbow { + my $self = shift; + my @chars = split //, $self->{string}; + my @colored; + + for my $char (@chars) { + my $code = $colors{ $colors_keys[ int rand($colors_num) ] }; + # other than spaces + $code = 0 if $char =~ /\s/; + push(@colored, "\e[${code}m$char\e[0m"); + } + return join '', @colored; +} +1; +} #package MY::Term::ANSIColor::Simple; + # vi: set ft=perl: # From e40d90c36e04ff9c6073faee5aa2209e033f21e2 Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 7 Apr 2019 13:56:44 -0400 Subject: [PATCH 4/6] Removed `git rev-parse` call It was checking whether we were in a git repo. However, the open() call to open `git log` also tells us that, so the rev-parse check was redundant. The only other `git` call before the `git log` is a `git --exec-path`, which doesn't care whether or not we're in a repo. I also added some comments to mark major parts of the script. --- git-log-compact | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/git-log-compact b/git-log-compact index 0944372..39d1068 100755 --- a/git-log-compact +++ b/git-log-compact @@ -7,9 +7,6 @@ # License GPL v2 -{ -package main; - our $VERSION = '1.1'; use 5.008; @@ -169,7 +166,7 @@ sub get_defaults { return split(" ", join(" ", @defaults)); } -system("git rev-parse --git-dir >/dev/null") == 0 or exit(1); +# Process defaults and arguments my ($usemark, $usegraph, $usereflog, $useboundary, $useleftright, $usecherry, $setusecolor, $usecolor, $defaultcolors, $usecad); my ($setpager, $pager); my @args = (); @@ -182,6 +179,7 @@ $iw = undef; my $iw2 = ""; my ($committer, $author, $ivar, $ivar2); $ivar = \$author; + foreach my $arg (get_defaults(), @ARGV) { my $nextisgrep; if ($sawdashdash || $lastwasgrep) { @@ -335,6 +333,7 @@ if ($mark && !$useleftright) { $fixmark = "+" if $usecherry; } +# Process colors my $color = "never"; my ($hashcolor, $datecolor, $timecolor, $initialscolor, $autocolor) = ("", "", "", "", ""); $usecolor = 1 if !$setusecolor && system("git", "config", "--get-colorbool", "color.diff") == 0; @@ -360,11 +359,14 @@ if ($usecolor) { } my $decopt = ""; $decopt = "$autocolor%d" if use_decorate; + +# Process pager $pager = qx(git var GIT_PAGER) unless $setpager; defined($pager) and chomp $pager; $ENV{LESS} = "-FRX" unless exists $ENV{LESS}; $ENV{LV} = "-c" unless exists $ENV{LV}; +# Run `git log` my ($lastdate, $lastprefix, $lastplainprefix) = (""); my $msgopt = "%s"; $msgopt = "%gd: $reflogsubj" if $usereflog; @@ -378,6 +380,8 @@ if (defined($pager) && $pager ne "cat") { open OUT, '>&STDOUT' or die "could not dupe STDOUT: $!"; } select((select(OUT),$|=1)[0]); + +# Read the `git log` output my $delblank; my @lastparents = (); my $lastwascommit; @@ -486,12 +490,11 @@ NOBREAKNEEDED: $initialscolor, $initials, ($iw2 ? "/" : ""), $initials2, ($iw ? "$resetcolor " : ""), $subject; $delblank = 1; -} +} #while close LOG; close OUT; -} #package main - +# End of the main package ############################################################################ BEGIN { # A modification of Term::ANSIColor::Simple, which is licensed under the From 15c7ca13a3f53946915cbc5e5a447a69a899a19a Mon Sep 17 00:00:00 2001 From: Chris White Date: Sun, 7 Apr 2019 14:07:57 -0400 Subject: [PATCH 5/6] Added GIT_LOG_COMPACT_OPTIONS environment variable This variable, if it exists, is used instead of `log-compact.defaults`. This speeds up git-log-compact, since it eliminates a `git config` call. --- README | 21 +++++++++++++++++++++ git-log-compact | 18 +++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README b/README index 419235a..6270a81 100644 --- a/README +++ b/README @@ -276,8 +276,29 @@ config value and they will be treated as though they appeared at the very beginning of the `git log-compact` command line option list (e.g. `git config log-compact.defaults "--abbrev=8 --seconds"`). +If the `GIT_LOG_COMPACT_OPTIONS` environment variable is set, its contents +will be used as default options **instead of** the contents of the +`log-compact.defaults` variable. + + +Making it run faster +-------------------- + +The things that take git-log-compact the longest are reading configuration. +Therefore, for maximum speed, specify all the configuration in +`GIT_LOG_COMPACT_OPTIONS`. For example (in `bash`): + + export GIT_LOG_COMPACT_OPTIONS="--decorate --color=always --pager=less --default-colors" + + Contributors ------------ * Kyle J. McKay * Christopher White + + +License +------- + +GPL v2, diff --git a/git-log-compact b/git-log-compact index 39d1068..e809be3 100755 --- a/git-log-compact +++ b/git-log-compact @@ -48,10 +48,16 @@ Default colors for dates, times and initials may be changed by setting `color.log-compact.date`, `color.log-compact.time` and/or `color.log-compact.initials` config values. Dates and times are shown in the local time zone if TZ is not set in the environment and the `--time-zone` -option has not been used. Default options may be set in the -`log-compact.defaults` config value and they will be treated as though they -were listed first in the command line options list (e.g., -`git config log-compact.defaults "--abbrev=8 --seconds"`) +option has not been used. + +Default options may be set in the GIT_LOG_COMPACT_OPTIONS environment variable +or in the git `log-compact.defaults` config value. Default options will be +treated as though they were listed first in the command line options list. +Example usage: + `git config log-compact.defaults "--abbrev=8 --seconds"`) + +Note that, for speed, if GIT_LOG_COMPACT_OPTIONS is set, `log-compact.defaults` +will NOT be used. USAGE my $timeformat = "%H:%M"; @@ -153,7 +159,9 @@ sub get_prefix { sub get_defaults { # defaults are cumulative, but an empty setting resets my @defaults = (); - my $opts = qx(git config --get-all log-compact.defaults 2>/dev/null); + my $opts = $ENV{GIT_LOG_COMPACT_OPTIONS}; + $opts = qx(git config --get-all log-compact.defaults 2>/dev/null) + unless defined $opts; # Only call `git config` if no env var. chomp($opts); foreach (split(/\r\n|\r|\n/, $opts, -1)) { s/^\s+//; s/\s+$//; From 72e8207149b6c07f07e46fc379166c174ad68c40 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 8 Apr 2019 12:52:30 -0400 Subject: [PATCH 6/6] MY::Term::ANSIColor::Simple: remove unused subs Also removed the `use` statements for Exporter and overload, which reduces compilation time. --- git-log-compact | 44 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/git-log-compact b/git-log-compact index e809be3..1312213 100755 --- a/git-log-compact +++ b/git-log-compact @@ -350,7 +350,7 @@ if ($usecolor) { local *c = sub { my $c = MY::Term::ANSIColor::Simple->new(''); $c->$_ foreach @_; - return "$c"; + return $c->string; }; $color = "always"; $autocolor= "%C(auto)"; @@ -507,21 +507,16 @@ close OUT; BEGIN { # A modification of Term::ANSIColor::Simple, which is licensed under the # same terms as Perl itself. Therefore, it can be relicensed GPLv2 along - # with the rest of this code. POD is omitted. + # with the rest of this code. POD and unused functions are omitted. # sub reset() has been added, and implicit reset has been removed. package MY::Term::ANSIColor::Simple; use strict; use warnings; -use parent qw/Exporter/; -our @EXPORT = qw/color/; -our @EXPORT_OK = qw/c/; - our $VERSION = "0.10"; -use overload - '""' => sub { shift->{string} }; +sub string { shift->{string} }; # instead of overloading stringification my %effects = ( 'bold' => 1, @@ -588,39 +583,16 @@ while ( my ($color, $code) = each %all ) { } sub reset { # explicit reset required - my $self = shift; - $self->{string} .= "\e[0m"; - return $self; + my $self = shift; + $self->{string} .= "\e[0m"; + return $self; } sub new { - my ($class, $string) = @_; - return bless +{ string => $string }, $class; -} - -sub c { - my ($string) = @_; - return __PACKAGE__->new($string); + my ($class, $string) = @_; + return bless +{ string => $string }, $class; } -sub color { - my ($string) = @_; - return __PACKAGE__->new($string); -} - -sub rainbow { - my $self = shift; - my @chars = split //, $self->{string}; - my @colored; - - for my $char (@chars) { - my $code = $colors{ $colors_keys[ int rand($colors_num) ] }; - # other than spaces - $code = 0 if $char =~ /\s/; - push(@colored, "\e[${code}m$char\e[0m"); - } - return join '', @colored; -} 1; } #package MY::Term::ANSIColor::Simple;