--- /dev/null
+(**Note:** this patch is built on top of the patch discussed at [[Attempt to extend Mercurial backend support]]. The `run_or_die()` function declared therein is needed for this patch to run.)
+
+Patch to change the Mercurial entries for `rcs_getctime` and `rcs_getmtime` from "slow"/"no" to "fast"/"fast" in [[/rcs]].
+
+The patch is mostly a slightly modified cc of the code in `git.pm`. The exception is that a Mercurial style file is needed to get a reasonable output from `hg log`. To make the file self-contained in its current state, this was solved with a generated temp file, but that section could and should be replaced with just setting `$tmpl_filename` to a path to a static file `map-cmdline.ikiwiki-log` (to conform with Mercurial's naming of its default styles) in the Ikiwiki distribution, with contents
+
+ changeset = "{date}\n{files}\n"
+ file = "{file}\n"
+
+which is based on an [example](http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html#id417978) in [Mercurial: The Definitive Guide](http://hgbook.red-bean.com/) (and otherwise fascinatingly undocumented). A style *file* is required for this kind of formatting. There is a switch `hg log --template` to directly control simple output formatting, but in this case, the `{file}` directive must be redefined, which can only be done with `hg log --style`.
+
+If `{file}` is not redefined, all filenames are output on a single line separated with a space. It is not possible to conclude if the space is part of a filename or just a separator, and thus impossible to use in this case. Some output filters are available in hg, but they are not fit for this cause (and would slow down the process unnecessarily).
+
+In the patch listing below, I've marked the parts of the patch that should be removed when the tempfile replacement is done with **Marker# start** and **Marker# end**.
+
+[Patch at pastebin](http://pastebin.com/QBE4UH6n).
+
+[Patch at pastebin with tempfile code replaced by a path to a static file (change path accordingly)](http://pastebin.com/dmSCRkUK).
+
+[My `mercurial.pm` in raw format after this and beforementioned patches (tempfile code present)](http://510x.se/hg/program/ikiwiki/raw-file/1b6c46b62a28/Plugin/mercurial.pm).
+
+--[[Daniel Andersson]]
+
+---
+
+ diff -r 78a217fb13f3 -r 1b6c46b62a28 Plugin/mercurial.pm
+ --- a/Plugin/mercurial.pm Sat Jul 16 03:19:25 2011 +0200
+ +++ b/Plugin/mercurial.pm Tue Jul 19 13:35:17 2011 +0200
+ @@ -310,28 +310,91 @@
+ # TODO
+ }
+
+ -sub rcs_getctime ($) {
+ - my ($file) = @_;
+ +{
+ +my %time_cache;
+
+ - my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v",
+ - "--style", "default", "$config{srcdir}/$file");
+ - open (my $out, "-|", @cmdline);
+ +sub findtimes ($$) {
+ + my $file=shift;
+ + my $id=shift; # 0 = mtime ; 1 = ctime
+
+ - my @log = (mercurial_log($out));
+ + if (! keys %time_cache) {
+ + my $date;
+
+ - if (@log < 1) {
+ - return 0;
+
+**Marker1 start**
+
+ + # The tempfile logic should be replaced with a file included
+ + # with ikiwiki containing
+ + # --
+ + # changeset = "{date}\n{files}\n"
+ + # file = "{file}\n"
+ + # --
+ + # to avoid creating a file with static contents every time this
+ + # function is called. The path to this file should replace
+ + # $tmpl_filename in run_or_die() below.
+ + #
+
+**Marker1 end**
+
+ + # It doesn't seem possible to specify the format wanted for the
+ + # changelog (same format as is generated in git.pm:findtimes(),
+ + # though the date differs slightly) without using a style
+ + # _file_. There is a "hg log" switch "--template" to directly
+ + # control simple output formatting, but in this case, the
+ + # {file} directive must be redefined, which can only be done
+ + # with "--style".
+ + #
+ + # If {file} is not redefined, all files are output on a single
+ + # line separated with a space. It is not possible to conclude
+ + # if the space is part of a filename or just a separator, and
+ + # thus impossible to use in this case.
+ + #
+ + # Some output filters are available in hg, but they are not fit
+ + # for this cause (and would slow down the process
+ + # unnecessarily).
+ +
+
+**Marker2 start**
+
+ + use File::Temp qw(tempfile);
+ + my ($tmpl_fh, $tmpl_filename) = tempfile(UNLINK => 1);
+ +
+ + print $tmpl_fh 'changeset = "{date}\\n{files}\\n"' . "\n";
+ + print $tmpl_fh 'file = "{file}\\n"' . "\n";
+ +
+
+**Marker2 end**
+
+ + foreach my $line (run_or_die('hg', 'log', '--style',
+ + $tmpl_filename)) {
+ + # {date} gives output on the form
+ + # 1310694511.0-7200
+ + # where the first number is UTC Unix timestamp with one
+ + # decimal (decimal always 0, at least on my system)
+ + # followed by local timezone offset from UTC in
+ + # seconds.
+ + if (! defined $date && $line =~ /^\d+\.\d[+-]\d*$/) {
+ + $line =~ s/^(\d+).*/$1/;
+ + $date=$line;
+ + }
+ + elsif (! length $line) {
+ + $date=undef;
+ + }
+ + else {
+ + my $f=$line;
+ +
+ + if (! $time_cache{$f}) {
+ + $time_cache{$f}[0]=$date; # mtime
+ + }
+ + $time_cache{$f}[1]=$date; # ctime
+ + }
+ + }
+
+**Marker3 start**
+
+ + close ($tmpl_fh);
+
+**Marker3 end**
+
+ }
+
+ - eval q{use Date::Parse};
+ - error($@) if $@;
+ -
+ - my $ctime = str2time($log[$#log]->{"date"});
+ - return $ctime;
+ + return exists $time_cache{$file} ? $time_cache{$file}[$id] : 0;
+ +}
+ +
+ +}
+ +
+ +sub rcs_getctime ($) {
+ + my $file = shift;
+ +
+ + return findtimes($file, 1);
+ }
+
+ sub rcs_getmtime ($) {
+ - error "rcs_getmtime is not implemented for mercurial\n"; # TODO
+ + my $file = shift;
+ +
+ + return findtimes($file, 0);
+ }
+
+ 1