2 # For subversion support.
9 sub svn_info ($$) { #{{{
13 my $info=`LANG=C svn info $file`;
14 my ($ret)=$info=~/^$field: (.*)$/m;
18 sub rcs_update () { #{{{
19 if (-d "$config{srcdir}/.svn") {
20 if (system("svn", "update", "--quiet", $config{srcdir}) != 0) {
21 warn("svn update failed\n");
26 sub rcs_prepedit ($) { #{{{
27 # Prepares to edit a file under revision control. Returns a token
28 # that must be passed into rcs_commit when the file is ready
30 # The file is relative to the srcdir.
33 if (-d "$config{srcdir}/.svn") {
34 # For subversion, return the revision of the file when
36 my $rev=svn_info("Revision", "$config{srcdir}/$file");
37 return defined $rev ? $rev : "";
41 sub rcs_commit ($$$) { #{{{
42 # Tries to commit the page; returns undef on _success_ and
43 # a version of the page with the rcs's conflict markers on failure.
44 # The file is relative to the srcdir.
49 if (-d "$config{srcdir}/.svn") {
50 # Check to see if the page has been changed by someone
51 # else since rcs_prepedit was called.
52 my ($oldrev)=$rcstoken=~/^([0-9]+)$/; # untaint
53 my $rev=svn_info("Revision", "$config{srcdir}/$file");
54 if (defined $rev && defined $oldrev && $rev != $oldrev) {
55 # Merge their changes into the file that we've
57 chdir($config{srcdir}); # svn merge wants to be here
58 if (system("svn", "merge", "--quiet", "-r$oldrev:$rev",
59 "$config{srcdir}/$file") != 0) {
60 warn("svn merge -r$oldrev:$rev failed\n");
64 if (system("svn", "commit", "--quiet", "-m",
65 possibly_foolish_untaint($message),
66 "$config{srcdir}") != 0) {
67 my $conflict=readfile("$config{srcdir}/$file");
68 if (system("svn", "revert", "--quiet", "$config{srcdir}/$file") != 0) {
69 warn("svn revert failed\n");
74 return undef # success
77 sub rcs_add ($) { #{{{
78 # filename is relative to the root of the srcdir
81 if (-d "$config{srcdir}/.svn") {
82 my $parent=dirname($file);
83 while (! -d "$config{srcdir}/$parent/.svn") {
85 $parent=dirname($file);
88 if (system("svn", "add", "--quiet", "$config{srcdir}/$file") != 0) {
89 warn("svn add failed\n");
94 sub rcs_recentchanges ($) { #{{{
98 eval q{use CGI 'escapeHTML'};
99 eval q{use Date::Parse};
100 eval q{use Time::Duration};
102 if (-d "$config{srcdir}/.svn") {
103 my $svn_url=svn_info("URL", $config{srcdir});
105 # FIXME: currently assumes that the wiki is somewhere
106 # under trunk in svn, doesn't support other layouts.
107 my ($svn_base)=$svn_url=~m!(/trunk(?:/.*)?)$!;
109 my $div=qr/^--------------------+$/;
110 my $infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
112 my ($rev, $user, $when, @pages, @message);
113 foreach (`LANG=C svn log --limit $num -v '$svn_url'`) {
115 if ($state eq 'start' && /$div/) {
118 elsif ($state eq 'header' && /$infoline/) {
121 $when=concise(ago(time - str2time($3)));
123 elsif ($state eq 'header' && /^\s+[A-Z]\s+\Q$svn_base\E\/([^ ]+)(?:$|\s)/) {
125 my $diffurl=$config{diffurl};
126 $diffurl=~s/\[\[file\]\]/$file/g;
127 $diffurl=~s/\[\[r1\]\]/$rev - 1/eg;
128 $diffurl=~s/\[\[r2\]\]/$rev/g;
130 link => htmllink("", pagename($file), 1),
134 elsif ($state eq 'header' && /^$/) {
137 elsif ($state eq 'body' && /$div/) {
138 my $committype="web";
139 if (defined $message[0] &&
140 $message[0]->{line}=~/^web commit by (\w+):?(.*)/) {
142 $message[0]->{line}=$2;
148 push @ret, { rev => $rev,
149 user => htmllink("", $user, 1),
150 committype => $committype,
151 when => $when, message => [@message],
154 return @ret if @ret >= $num;
157 $rev=$user=$when=undef;
160 elsif ($state eq 'body') {
161 push @message, {line => escapeHTML($_)},