(no commit message)
authorhttps://www.google.com/accounts/o8/id?id=AItOawmUWmB1M35_jviFvGPYDIH-a-_Al-7OrXM <Daniel@web>
Tue, 19 Jul 2011 12:44:32 +0000 (08:44 -0400)
committeradmin <admin@branchable.com>
Tue, 19 Jul 2011 12:44:32 +0000 (08:44 -0400)
doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn [new file with mode: 0644]

diff --git a/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn b/doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn
new file mode 100644 (file)
index 0000000..6cd195a
--- /dev/null
@@ -0,0 +1,152 @@
+(**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