]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn
link to submodule support question
[ikiwiki.git] / doc / todo / rcs__95__get__123__c__44__m__125__time_implementation_for_Mercurial_backend__44___based_on_Git_backend.mdwn
1 (**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.)
2
3 Patch to change the Mercurial entries for `rcs_getctime` and `rcs_getmtime` from "slow"/"no" to "fast"/"fast" in [[/rcs]].
4
5 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
6
7         changeset = "{date}\n{files}\n"
8         file = "{file}\n"
9
10 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`.
11
12 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).
13
14 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**.
15
16 [Patch at pastebin](http://pastebin.com/QBE4UH6n).
17
18 [Patch at pastebin with tempfile code replaced by a path to a static file (change path accordingly)](http://pastebin.com/dmSCRkUK).
19
20 [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).
21
22 --[[Daniel Andersson]]
23
24 > I have applied this, but I left the temp file in. 
25 > The overhead seems small since it will only be run once per ikiwiki run,
26 > and only when `ikiwiki --gettime` is run, or the first time
27 > ikiwiki runs. Thanks for this! [[done]] --[[Joey]] 
28
29 ---
30
31         diff -r 78a217fb13f3 -r 1b6c46b62a28 Plugin/mercurial.pm
32         --- a/Plugin/mercurial.pm       Sat Jul 16 03:19:25 2011 +0200
33         +++ b/Plugin/mercurial.pm       Tue Jul 19 13:35:17 2011 +0200
34         @@ -310,28 +310,91 @@
35                 # TODO
36          }
37          
38         -sub rcs_getctime ($) {
39         -       my ($file) = @_;
40         +{
41         +my %time_cache;
42          
43         -       my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v",
44         -               "--style", "default", "$config{srcdir}/$file");
45         -       open (my $out, "-|", @cmdline);
46         +sub findtimes ($$) {
47         +       my $file=shift;
48         +       my $id=shift; # 0 = mtime ; 1 = ctime
49          
50         -       my @log = (mercurial_log($out));
51         +       if (! keys %time_cache) {
52         +               my $date;
53          
54         -       if (@log < 1) {
55         -               return 0;
56
57 **Marker1 start**
58
59         +               # The tempfile logic should be replaced with a file included
60         +               # with ikiwiki containing
61         +               # --
62         +               # changeset = "{date}\n{files}\n"
63         +               # file = "{file}\n"
64         +               # --
65         +               # to avoid creating a file with static contents every time this
66         +               # function is called. The path to this file should replace
67         +               # $tmpl_filename in run_or_die() below.
68         +               #
69
70 **Marker1 end**
71
72         +               # It doesn't seem possible to specify the format wanted for the
73         +               # changelog (same format as is generated in git.pm:findtimes(),
74         +               # though the date differs slightly) without using a style
75         +               # _file_. There is a "hg log" switch "--template" to directly
76         +               # control simple output formatting, but in this case, the
77         +               # {file} directive must be redefined, which can only be done
78         +               # with "--style".
79         +               #
80         +               # If {file} is not redefined, all files are output on a single
81         +               # line separated with a space. It is not possible to conclude
82         +               # if the space is part of a filename or just a separator, and
83         +               # thus impossible to use in this case.
84         +               # 
85         +               # Some output filters are available in hg, but they are not fit
86         +               # for this cause (and would slow down the process
87         +               # unnecessarily).
88         +
89
90 **Marker2 start**
91
92         +               use File::Temp qw(tempfile);
93         +               my ($tmpl_fh, $tmpl_filename) = tempfile(UNLINK => 1);
94         +
95         +               print $tmpl_fh 'changeset = "{date}\\n{files}\\n"' . "\n";
96         +               print $tmpl_fh 'file = "{file}\\n"' . "\n";
97         +
98
99 **Marker2 end**
100
101         +               foreach my $line (run_or_die('hg', 'log', '--style',
102         +                               $tmpl_filename)) {
103         +                       # {date} gives output on the form
104         +                       # 1310694511.0-7200
105         +                       # where the first number is UTC Unix timestamp with one
106         +                       # decimal (decimal always 0, at least on my system)
107         +                       # followed by local timezone offset from UTC in
108         +                       # seconds.
109         +                       if (! defined $date && $line =~ /^\d+\.\d[+-]\d*$/) {
110         +                               $line =~ s/^(\d+).*/$1/;
111         +                               $date=$line;
112         +                       }
113         +                       elsif (! length $line) {
114         +                               $date=undef;
115         +                       }
116         +                       else {
117         +                               my $f=$line;
118         +
119         +                               if (! $time_cache{$f}) {
120         +                                       $time_cache{$f}[0]=$date; # mtime
121         +                               }
122         +                               $time_cache{$f}[1]=$date; # ctime
123         +                       }
124         +               }
125
126 **Marker3 start**
127
128         +               close ($tmpl_fh);
129
130 **Marker3 end**
131
132                 }
133          
134         -       eval q{use Date::Parse};
135         -       error($@) if $@;
136         -       
137         -       my $ctime = str2time($log[$#log]->{"date"});
138         -       return $ctime;
139         +       return exists $time_cache{$file} ? $time_cache{$file}[$id] : 0;
140         +}
141         +
142         +}
143         +
144         +sub rcs_getctime ($) {
145         +       my $file = shift;
146         +
147         +       return findtimes($file, 1);
148          }
149          
150          sub rcs_getmtime ($) {
151         -       error "rcs_getmtime is not implemented for mercurial\n"; # TODO
152         +       my $file = shift;
153         +
154         +       return findtimes($file, 0);
155          }
156          
157          1