diff options
-rw-r--r-- | IkiWiki.pm | 67 | ||||
-rw-r--r-- | IkiWiki/Plugin/git.pm | 166 | ||||
-rw-r--r-- | IkiWiki/Plugin/recentchanges.pm | 80 | ||||
-rw-r--r-- | IkiWiki/Receive.pm | 65 | ||||
-rw-r--r-- | debian/changelog | 5 | ||||
-rw-r--r-- | doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn | 6 | ||||
-rw-r--r-- | doc/plugins/recentchanges.mdwn | 2 | ||||
-rw-r--r-- | doc/plugins/write.mdwn | 30 | ||||
-rw-r--r-- | doc/rcs.mdwn | 2 | ||||
-rw-r--r-- | doc/smileys/icon-error.png | bin | 159 -> 397 bytes | |||
-rw-r--r-- | doc/style.css | 3 | ||||
-rw-r--r-- | doc/templates.mdwn | 2 | ||||
-rw-r--r-- | doc/todo/web_reversion.mdwn | 24 | ||||
-rw-r--r-- | doc/wikiicons/revert.png | bin | 0 -> 397 bytes | |||
-rw-r--r-- | templates/change.tmpl | 12 | ||||
-rw-r--r-- | templates/revert.tmpl | 21 |
16 files changed, 333 insertions, 152 deletions
diff --git a/IkiWiki.pm b/IkiWiki.pm index 66ae86809..2190f008c 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -717,7 +717,7 @@ sub pagename ($) { my $type=pagetype($file); my $page=$file; - $page=~s/\Q.$type\E*$// + $page=~s/\Q.$type\E*$// if defined $type && !$hooks{htmlize}{$type}{keepextension} && !$hooks{htmlize}{$type}{noextension}; if ($config{indexpages} && $page=~/(.*)\/index$/) { @@ -1124,7 +1124,7 @@ sub isselflink ($$) { my $page=shift; my $link=shift; - return $page eq $link; + return $page eq $link; } sub htmllink ($$$;@) { @@ -1519,6 +1519,69 @@ sub check_content (@) { return defined $ok ? $ok : 1; } +sub check_canchange (@) { + my %params = @_; + my $cgi = $params{cgi}; + my $session = $params{session}; + my @changes = @{$params{changes}}; + + my %newfiles; + foreach my $change (@changes) { + # This untaint is safe because we check file_pruned and + # wiki_file_regexp. + my ($file)=$change->{file}=~/$config{wiki_file_regexp}/; + $file=possibly_foolish_untaint($file); + if (! defined $file || ! length $file || + file_pruned($file)) { + error(gettext("bad file name %s"), $file); + } + + my $type=pagetype($file); + my $page=pagename($file) if defined $type; + + if ($change->{action} eq 'add') { + $newfiles{$file}=1; + } + + if ($change->{action} eq 'change' || + $change->{action} eq 'add') { + if (defined $page) { + check_canedit($page, $cgi, $session); + next; + } + else { + if (IkiWiki::Plugin::attachment->can("check_canattach")) { + IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path}); + check_canedit($file, $cgi, $session); + next; + } + } + } + elsif ($change->{action} eq 'remove') { + # check_canremove tests to see if the file is present + # on disk. This will fail when a single commit adds a + # file and then removes it again. Avoid the problem + # by not testing the removal in such pairs of changes. + # (The add is still tested, just to make sure that + # no data is added to the repo that a web edit + # could not add.) + next if $newfiles{$file}; + + if (IkiWiki::Plugin::remove->can("check_canremove")) { + IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session); + check_canedit(defined $page ? $page : $file, $cgi, $session); + next; + } + } + else { + error "unknown action ".$change->{action}; + } + + error sprintf(gettext("you are not allowed to change %s"), $file); + } +} + + my $wikilock; sub lockwiki () { diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index fd57ce1e4..e89813253 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -27,6 +27,8 @@ sub import { hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime); 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); } sub checkconfig () { @@ -718,10 +720,16 @@ sub rcs_getmtime ($) { return findtimes($file, 0); } -sub rcs_receive () { +{ +my $git_root; + +sub git_find_root { # The wiki may not be the only thing in the git repo. # Determine if it is in a subdirectory by examining the srcdir, # and its parents, looking for the .git directory. + + return $git_root if defined $git_root; + my $subdir=""; my $dir=$config{srcdir}; while (! -d "$dir/.git") { @@ -732,83 +740,119 @@ sub rcs_receive () { } } + return $git_root=$subdir; +} + +} + +sub git_parse_changes { + my @changes = @_; + + my $subdir = git_find_root(); + my @rets; + foreach my $ci (@changes) { + foreach my $detail (@{ $ci->{'details'} }) { + my $file = $detail->{'file'}; + + # check that all changed files are in the subdir + if (length $subdir && + ! ($file =~ s/^\Q$subdir\E//)) { + error sprintf(gettext("you are not allowed to change %s"), $file); + } + + my ($action, $mode, $path); + if ($detail->{'status'} =~ /^[M]+\d*$/) { + $action="change"; + $mode=$detail->{'mode_to'}; + } + elsif ($detail->{'status'} =~ /^[AM]+\d*$/) { + $action="add"; + $mode=$detail->{'mode_to'}; + } + elsif ($detail->{'status'} =~ /^[DAM]+\d*/) { + $action="remove"; + $mode=$detail->{'mode_from'}; + } + else { + error "unknown status ".$detail->{'status'}; + } + + # test that the file mode is ok + if ($mode !~ /^100[64][64][64]$/) { + error sprintf(gettext("you cannot act on a file with mode %s"), $mode); + } + if ($action eq "change") { + if ($detail->{'mode_from'} ne $detail->{'mode_to'}) { + error gettext("you are not allowed to change file modes"); + } + } + + # extract attachment to temp file + if (($action eq 'add' || $action eq 'change') && + ! pagetype($file)) { + eval q{use File::Temp}; + die $@ if $@; + my $fh; + ($fh, $path)=File::Temp::tempfile("XXXXXXXXXX", UNLINK => 1); + my $cmd = ($no_chdir ? '' : "cd $config{srcdir} && ") + . "git show $detail->{sha1_to} > '$path'"; + if (system($cmd) != 0) { + error("failed writing temp file '$path'."); + } + } + + push @rets, { + file => $file, + action => $action, + path => $path, + }; + } + } + + return @rets; +} + +sub rcs_receive () { my @rets; while (<>) { chomp; my ($oldrev, $newrev, $refname) = split(' ', $_, 3); - + # only allow changes to gitmaster_branch if ($refname !~ /^refs\/heads\/\Q$config{gitmaster_branch}\E$/) { error sprintf(gettext("you are not allowed to change %s"), $refname); } - + # Avoid chdir when running git here, because the changes # are in the master git repo, not the srcdir repo. - # The pre-recieve hook already puts us in the right place. + # The pre-receive hook already puts us in the right place. $no_chdir=1; - my @changes=git_commit_info($oldrev."..".$newrev); + push @rets, git_parse_changes(git_commit_info($oldrev."..".$newrev)); $no_chdir=0; + } - foreach my $ci (@changes) { - foreach my $detail (@{ $ci->{'details'} }) { - my $file = $detail->{'file'}; + return reverse @rets; +} - # check that all changed files are in the - # subdir - if (length $subdir && - ! ($file =~ s/^\Q$subdir\E//)) { - error sprintf(gettext("you are not allowed to change %s"), $file); - } +sub rcs_preprevert ($) { + my $rev=shift; + my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint - my ($action, $mode, $path); - if ($detail->{'status'} =~ /^[M]+\d*$/) { - $action="change"; - $mode=$detail->{'mode_to'}; - } - elsif ($detail->{'status'} =~ /^[AM]+\d*$/) { - $action="add"; - $mode=$detail->{'mode_to'}; - } - elsif ($detail->{'status'} =~ /^[DAM]+\d*/) { - $action="remove"; - $mode=$detail->{'mode_from'}; - } - else { - error "unknown status ".$detail->{'status'}; - } - - # test that the file mode is ok - if ($mode !~ /^100[64][64][64]$/) { - error sprintf(gettext("you cannot act on a file with mode %s"), $mode); - } - if ($action eq "change") { - if ($detail->{'mode_from'} ne $detail->{'mode_to'}) { - error gettext("you are not allowed to change file modes"); - } - } - - # extract attachment to temp file - if (($action eq 'add' || $action eq 'change') && - ! pagetype($file)) { - eval q{use File::Temp}; - die $@ if $@; - my $fh; - ($fh, $path)=File::Temp::tempfile("XXXXXXXXXX", UNLINK => 1); - if (system("git show ".$detail->{sha1_to}." > '$path'") != 0) { - error("failed writing temp file"); - } - } + return git_parse_changes(git_commit_info($sha1, 1)); +} - push @rets, { - file => $file, - action => $action, - path => $path, - }; - } - } - } +sub rcs_revert ($) { + # Try to revert the given rev; returns undef on _success_. + my $rev = shift; + my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint - return reverse @rets; + if (run_or_non('git', 'revert', '--no-commit', $sha1)) { + return undef; + } + else { + run_or_die('git', 'reset', '--hard'); + return sprintf(gettext("Failed to revert commit %s"), $sha1); + } } 1 diff --git a/IkiWiki/Plugin/recentchanges.pm b/IkiWiki/Plugin/recentchanges.pm index 758b98348..562f61d40 100644 --- a/IkiWiki/Plugin/recentchanges.pm +++ b/IkiWiki/Plugin/recentchanges.pm @@ -13,6 +13,7 @@ sub import { hook(type => "refresh", id => "recentchanges", call => \&refresh); hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate); hook(type => "htmlize", id => "_change", call => \&htmlize); + hook(type => "sessioncgi", id => "recentchanges", call => \&sessioncgi); # Load goto to fix up links from recentchanges IkiWiki::loadplugin("goto"); } @@ -60,6 +61,76 @@ sub refresh ($) { } } +sub sessioncgi ($$) { + my ($q, $session) = @_; + my $do = $q->param('do'); + my $rev = $q->param('rev'); + + return unless $do eq 'revert' && $rev; + + my @changes=$IkiWiki::hooks{rcs}{rcs_preprevert}{call}->($rev); + IkiWiki::check_canchange( + cgi => $q, + session => $session, + changes => \@changes, + ); + + eval q{use CGI::FormBuilder}; + error($@) if $@; + my $form = CGI::FormBuilder->new( + name => "revert", + header => 0, + charset => "utf-8", + method => 'POST', + javascript => 0, + params => $q, + action => $config{cgiurl}, + stylesheet => 1, + template => { template('revert.tmpl') }, + fields => [qw{revertmessage do sid rev}], + ); + my $buttons=["Revert", "Cancel"]; + + $form->field(name => "revertmessage", type => "text", size => 80); + $form->field(name => "sid", type => "hidden", value => $session->id, + force => 1); + $form->field(name => "do", type => "hidden", value => "revert", + force => 1); + + IkiWiki::decode_form_utf8($form); + + if ($form->submitted eq 'Revert' && $form->validate) { + IkiWiki::checksessionexpiry($q, $session, $q->param('sid')); + my $message=sprintf(gettext("This reverts commit %s"), $rev); + if (defined $form->field('revertmessage') && + length $form->field('revertmessage')) { + $message=$form->field('revertmessage')."\n\n".$message; + } + my $r = $IkiWiki::hooks{rcs}{rcs_revert}{call}->($rev); + error $r if defined $r; + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_commit_staged( + message => $message, + session => $session, + ); + IkiWiki::enable_commit_hook(); + + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + } + elsif ($form->submitted ne 'Cancel') { + $form->title(sprintf(gettext("confirm reversion of %s"), $rev)); + $form->tmpl_param(diff => encode_entities(scalar IkiWiki::rcs_diff($rev))); + $form->field(name => "rev", type => "hidden", value => $rev, force => 1); + IkiWiki::showform($form, $buttons, $session, $q); + exit 0; + } + + IkiWiki::redirect($q, urlto($config{recentchangespage}, '')); + exit 0; +} + # Enable the recentchanges link. sub pagetemplate (@) { my %params=@_; @@ -113,6 +184,15 @@ sub store ($$$) { } @{$change->{pages}} ]; push @{$change->{pages}}, { link => '...' } if $is_excess; + + if (length $config{cgiurl} && + exists $IkiWiki::hooks{rcs}{rcs_preprevert} && + exists $IkiWiki::hooks{rcs}{rcs_revert}) { + $change->{reverturl} = IkiWiki::cgiurl( + do => "revert", + rev => $change->{rev} + ); + } $change->{author}=$change->{user}; my $oiduser=eval { IkiWiki::openiduser($change->{user}) }; diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm index e77c477a9..225f2b9ab 100644 --- a/IkiWiki/Receive.pm +++ b/IkiWiki/Receive.pm @@ -48,10 +48,10 @@ EOF sub test () { exit 0 if trusted(); - + IkiWiki::lockwiki(); IkiWiki::loadindex(); - + # Dummy up a cgi environment to use when calling check_canedit # and friends. eval q{use CGI}; @@ -72,63 +72,12 @@ sub test () { regdate => time, }) || error("failed adding user"); } - - my %newfiles; - - foreach my $change (IkiWiki::rcs_receive()) { - # This untaint is safe because we check file_pruned and - # wiki_file_regexp. - my ($file)=$change->{file}=~/$config{wiki_file_regexp}/; - $file=IkiWiki::possibly_foolish_untaint($file); - if (! defined $file || ! length $file || - IkiWiki::file_pruned($file)) { - error(gettext("bad file name %s"), $file); - } - - my $type=pagetype($file); - my $page=pagename($file) if defined $type; - - if ($change->{action} eq 'add') { - $newfiles{$file}=1; - } - - if ($change->{action} eq 'change' || - $change->{action} eq 'add') { - if (defined $page) { - IkiWiki::check_canedit($page, $cgi, $session); - next; - } - else { - if (IkiWiki::Plugin::attachment->can("check_canattach")) { - IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path}); - IkiWiki::check_canedit($file, $cgi, $session); - next; - } - } - } - elsif ($change->{action} eq 'remove') { - # check_canremove tests to see if the file is present - # on disk. This will fail when a single commit adds a - # file and then removes it again. Avoid the problem - # by not testing the removal in such pairs of changes. - # (The add is still tested, just to make sure that - # no data is added to the repo that a web edit - # could not add.) - next if $newfiles{$file}; - - if (IkiWiki::Plugin::remove->can("check_canremove")) { - IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session); - IkiWiki::check_canedit(defined $page ? $page : $file, $cgi, $session); - next; - } - } - else { - error "unknown action ".$change->{action}; - } - - error sprintf(gettext("you are not allowed to change %s"), $file); - } + check_canchange( + cgi => $cgi, + session => $session, + changes => [IkiWiki::rcs_receive()] + ); exit 0; } diff --git a/debian/changelog b/debian/changelog index 1d12d0558..d1ee4967d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,11 @@ ikiwiki (3.20100927) UNRELEASED; urgency=low * htmltidy: Allow configuring tidy parameters in setup file. (W. Trevor King) * Updated French program translation. Closes: #598918 + * git: Added new rcs_revert and rcs_preprevert hooks. + * recentchanges: Add revert buttons to RecentChanges page, and + implement web-based reversion interface. + * Thanks to Peter Gammie for his assistance with the web-based reversion + feature. -- Joey Hess <joeyh@debian.org> Wed, 29 Sep 2010 11:58:23 -0400 diff --git a/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn b/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn index 4998c1a75..d69b3801b 100644 --- a/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn +++ b/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn @@ -38,3 +38,9 @@ Puzzled a bit :-/ Perer Gammie and I are working on reversion over at [[todo/web_reversion]]. --[[Joey]] + +Update: Web reversion is now supported by ikiwiki. Only changes committed +to your wiki after you upgrade to the version of ikiwiki that supports it +will get revert buttons on the RecentChanges page. If you want to force +adding buttons for older changes, you can delete `recentchanges/*._change` +from your srcdir, and rebuild the wiki. --[[Joey]] diff --git a/doc/plugins/recentchanges.mdwn b/doc/plugins/recentchanges.mdwn index 823f68502..6fff18e8a 100644 --- a/doc/plugins/recentchanges.mdwn +++ b/doc/plugins/recentchanges.mdwn @@ -6,6 +6,8 @@ generates a page describing each recent change made to the wiki. These pages can be joined together with [[inline]] to generate the [[RecentChanges]] page. +This plugin also currently handles web-based reversion of changes. + Typically only the RecentChanges page will use the pages generated by this plugin, but you can use it elsewhere too if you like. It's used like this: diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index d5bd1dd76..6b751f0cd 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1154,8 +1154,6 @@ context, and the whole diff in scalar context. This is used to get the page creation time for a file from the RCS, by looking it up in the history. -It's ok if this is not implemented, and throws an error. - If the RCS cannot determine a ctime for the file, return 0. #### `rcs_getmtime($)` @@ -1176,9 +1174,9 @@ sense to implement for all RCSs. It should examine the incoming changes, and do any sanity checks that are appropriate for the RCS to limit changes to safe file adds, -removes, and changes. If something bad is found, it should exit -nonzero, to abort the push. Otherwise, it should return a list of -files that were changed, in the form: +removes, and changes. If something bad is found, it should die, to abort +the push. Otherwise, it should return a list of files that were changed, +in the form: { file => # name of file that was changed @@ -1191,6 +1189,28 @@ files that were changed, in the form: The list will then be checked to make sure that each change is one that is allowed to be made via the web interface. +#### `rcs_preprevert($)` + +This is called by the revert web interface. It is passed a RCS-specific +change ID, and should determine what the effects would be of reverting +that change, and return the same data structure as `rcs_receive`. + +Like `rcs_receive`, it should do whatever sanity checks are appropriate +for the RCS to limit changes to safe changes, and die if a change would +be unsafe to revert. + +#### `rcs_revert($)` + +This is called by the revert web interface. It is passed a named +parameter rev that is the RCS-specific change ID to revert. + +It should try to revert the specified rev, and leave the reversion staged +so `rcs_commit_staged` will complete it. It should return undef on _success_ +and an error message on failure. + +This hook and `rcs_preprevert` are optional, if not implemented, no revert +web interface will be available. + ### PageSpec plugins It's also possible to write plugins that add new functions to diff --git a/doc/rcs.mdwn b/doc/rcs.mdwn index 83c6910d0..06af9807c 100644 --- a/doc/rcs.mdwn +++ b/doc/rcs.mdwn @@ -23,6 +23,8 @@ auto.setup |yes |yes |incomplete|yes |incomplete |yes `rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes `rcs_getctime` |fast |slow |slow |slow |slow |slow |slow |slow `rcs_getmtime` |fast |slow |slow |no |no |no |no |no +`rcs_preprevert` |yes |no |no |no |no |no |no |no +`rcs_revert` |yes |no |no |no |no |no |no |no anonymous push |yes |no |no |no |no |no |no |no conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes openid username |yes |no |no |no |no |no |no |no diff --git a/doc/smileys/icon-error.png b/doc/smileys/icon-error.png Binary files differindex 53b1055f6..c39e65c33 100644 --- a/doc/smileys/icon-error.png +++ b/doc/smileys/icon-error.png diff --git a/doc/style.css b/doc/style.css index fa4b2a38a..aa27d8866 100644 --- a/doc/style.css +++ b/doc/style.css @@ -172,7 +172,8 @@ div.recentchanges { width: 35%; font-size: small; } -.recentchanges .pagelinks { +.recentchanges .pagelinks, +.recentchanges .revert { float: right; margin: 0; width: 60%; diff --git a/doc/templates.mdwn b/doc/templates.mdwn index bfb6a439a..4fd2bf501 100644 --- a/doc/templates.mdwn +++ b/doc/templates.mdwn @@ -74,7 +74,7 @@ html out of ikiwiki and in the templates. * `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`, `editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`, `editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`, - `passwordmail.tmpl`, `openid-selector.tmpl` - Parts of ikiwiki's user + `passwordmail.tmpl`, `openid-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user interface; do not normally need to be customised. [[!meta robots="noindex, follow"]] diff --git a/doc/todo/web_reversion.mdwn b/doc/todo/web_reversion.mdwn index 33fa79aad..9550fa58b 100644 --- a/doc/todo/web_reversion.mdwn +++ b/doc/todo/web_reversion.mdwn @@ -55,7 +55,6 @@ Peter Gammie has done an initial implementation of the above. > (The data from `rcs_preprevert` could also be used for a confirmation > prompt -- it doesn't currently include enough info for diffs, but at > least could have a list of changed files.) ->> I added `rcs_showpatch` which simply yields the output of `git show <patch-id>`. -- [[peteg]] > > Note that it's possible for a git repo to have commits that modify wiki > files in a subdir, and code files elsewhere. `rcs_preprevert` should @@ -63,29 +62,14 @@ Peter Gammie has done an initial implementation of the above. >> Taken care of by refactoring `rcs_receive` in `git.pm` >> I've tested it lightly in my single-user setup. It's a little nasty that the `attachment` plugin >> gets used to check whether attachments are allowed -- there really should be a hook for that. +>>> I agree, but have not figured out a way to make a hook work yet. +>>> --[[Joey]] >> >> Please look it over and tell me what else needs fixing... -- [[peteg]] >>> I have made my own revert branch and put a few fixes in there >>> [[!template id=gitbranch branch=origin/revert author="[[joey]]"]] ->>> (and fixed all the indention..). Issues I noticed but have not gotten ->>> to: --[[Joey]] +>>> (and fixed all the indention..). --[[Joey]] >>>> Please change the git pointer above, then. I will work on your branch. -- [[peteg]] ->>> ->>> * `rcs_diff` already exists; why add `rcs_showpatch`? ->>>> If `rcs_diff` is intended for human consumption, by all means we can use that. -- [[peteg]] ->>> * Would it be better for `rcs_revert` to not commit, and ->>> `rcs_commit_staged` to then be used? This would work for git, but ->>> maybe other RCSs would be problimatic. It would simplifiy the ->>> interface and allow for future mulitple-revert interfaces. ->>> * I quite don't understand why one caller of `git_parse_changes` ->>> needs it to chdir, and not the other one. It's running ->>> in the same git repo either way, and git doesn't need ->>> `git show` to run in a subdir at all.. ->>>> I was aping (preserving) what was already there. I don't understand what you say about `git show` - it must run under $srcdir, surely? And empirically the CGI process wasn't in the right place. By all means simplify that. -- [[peteg]] - ->>> * Probably needs to untaint the revs passed in. ->>> * Seems backwards for `rcs_preprevert` to import and ->>> use `IkiWiki::Receive`. ->>>> Indeed. This is saying that the checking code in IkiWiki::Receive is in the wrong place. I think it would be better to set up some general hooks and shuffle it into a plugin, for then other plugins that maintain special files in the repo can have a say about validity. -- [[peteg]] +[[done]] diff --git a/doc/wikiicons/revert.png b/doc/wikiicons/revert.png Binary files differnew file mode 100644 index 000000000..c39e65c33 --- /dev/null +++ b/doc/wikiicons/revert.png diff --git a/templates/change.tmpl b/templates/change.tmpl index 671b9e483..60a9d94b5 100644 --- a/templates/change.tmpl +++ b/templates/change.tmpl @@ -10,10 +10,8 @@ <span class="desc"><br />Changed pages:</span> <span class="pagelinks"> <TMPL_LOOP PAGES> -<TMPL_IF DIFFURL><a href="<TMPL_VAR DIFFURL>">[[diff|wikiicons/diff.png]]</a><TMPL_VAR LINK> -<TMPL_ELSE> -<TMPL_VAR LINK> -</TMPL_IF> +<TMPL_IF DIFFURL><a href="<TMPL_VAR DIFFURL>" title="diff" rel="nofollow">[[diff|wikiicons/diff.png]]</a><TMPL_VAR LINK> +<TMPL_ELSE><TMPL_VAR LINK></TMPL_IF> </TMPL_LOOP> </span> <span class="desc"><br />Changed by:</span> @@ -28,7 +26,13 @@ <span class="committype"><TMPL_VAR COMMITTYPE></span> <span class="desc"><br />Date:</span> <span class="changedate"><TMPL_VAR COMMITDATE></span> +<span class="desc"><br /></span> </div> +<TMPL_IF REVERTURL> +<span class="revert"> +<a href="<TMPL_VAR REVERTURL>" title="revert" rel="nofollow">[[revert|wikiicons/revert.png]]</a> +</span> +</TMPL_IF> <div class="changelog"> <TMPL_LOOP MESSAGE> <TMPL_IF LINE> diff --git a/templates/revert.tmpl b/templates/revert.tmpl new file mode 100644 index 000000000..0de32811b --- /dev/null +++ b/templates/revert.tmpl @@ -0,0 +1,21 @@ +<TMPL_VAR FORM-START> +<div> + <TMPL_VAR FIELD-DO> + <TMPL_VAR FIELD-SID> + <TMPL_VAR FIELD-REV> +<label for="revertmessage" class="block">Optional comment about this change:</label> + <TMPL_VAR FIELD-REVERTMESSAGE> +</div> +<div class="revert buttons"> +<TMPL_VAR form-submit> +<TMPL_VAR form-cancel> +</div> +<TMPL_VAR FORM-END> +<br \> +<div class="header"> +<span>Diff being reverted:</span> +</div> +<div id="diff"> +<pre> +<TMPL_VAR diff> +</pre> |