X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/21add7ffa87a5e622d18bdbb24c638c15bdb3800..ce7966a82cf8d0043a771a1a5b26e3a953e909b2:/IkiWiki/Plugin/git.pm diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index 6a7f6c3ae..e3e1448d3 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -4,6 +4,7 @@ package IkiWiki::Plugin::git; use warnings; use strict; use IkiWiki; +use IkiWiki::UserInfo; use Encode; use open qw{:utf8 :std}; @@ -14,6 +15,7 @@ my $no_chdir=0; sub import { hook(type => "checkconfig", id => "git", call => \&checkconfig); hook(type => "getsetup", id => "git", call => \&getsetup); + hook(type => "genwrapper", id => "git", call => \&genwrapper); hook(type => "rcs", id => "rcs_update", call => \&rcs_update); hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit); hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit); @@ -41,6 +43,7 @@ sub checkconfig () { wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"), }; } + if (defined $config{git_test_receive_wrapper} && length $config{git_test_receive_wrapper}) { push @{$config{wrappers}}, { @@ -49,6 +52,16 @@ sub checkconfig () { wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"), }; } + + # Avoid notes, parser does not handle and they only slow things down. + $ENV{GIT_NOTES_REF}=""; + + # Run receive test only if being called by the wrapper, and not + # when generating same. + if ($config{test_receive} && ! exists $config{wrapper}) { + require IkiWiki::Receive; + IkiWiki::Receive::test(); + } } sub getsetup () { @@ -56,6 +69,7 @@ sub getsetup () { plugin => { safe => 0, # rcs plugin rebuild => undef, + section => "rcs", }, git_wrapper => { type => "string", @@ -94,8 +108,8 @@ sub getsetup () { }, diffurl => { type => "string", - example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_parent]];f=[[file]]", - description => "gitweb url to show a diff ([[sha1_to]], [[sha1_from]], [[sha1_parent]], [[sha1_commit]] and [[file]] substituted)", + example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]", + description => "gitweb url to show a diff ([[file]], [[sha1_to]], [[sha1_from]], [[sha1_commit]], and [[sha1_parent]] substituted)", safe => 1, rebuild => 1, }, @@ -115,6 +129,16 @@ sub getsetup () { }, } +sub genwrapper { + if ($config{test_receive}) { + require IkiWiki::Receive; + return IkiWiki::Receive::genwrapper(); + } + else { + return ""; + } +} + sub safe_git (&@) { # Start a child process safely without resorting /bin/sh. # Return command output or success state (in scalar context). @@ -136,9 +160,17 @@ sub safe_git (&@) { } # In parent. + # git output is probably utf-8 encoded, but may contain + # other encodings or invalidly encoded stuff. So do not rely + # on the normal utf-8 IO layer, decode it by hand. + binmode($OUT); + my @lines; while (<$OUT>) { + $_=decode_utf8($_, 0); + chomp; + push @lines, $_; } @@ -392,7 +424,10 @@ sub git_sha1 (;$) { '--', $file); if ($sha1) { ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now - } else { debug("Empty sha1sum for '$file'.") } + } + else { + debug("Empty sha1sum for '$file'."); + } return defined $sha1 ? $sha1 : q{}; } @@ -441,9 +476,10 @@ sub rcs_commit_staged ($$$) { # Set the commit author and email to the web committer. my %env=%ENV; if (defined $user || defined $ipaddr) { - my $u=defined $user ? $user : $ipaddr; - $ENV{GIT_AUTHOR_NAME}=$u; - $ENV{GIT_AUTHOR_EMAIL}="$u\@web"; + my $u=encode_utf8(defined $user ? $user : $ipaddr); + # MITLOGIN This algorithm could be improved + $ENV{GIT_AUTHOR_NAME}=IkiWiki::userinfo_get($u, "realname"); + $ENV{GIT_AUTHOR_EMAIL}="$u\@mit.edu"; } $message = IkiWiki::possibly_foolish_untaint($message); @@ -586,9 +622,15 @@ sub rcs_getctime ($) { # Remove srcdir prefix $file =~ s/^\Q$config{srcdir}\E\/?//; - my $sha1 = git_sha1($file); - my $ci = git_commit_info($sha1, 1); - my $ctime = $ci->{'author_epoch'}; + my @raw_lines = run_or_die('git', 'log', + '--follow', '--no-merges', + '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c', + '-r', '--', $file); + my @ci; + while (my $parsed = parse_diff_tree("", \@raw_lines)) { + push @ci, $parsed; + } + my $ctime = $ci[$#ci]->{'author_epoch'}; debug("ctime for '$file': ". localtime($ctime)); return $ctime;