From cbddb5a4b8e0e2fb63886ad9d1cf8a087cdb83b1 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 22 Jul 2008 16:14:33 -0400 Subject: [PATCH] add rcs_commit_staged and rcs_rename Implemented for git and svn so far. Note that rcs_commit_staged does assume that the rcs has the ability to "stage" multiple changes for a later commit. Support for this varies, but all we really care about is staging removals and renames, which, AFAIK, all modern rcs's support. --- IkiWiki/Plugin/remove.pm | 5 ++-- IkiWiki/Plugin/rename.pm | 13 ++++++---- IkiWiki/Rcs/Stub.pm | 21 +++++++++++++++++ IkiWiki/Rcs/bzr.pm | 14 +++++++++++ IkiWiki/Rcs/git.pm | 22 ++++++++++++++--- IkiWiki/Rcs/mercurial.pm | 14 +++++++++++ IkiWiki/Rcs/monotone.pm | 14 +++++++++++ IkiWiki/Rcs/svn.pm | 51 +++++++++++++++++++++++++++++++++++----- IkiWiki/Rcs/tla.pm | 14 +++++++++++ debian/changelog | 3 ++- 10 files changed, 153 insertions(+), 18 deletions(-) diff --git a/IkiWiki/Plugin/remove.pm b/IkiWiki/Plugin/remove.pm index f263db9b8..4c73ed9e5 100644 --- a/IkiWiki/Plugin/remove.pm +++ b/IkiWiki/Plugin/remove.pm @@ -171,11 +171,10 @@ sub sessioncgi ($$) { #{{{ if ($config{rcs}) { IkiWiki::disable_commit_hook(); foreach my $file (@files) { - my $token=IkiWiki::rcs_prepedit($file); IkiWiki::rcs_remove($file); - IkiWiki::rcs_commit($file, gettext("removed"), - $token, $session->param("name"), $ENV{REMOTE_ADDR}); } + IkiWiki::rcs_commit_staged(gettext("removed"), + $session->param("name"), $ENV{REMOTE_ADDR}); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Plugin/rename.pm b/IkiWiki/Plugin/rename.pm index c0ccb25ce..32888877f 100644 --- a/IkiWiki/Plugin/rename.pm +++ b/IkiWiki/Plugin/rename.pm @@ -66,7 +66,9 @@ sub check_canrename ($$$$$$$) { #{{{ # Must be editable. IkiWiki::check_canedit($dest, $q, $session); if ($attachment) { - IkiWiki::Plugin::attachment::check_canattach($session, $dest, $destfile); + # Note that $srcfile is used here, not $destfile, + # because it wants the current file, to check it. + IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile); } } } #}}} @@ -210,15 +212,16 @@ sub sessioncgi ($$) { #{{{ check_canrename($src, $srcfile, $dest, $destfile, $q, $session, $q->param("attachment")); + # Ensures that the dest directory exists and is ok. + IkIWiki::prep_writefile($destfile, $config{srcdir}); + # Do rename, and update the wiki. require IkiWiki::Render; if ($config{rcs}) { IkiWiki::disable_commit_hook(); - my $token=IkiWiki::rcs_prepedit($srcfile); IkiWiki::rcs_rename($srcfile, $destfile); - # TODO commit destfile too - IkiWiki::rcs_commit($srcfile, gettext("rename $srcfile to $destfile"), - $token, $session->param("name"), $ENV{REMOTE_ADDR}); + IkiWiki::rcs_commit_staged(gettext("rename $srcfile to $destfile"), + $session->param("name"), $ENV{REMOTE_ADDR}); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Rcs/Stub.pm b/IkiWiki/Rcs/Stub.pm index 375591c96..43a2f2029 100644 --- a/IkiWiki/Rcs/Stub.pm +++ b/IkiWiki/Rcs/Stub.pm @@ -24,6 +24,14 @@ sub rcs_commit ($$$;$$) { # Tries to commit the page; returns undef on _success_ and # a version of the page with the rcs's conflict markers on failure. # The file is relative to the srcdir. + my ($file, $message, $rcstoken, $user, $ipaddr) = @_; + return undef # success +} + +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; return undef # success } @@ -31,12 +39,25 @@ sub rcs_add ($) { # Add a file. The filename is relative to the root of the srcdir. # Note that this should not check the new file in, it should only # prepare for it to be checked in when rcs_commit is called. + # Note that the file may be in a new subdir that is not yet added + # to version control; the subdir can be added if so. } sub rcs_remove ($) { # Remove a file. The filename is relative to the root of the srcdir. # Note that this should not check the removal in, it should only # prepare for it to be checked in when rcs_commit is called. + # Note that the new file may be in a new subdir that is not yet added + # to version control; the subdir can be added if so. +} + +sub rcs_rename ($$) { + # Rename a file. The filenames are relative to the root of the srcdir. + # Note that this should not commit the rename, it should only + # prepare it for when rcs_commit is called. + # The new filename may be in a new subdir, that is not yet added to + # version control. If so, the subdir will exist already, and should + # be added. } sub rcs_recentchanges ($) { diff --git a/IkiWiki/Rcs/bzr.pm b/IkiWiki/Rcs/bzr.pm index ca60190ea..e414e85d2 100644 --- a/IkiWiki/Rcs/bzr.pm +++ b/IkiWiki/Rcs/bzr.pm @@ -80,6 +80,14 @@ sub rcs_commit ($$$;$$) { #{{{ return undef; # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + error("rcs_commit_staged not implemented for bzr"); # TODO +} + sub rcs_add ($) { # {{{ my ($file) = @_; @@ -95,6 +103,12 @@ sub rcs_remove ($) { # {{{ error("rcs_remove not implemented for bzr"); # TODO } #}}} +sub rcs_rename ($$) { # {{{ + my ($src, $dest) = @_; + + error("rcs_rename not implemented for bzr"); # TODO +} #}}} + sub rcs_recentchanges ($) { #{{{ my ($num) = @_; diff --git a/IkiWiki/Rcs/git.pm b/IkiWiki/Rcs/git.pm index b02b286bd..ecf560d0b 100644 --- a/IkiWiki/Rcs/git.pm +++ b/IkiWiki/Rcs/git.pm @@ -318,7 +318,16 @@ sub rcs_commit ($$$;$$) { #{{{ my $conflict = _merge_past($prev, $file, $dummy_commit_msg); return $conflict if defined $conflict; } - + + rcs_add($file); + return rcs_commit_staged($message, $user, $ipaddr); +} #}}} + +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + # Set the commit author and email to the web committer. my %env=%ENV; if (defined $user || defined $ipaddr) { @@ -330,7 +339,8 @@ sub rcs_commit ($$$;$$) { #{{{ # git commit returns non-zero if file has not been really changed. # so we should ignore its exit status (hence run_or_non). $message = possibly_foolish_untaint($message); - if (run_or_non('git', 'commit', '--cleanup=verbatim', '-q', '-m', $message, '-i', $file)) { + if (run_or_non('git', 'commit', '--cleanup=verbatim', + '-q', '-m', $message)) { if (length $config{gitorigin_branch}) { run_or_cry('git', 'push', $config{gitorigin_branch}); } @@ -338,7 +348,7 @@ sub rcs_commit ($$$;$$) { #{{{ %ENV=%env; return undef; # success -} #}}} +} sub rcs_add ($) { # {{{ # Add file to archive. @@ -356,6 +366,12 @@ sub rcs_remove ($) { # {{{ run_or_cry('git', 'rm', '-f', $file); } #}}} +sub rcs_rename ($$) { # {{{ + my ($src, $dest) = @_; + + run_or_cry('git', 'mv', '-f', $src, $dest); +} #}}} + sub rcs_recentchanges ($) { #{{{ # List of recent changes. diff --git a/IkiWiki/Rcs/mercurial.pm b/IkiWiki/Rcs/mercurial.pm index 1bfcf6242..8c3f03e07 100644 --- a/IkiWiki/Rcs/mercurial.pm +++ b/IkiWiki/Rcs/mercurial.pm @@ -92,6 +92,14 @@ sub rcs_commit ($$$;$$) { #{{{ return undef; # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + error("rcs_commit_staged not implemented for mercurial"); # TODO +} + sub rcs_add ($) { # {{{ my ($file) = @_; @@ -107,6 +115,12 @@ sub rcs_remove ($) { # {{{ error("rcs_remove not implemented for mercurial"); # TODO } #}}} +sub rcs_rename ($$) { # {{{ + my ($src, $dest) = @_; + + error("rcs_rename not implemented for mercurial"); # TODO +} #}}} + sub rcs_recentchanges ($) { #{{{ my ($num) = @_; diff --git a/IkiWiki/Rcs/monotone.pm b/IkiWiki/Rcs/monotone.pm index 948edac0a..97d9c7a30 100644 --- a/IkiWiki/Rcs/monotone.pm +++ b/IkiWiki/Rcs/monotone.pm @@ -359,6 +359,14 @@ sub rcs_commit ($$$;$$) { #{{{ return undef # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + error("rcs_commit_staged not implemented for monotone"); # TODO +} + sub rcs_add ($) { #{{{ my $file=shift; @@ -376,6 +384,12 @@ sub rcs_remove ($) { # {{{ error("rcs_remove not implemented for monotone"); # TODO } #}}} +sub rcs_rename ($$) { # {{{ + my ($src, $dest) = @_; + + error("rcs_rename not implemented for monotone"); # TODO +} #}}} + sub rcs_recentchanges ($) { #{{{ my $num=shift; my @ret; diff --git a/IkiWiki/Rcs/svn.pm b/IkiWiki/Rcs/svn.pm index 6c15c2ca9..9081c3902 100644 --- a/IkiWiki/Rcs/svn.pm +++ b/IkiWiki/Rcs/svn.pm @@ -117,6 +117,28 @@ sub rcs_commit ($$$;$$) { #{{{ return undef # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + if (defined $user) { + $message="web commit by $user".(length $message ? ": $message" : ""); + } + elsif (defined $ipaddr) { + $message="web commit from $ipaddr".(length $message ? ": $message" : ""); + } + + if (system("svn", "commit", "--quiet", + "--encoding", "UTF-8", "-m", + possibly_foolish_untaint($message), + $config{srcdir}) != 0) { + warn("svn commit failed\n"); + return 1; # failure + } + return undef # success +} + sub rcs_add ($) { #{{{ # filename is relative to the root of the srcdir my $file=shift; @@ -139,18 +161,35 @@ sub rcs_remove ($) { #{{{ my $file=shift; if (-d "$config{srcdir}/.svn") { - my $parent=dirname($file); - while (! -d "$config{srcdir}/$parent/.svn") { - $file=$parent; - $parent=dirname($file); - } - if (system("svn", "rm", "--force", "--quiet", "$config{srcdir}/$file") != 0) { warn("svn rm failed\n"); } } } #}}} +sub rcs_rename ($$) { #{{{ + # filenames relative to the root of the srcdir + my ($src, $dest)=@_; + + if (-d "$config{srcdir}/.svn") { + # Add parent directory for $dest + my $parent=dirname($dest); + if (! -d "$config{srcdir}/$parent/.svn") { + while (! -d "$config{srcdir}/$parent/.svn") { + $parent=dirname($dest); + } + if (system("svn", "add", "--quiet", "$config{srcdir}/$parent") != 0) { + warn("svn add $parent failed\n"); + } + } + + if (system("svn", "mv", "--force", "--quiet", + "$config{srcdir}/$src", "$config{srcdir}/$dest") != 0) { + warn("svn rename failed\n"); + } + } +} #}}} + sub rcs_recentchanges ($) { #{{{ my $num=shift; my @ret; diff --git a/IkiWiki/Rcs/tla.pm b/IkiWiki/Rcs/tla.pm index 29dbd092a..4232e1fe8 100644 --- a/IkiWiki/Rcs/tla.pm +++ b/IkiWiki/Rcs/tla.pm @@ -78,6 +78,14 @@ sub rcs_commit ($$$;$$) { #{{{ return undef # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + error("rcs_commit_staged not implemented for tla"); # TODO +} + sub rcs_add ($) { #{{{ my $file=shift; @@ -94,6 +102,12 @@ sub rcs_remove ($) { # {{{ error("rcs_remove not implemented for tla"); # TODO } #}}} +sub rcs_rename ($$) { # {{{a + my ($src, $dest) = @_; + + error("rcs_rename not implemented for tla"); # TODO +} #}}} + sub rcs_recentchanges ($) { my $num=shift; my @ret; diff --git a/debian/changelog b/debian/changelog index b53d846d7..b44d8923d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,12 +2,13 @@ ikiwiki (2.55) UNRELEASED; urgency=low * remove: New plugin that adds the ability to remove pages via the web. (Sponsored by The TOVA Company.) + * All rcs backends need to implement rcs_remove, rcs_commitstaged, + and rcs_rename. (Done for svn, git). * rename: New plugin that adds the ability to rename pages via the web. (Sponsored by The TOVA Company.) (This one's for you, Kyle.) * prefix_directives enabled in doc wiki, all preprocessor directives converted. (Simon McVittie) * editpage: Don't show attachments link when attachments are disabled. - * All rcs backends need to implement rcs_remove. (Done for svn, git). * tag: Allow tagbase to be overridden by starting a tag with "./" or "/". (Simon McVittie) * Really fix bug with links to pages with names containing colons. -- 2.44.0