X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/8517aa8687fe2d68f380268854929eef18abec14..946af13ae60da6a8688e66bbe17dd1a012e5d747:/IkiWiki/Plugin/git.pm diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index cadc69e24..bbdcbdba8 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -5,11 +5,11 @@ use warnings; use strict; use IkiWiki; use Encode; +use URI::Escape q{uri_escape_utf8}; use open qw{:utf8 :std}; my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums my $dummy_commit_msg = 'dummy commit'; # message to skip in recent changes -my $git_dir=undef; sub import { hook(type => "checkconfig", id => "git", call => \&checkconfig); @@ -151,6 +151,17 @@ sub genwrapper { } } +my $git_dir=undef; +my $prefix=undef; + +sub in_git_dir ($$) { + $git_dir=shift; + my @ret=shift->(); + $git_dir=undef; + $prefix=undef; + return @ret; +} + sub safe_git (&@) { # Start a child process safely without resorting to /bin/sh. # Returns command output (in list content) or success state @@ -302,8 +313,6 @@ sub merge_past ($$$) { return $conflict; } -{ -my $prefix; sub decode_git_file ($) { my $file=shift; @@ -325,7 +334,6 @@ sub decode_git_file ($) { return decode("utf8", $file); } -} sub parse_diff_tree ($) { # Parse the raw diff tree chunk and return the info hash. @@ -333,8 +341,8 @@ sub parse_diff_tree ($) { my $dt_ref = shift; # End of stream? - return if !defined @{ $dt_ref } || - !defined @{ $dt_ref }[0] || !length @{ $dt_ref }[0]; + return if ! @{ $dt_ref } || + !defined $dt_ref->[0] || !length $dt_ref->[0]; my %ci; # Header line. @@ -461,13 +469,10 @@ 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 ($sha1) { + if (defined $sha1) { ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now } - else { - debug("Empty sha1sum for '$file'."); - } - return defined $sha1 ? $sha1 : q{}; + return defined $sha1 ? $sha1 : ''; } sub rcs_update () { @@ -545,7 +550,13 @@ sub rcs_commit_helper (@) { # 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 { @@ -610,9 +621,10 @@ sub rcs_recentchanges ($) { my @pages; foreach my $detail (@{ $ci->{'details'} }) { my $file = $detail->{'file'}; + my $efile = uri_escape_utf8($file); my $diffurl = defined $config{'diffurl'} ? $config{'diffurl'} : ""; - $diffurl =~ s/\[\[file\]\]/$file/go; + $diffurl =~ s/\[\[file\]\]/$efile/go; $diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go; $diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go; $diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go; @@ -762,6 +774,7 @@ sub git_find_root { } sub git_parse_changes { + my $reverted = shift; my @changes = @_; my ($subdir, $rootdir) = git_find_root(); @@ -782,11 +795,11 @@ sub git_parse_changes { $mode=$detail->{'mode_to'}; } elsif ($detail->{'status'} =~ /^[AM]+\d*$/) { - $action="add"; + $action= $reverted ? "remove" : "add"; $mode=$detail->{'mode_to'}; } elsif ($detail->{'status'} =~ /^[DAM]+\d*/) { - $action="remove"; + $action= $reverted ? "add" : "remove"; $mode=$detail->{'mode_from'}; } else { @@ -844,9 +857,9 @@ sub rcs_receive () { # (Also, if a subdir is involved, we don't want to chdir to # it and only see changes in it.) # The pre-receive hook already puts us in the right place. - $git_dir="."; - push @rets, git_parse_changes(git_commit_info($oldrev."..".$newrev)); - $git_dir=undef; + in_git_dir(".", sub { + push @rets, git_parse_changes(0, git_commit_info($oldrev."..".$newrev)); + }); } return reverse @rets; @@ -859,21 +872,21 @@ sub rcs_preprevert ($) { # Examine changes from root of git repo, not from any subdir, # in order to see all changes. my ($subdir, $rootdir) = git_find_root(); - $git_dir=$rootdir; - my @commits=git_commit_info($sha1, 1); - $git_dir=undef; - - if (! @commits) { - error "unknown commit"; # just in case - } + in_git_dir($rootdir, sub { + my @commits=git_commit_info($sha1, 1); + + if (! @commits) { + error "unknown commit"; # just in case + } - # git revert will fail on merge commits. Add a nice message. - if (exists $commits[0]->{parents} && - @{$commits[0]->{parents}} > 1) { - error gettext("you are not allowed to revert a merge"); - } + # git revert will fail on merge commits. Add a nice message. + if (exists $commits[0]->{parents} && + @{$commits[0]->{parents}} > 1) { + error gettext("you are not allowed to revert a merge"); + } - return git_parse_changes(@commits); + git_parse_changes(1, @commits); + }); } sub rcs_revert ($) {