git-svn: color support for the log command

* match LESS environment settings to those in pager.c
 * parse diff.color and pager.color settings in the
   config file, and pass --color to git-log
 * --color and --pager= settings are supported

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Eric Wong 2006-11-28 18:51:40 -08:00 committed by Junio C Hamano
parent d5cc2de9ff
commit 9aca025849

View File

@ -60,6 +60,7 @@ nag_lib() unless $_use_lib;
my $_optimize_commits = 1 unless $ENV{GIT_SVN_NO_OPTIMIZE_COMMITS}; my $_optimize_commits = 1 unless $ENV{GIT_SVN_NO_OPTIMIZE_COMMITS};
my $sha1 = qr/[a-f\d]{40}/; my $sha1 = qr/[a-f\d]{40}/;
my $sha1_short = qr/[a-f\d]{4,40}/; my $sha1_short = qr/[a-f\d]{4,40}/;
my $_esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
$_find_copies_harder, $_l, $_cp_similarity, $_cp_remote, $_find_copies_harder, $_l, $_cp_similarity, $_cp_remote,
$_repack, $_repack_nr, $_repack_flags, $_q, $_repack, $_repack_nr, $_repack_flags, $_q,
@ -68,7 +69,8 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
$_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit, $_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,
$_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m, $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m,
$_merge, $_strategy, $_dry_run, $_ignore_nodate, $_non_recursive, $_merge, $_strategy, $_dry_run, $_ignore_nodate, $_non_recursive,
$_username, $_config_dir, $_no_auth_cache, $_xfer_delta); $_username, $_config_dir, $_no_auth_cache, $_xfer_delta,
$_pager, $_color);
my (@_branch_from, %tree_map, %users, %rusers, %equiv); my (@_branch_from, %tree_map, %users, %rusers, %equiv);
my ($_svn_co_url_revs, $_svn_pg_peg_revs); my ($_svn_co_url_revs, $_svn_pg_peg_revs);
my @repo_path_split_cache; my @repo_path_split_cache;
@ -135,6 +137,8 @@ my %cmd = (
'show-commit' => \$_show_commit, 'show-commit' => \$_show_commit,
'non-recursive' => \$_non_recursive, 'non-recursive' => \$_non_recursive,
'authors-file|A=s' => \$_authors, 'authors-file|A=s' => \$_authors,
'color' => \$_color,
'pager=s' => \$_pager,
} ], } ],
'commit-diff' => [ \&commit_diff, 'Commit a diff between two trees', 'commit-diff' => [ \&commit_diff, 'Commit a diff between two trees',
{ 'message|m=s' => \$_message, { 'message|m=s' => \$_message,
@ -759,16 +763,17 @@ sub show_log {
} }
} }
config_pager();
my $pid = open(my $log,'-|'); my $pid = open(my $log,'-|');
defined $pid or croak $!; defined $pid or croak $!;
if (!$pid) { if (!$pid) {
exec(git_svn_log_cmd($r_min,$r_max), @args) or croak $!; exec(git_svn_log_cmd($r_min,$r_max), @args) or croak $!;
} }
setup_pager(); run_pager();
my (@k, $c, $d); my (@k, $c, $d);
while (<$log>) { while (<$log>) {
if (/^commit ($sha1_short)/o) { if (/^${_esc_color}commit ($sha1_short)/o) {
my $cmt = $1; my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) { if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r}; $r_last = $c->{r};
@ -777,25 +782,25 @@ sub show_log {
} }
$d = undef; $d = undef;
$c = { c => $cmt }; $c = { c => $cmt };
} elsif (/^author (.+) (\d+) ([\-\+]?\d+)$/) { } elsif (/^${_esc_color}author (.+) (\d+) ([\-\+]?\d+)$/) {
get_author_info($c, $1, $2, $3); get_author_info($c, $1, $2, $3);
} elsif (/^(?:tree|parent|committer) /) { } elsif (/^${_esc_color}(?:tree|parent|committer) /) {
# ignore # ignore
} elsif (/^:\d{6} \d{6} $sha1_short/o) { } elsif (/^${_esc_color}:\d{6} \d{6} $sha1_short/o) {
push @{$c->{raw}}, $_; push @{$c->{raw}}, $_;
} elsif (/^[ACRMDT]\t/) { } elsif (/^${_esc_color}[ACRMDT]\t/) {
# we could add $SVN->{svn_path} here, but that requires # we could add $SVN->{svn_path} here, but that requires
# remote access at the moment (repo_path_split)... # remote access at the moment (repo_path_split)...
s#^([ACRMDT])\t# $1 #; s#^(${_esc_color})([ACRMDT])\t#$1 $2 #;
push @{$c->{changed}}, $_; push @{$c->{changed}}, $_;
} elsif (/^diff /) { } elsif (/^${_esc_color}diff /) {
$d = 1; $d = 1;
push @{$c->{diff}}, $_; push @{$c->{diff}}, $_;
} elsif ($d) { } elsif ($d) {
push @{$c->{diff}}, $_; push @{$c->{diff}}, $_;
} elsif (/^ (git-svn-id:.+)$/) { } elsif (/^${_esc_color} (git-svn-id:.+)$/) {
($c->{url}, $c->{r}, undef) = extract_metadata($1); ($c->{url}, $c->{r}, undef) = extract_metadata($1);
} elsif (s/^ //) { } elsif (s/^${_esc_color} //) {
push @{$c->{l}}, $_; push @{$c->{l}}, $_;
} }
} }
@ -901,12 +906,30 @@ sub cmt_showable {
return defined $c->{r}; return defined $c->{r};
} }
sub log_use_color {
return 1 if $_color;
my $dc;
chomp($dc = `git-repo-config --get diff.color`);
if ($dc eq 'auto') {
if (-t *STDOUT || (defined $_pager &&
`git-repo-config --bool --get pager.color` !~ /^false/)) {
return ($ENV{TERM} && $ENV{TERM} ne 'dumb');
}
return 0;
}
return 0 if $dc eq 'never';
return 1 if $dc eq 'always';
chomp($dc = `git-repo-config --bool --get diff.color`);
$dc eq 'true';
}
sub git_svn_log_cmd { sub git_svn_log_cmd {
my ($r_min, $r_max) = @_; my ($r_min, $r_max) = @_;
my @cmd = (qw/git-log --abbrev-commit --pretty=raw my @cmd = (qw/git-log --abbrev-commit --pretty=raw
--default/, "refs/remotes/$GIT_SVN"); --default/, "refs/remotes/$GIT_SVN");
push @cmd, '-r' unless $_non_recursive; push @cmd, '-r' unless $_non_recursive;
push @cmd, qw/--raw --name-status/ if $_verbose; push @cmd, qw/--raw --name-status/ if $_verbose;
push @cmd, '--color' if log_use_color();
return @cmd unless defined $r_max; return @cmd unless defined $r_max;
if ($r_max == $r_min) { if ($r_max == $r_min) {
push @cmd, '--max-count=1'; push @cmd, '--max-count=1';
@ -2533,14 +2556,18 @@ sub tz_to_s_offset {
return ($1 * 60) + ($tz * 3600); return ($1 * 60) + ($tz * 3600);
} }
sub setup_pager { # translated to Perl from pager.c # adapted from pager.c
return unless (-t *STDOUT); sub config_pager {
my $pager = $ENV{PAGER}; $_pager ||= $ENV{GIT_PAGER} || $ENV{PAGER};
if (!defined $pager) { if (!defined $_pager) {
$pager = 'less'; $_pager = 'less';
} elsif (length $pager == 0 || $pager eq 'cat') { } elsif (length $_pager == 0 || $_pager eq 'cat') {
return; $_pager = undef;
} }
}
sub run_pager {
return unless -t *STDOUT;
pipe my $rfd, my $wfd or return; pipe my $rfd, my $wfd or return;
defined(my $pid = fork) or croak $!; defined(my $pid = fork) or croak $!;
if (!$pid) { if (!$pid) {
@ -2548,8 +2575,8 @@ sub setup_pager { # translated to Perl from pager.c
return; return;
} }
open STDIN, '<&', $rfd or croak $!; open STDIN, '<&', $rfd or croak $!;
$ENV{LESS} ||= '-S'; $ENV{LESS} ||= 'FRSX';
exec $pager or croak "Can't run pager: $!\n";; exec $_pager or croak "Can't run pager: $! ($_pager)\n";
} }
sub get_author_info { sub get_author_info {