use warnings;
use strict;
use IkiWiki;
+use IkiWiki::UserInfo;
use Encode;
use URI::Escape q{uri_escape_utf8};
use open qw{:utf8 :std};
hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive);
hook(type => "rcs", id => "rcs_preprevert", call => \&rcs_preprevert);
hook(type => "rcs", id => "rcs_revert", call => \&rcs_revert);
+ hook(type => "rcs", id => "rcs_find_changes", call => \&rcs_find_changes);
+ hook(type => "rcs", id => "rcs_get_current_rev", call => \&rcs_get_current_rev);
}
sub checkconfig () {
return wantarray ? @ci : $ci[0];
}
- sub git_sha1 (;$) {
- # Return head sha1sum (of given file).
- my $file = shift || q{--};
+ sub rcs_find_changes ($) {
+ my $oldrev=shift;
+ my @raw_lines = run_or_die('git', 'log',
+ '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
+ '--no-renames', , '--reverse',
+ '-r', "$oldrev..HEAD", '--', '.');
+
+ # Due to --reverse, we see changes in chronological order.
+ my %changed;
+ my %deleted;
+ my $nullsha = 0 x 40;
+ my $newrev=$oldrev;
+ while (my $ci = parse_diff_tree(\@raw_lines)) {
+ $newrev=$ci->{sha1};
+ foreach my $i (@{$ci->{details}}) {
+ my $file=$i->{file};
+ if ($i->{sha1_to} eq $nullsha) {
+ delete $changed{$file};
+ $deleted{$file}=1;
+ }
+ else {
+ delete $deleted{$file};
+ $changed{$file}=1;
+ }
+ }
+ }
+
+ return (\%changed, \%deleted, $newrev);
+ }
+
+ sub git_sha1_file ($) {
+ my $file=shift;
+ git_sha1("--", $file);
+ }
+
+ sub git_sha1 (@) {
# Ignore error since a non-existing file might be given.
my ($sha1) = run_or_non('git', 'rev-list', '--max-count=1', 'HEAD',
- '--', $file);
+ '--', @_);
if (defined $sha1) {
($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
}
return defined $sha1 ? $sha1 : '';
}
+ sub rcs_get_current_rev () {
+ git_sha1();
+ }
+
sub rcs_update () {
# Update working directory.
# This will be later used in rcs_commit if a merge is required.
my ($file) = @_;
- return git_sha1($file);
+ return git_sha1_file($file);
}
sub rcs_commit (@) {
# Check to see if the page has been changed by someone else since
# rcs_prepedit was called.
- my $cur = git_sha1($params{file});
+ my $cur = git_sha1_file($params{file});
my ($prev) = $params{token} =~ /^($sha1_pattern)$/; # untaint
if (defined $cur && defined $prev && $cur ne $prev) {
}
if (defined $u) {
$u=encode_utf8($u);
- $ENV{GIT_AUTHOR_NAME}=$u;
+ # MITLOGIN This algorithm could be improved
+ $ENV{GIT_AUTHOR_NAME}=IkiWiki::userinfo_get($u, "realname");
}
if (defined $params{session}->param("nickname")) {
$u=encode_utf8($params{session}->param("nickname"));
$u=~s/[^-_0-9[:alnum:]]+//g;
}
if (defined $u) {
- $ENV{GIT_AUTHOR_EMAIL}="$u\@web";
+ $ENV{GIT_AUTHOR_EMAIL}="$u\@mit.edu";
}
}
# Force git to allow empty commit messages.
# (If this version of git supports it.)
my ($version)=`git --version` =~ /git version (.*)/;
- if ($version ge "1.5.4") {
+ if ($version ge "1.7.8") {
+ push @opts, "--allow-empty-message", "--no-edit";
+ }
+ if ($version ge "1.7.2") {
+ push @opts, "--allow-empty-message";
+ }
+ elsif ($version ge "1.5.4") {
push @opts, '--cleanup=verbatim';
}
else {
my @envsave;
push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
- HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS
+ HTTP_COOKIE REMOTE_USER HTTPS SSL_CLIENT_S_DN_CN REDIRECT_STATUS
HTTP_HOST SERVER_PORT HTTPS HTTP_ACCEPT
REDIRECT_URL} if $config{cgi};
my $envsave="";
newenviron[i++]=s;
}
- set_cgilock_fd (int lockfd) {
+ void set_cgilock_fd (int lockfd) {
char *fd_s=malloc(8);
sprintf(fd_s, "%i", lockfd);
setenv("IKIWIKI_CGILOCK_FD", fd_s, 1);
#translators: The parameter is a C filename.
error(sprintf(gettext("failed to compile %s"), "$wrapper.c"));
}
- unlink("$wrapper.c");
if (defined $config{wrappergroup}) {
my $gid=(getgrnam($config{wrappergroup}))[2];
if (! defined $gid) {