158 lines
5.6 KiB
Markdown
158 lines
5.6 KiB
Markdown
(**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]]
|
|
|
|
> I have applied this, but I left the temp file in.
|
|
> The overhead seems small since it will only be run once per ikiwiki run,
|
|
> and only when `ikiwiki --gettime` is run, or the first time
|
|
> ikiwiki runs. Thanks for this! [[done]] --[[Joey]]
|
|
|
|
---
|
|
|
|
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
|