--gettime revamp

* Rename --getctime to --gettime. (The old name still works for
  backwards compatability.)
* --gettime now also looks up last modification time.
* Add rcs_getmtime to plugin API; currently only implemented
  for git.
master
Joey Hess 2010-04-16 17:02:29 -04:00
parent 6c5c0f8c68
commit b14f84c4ac
22 changed files with 109 additions and 57 deletions

View File

@ -440,10 +440,10 @@ sub getsetup () {
safe => 0, safe => 0,
rebuild => 0, rebuild => 0,
}, },
getctime => { gettime => {
type => "internal", type => "internal",
default => 0, default => 0,
description => "running in getctime mode", description => "running in gettime mode",
safe => 0, safe => 0,
rebuild => 0, rebuild => 0,
}, },
@ -1790,6 +1790,10 @@ sub rcs_getctime ($) {
$hooks{rcs}{rcs_getctime}{call}->(@_); $hooks{rcs}{rcs_getctime}{call}->(@_);
} }
sub rcs_getmtime ($) {
$hooks{rcs}{rcs_getmtime}{call}->(@_);
}
sub rcs_receive () { sub rcs_receive () {
$hooks{rcs}{rcs_receive}{call}->(); $hooks{rcs}{rcs_receive}{call}->();
} }

View File

@ -20,6 +20,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub checkconfig () { sub checkconfig () {
@ -306,4 +307,8 @@ sub rcs_getctime ($) {
return $ctime; return $ctime;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for bzr\n"; # TODO
}
1 1

View File

@ -49,6 +49,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub genwrapper () { sub genwrapper () {
@ -485,4 +486,8 @@ sub rcs_getctime ($) {
return $date; return $date;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for cvs\n"; # TODO
}
1 1

View File

@ -18,6 +18,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub silentsystem (@) { sub silentsystem (@) {
@ -427,4 +428,8 @@ sub rcs_getctime ($) {
return $date; return $date;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for darcs\n"; # TODO
}
1 1

View File

@ -25,6 +25,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive); hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive);
} }
@ -634,6 +635,10 @@ sub rcs_getctime ($) {
return $ctime; return $ctime;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for git\n"; # TODO
}
sub rcs_receive () { sub rcs_receive () {
# The wiki may not be the only thing in the git repo. # The wiki may not be the only thing in the git repo.
# Determine if it is in a subdirectory by examining the srcdir, # Determine if it is in a subdirectory by examining the srcdir,

View File

@ -20,6 +20,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub checkconfig () { sub checkconfig () {
@ -254,4 +255,8 @@ sub rcs_getctime ($) {
return $ctime; return $ctime;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for mercurial\n"; # TODO
}
1 1

View File

@ -23,6 +23,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub checkconfig () { sub checkconfig () {
@ -693,4 +694,8 @@ sub rcs_getctime ($) {
return $date; return $date;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for monotone\n"; # TODO
}
1 1

View File

@ -18,6 +18,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub getsetup () { sub getsetup () {
@ -63,7 +64,11 @@ sub rcs_diff ($) {
} }
sub rcs_getctime ($) { sub rcs_getctime ($) {
error gettext("getctime not implemented"); return 0;
}
sub rcs_getmtime ($) {
return 0;
} }
1 1

View File

@ -19,6 +19,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub checkconfig () { sub checkconfig () {
@ -379,4 +380,8 @@ sub rcs_getctime ($) {
return $date; return $date;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for svn\n"; # TODO
}
1 1

View File

@ -18,6 +18,7 @@ sub import {
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges); hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
} }
sub checkconfig () { sub checkconfig () {
@ -284,4 +285,8 @@ sub rcs_getctime ($) {
return $date; return $date;
} }
sub rcs_getmtime ($) {
error "rcs_getmtime is not implemented for tla\n"; # TODO
}
1 1

View File

@ -365,14 +365,26 @@ sub find_new_files ($) {
} }
else { else {
push @new, $file; push @new, $file;
if ($config{getctime} && -e "$config{srcdir}/$file") { if ($config{gettime} && -e "$config{srcdir}/$file") {
eval { eval {
my $time=rcs_getctime("$config{srcdir}/$file"); my $ctime=rcs_getctime("$config{srcdir}/$file");
$pagectime{$page}=$time; if ($ctime > 0) {
$pagectime{$page}=$ctime;
}
}; };
if ($@) { if ($@) {
print STDERR $@; print STDERR $@;
} }
my $mtime;
eval {
my $mtime=rcs_getmtime("$config{srcdir}/$file");
};
if ($@) {
print STDERR $@;
}
elsif ($mtime > 0) {
utime($mtime, $mtime, "$config{srcdir}/$file");
}
} }
} }
$pagecase{lc $page}=$page; $pagecase{lc $page}=$page;

5
debian/changelog vendored
View File

@ -44,6 +44,11 @@ ikiwiki (3.20100415) UNRELEASED; urgency=low
* conditional: Fix bug that forced "all" mode off by default. * conditional: Fix bug that forced "all" mode off by default.
* calendarmonth.tmpl: The month calendar is now put in a sidebar. * calendarmonth.tmpl: The month calendar is now put in a sidebar.
* calendar: Improved display of arrows. * calendar: Improved display of arrows.
* Rename --getctime to --gettime. (The old name still works for
backwards compatability.)
* --gettime now also looks up last modification time.
* Add rcs_getmtime to plugin API; currently only implemented
for git.
-- Joey Hess <joeyh@debian.org> Sun, 04 Apr 2010 12:17:11 -0400 -- Joey Hess <joeyh@debian.org> Sun, 04 Apr 2010 12:17:11 -0400

View File

@ -20,15 +20,17 @@ Do I have it right?
> Some VCS, like git, set the file mtimes to the current time > Some VCS, like git, set the file mtimes to the current time
> when making a new checkout, so they will be lost if you do that. > when making a new checkout, so they will be lost if you do that.
> The creation times can be retrived using the `--getctime` option. > The creation times can be retrived using the `--getctime` option.
> I suppose it might be nice if there were a `--getmtime` that pulled > --[[Joey]]
> true modification times out of the VCS, but I haven't found it a big
> deal in practice for the last modification times to be updated to the
> current time when rebuilding a wiki like this. --[[Joey]]
> >
> > Thanks for the clarification. I ran some tests of my own to make sure I understand it right, and I'm satisfied > > Thanks for the clarification. I ran some tests of my own to make sure I understand it right, and I'm satisfied
> > that the order of posts in my blog can be retrieved from the VCS using the `--getctime` option, at least if I > > that the order of posts in my blog can be retrieved from the VCS using the `--getctime` option, at least if I
> > choose to order my posts by creation time rather than modification time. But I now know that I can't rely on > > choose to order my posts by creation time rather than modification time. But I now know that I can't rely on
> > page modification times in ikiwiki as these can be lost permanently. > > page modification times in ikiwiki as these can be lost permanently.
>
> > > Update: It's now renamed to `--gettime`, and pulls both the creation
> > > and modification times. Also, per [[todo/auto_getctime_on_fresh_build]],
> > > this is now done automatically the first time ikiwiki builds a
> > > srcdir. So, no need to worry about this any more! --[[Joey]]
> > > >
> > I would suggest that there should at least be a `--getmtime` option like you describe, and perhaps that > > I would suggest that there should at least be a `--getmtime` option like you describe, and perhaps that
> > `--getctime` and `--getmtime` be _on by default_. In my opinion the creation times and modification times of > > `--getctime` and `--getmtime` be _on by default_. In my opinion the creation times and modification times of
@ -91,19 +93,6 @@ Do I have it right?
> A quick workaround for me to get modification times right is the following > A quick workaround for me to get modification times right is the following
> little zsh script, which unfortunately only works for git: > little zsh script, which unfortunately only works for git:
#!/usr/bin/env zsh >> Elided; no longer needed since --gettime does that, and much faster! --[[Joey]]
set +x
for FILE in **/*(.); do
TIMES="`git log --pretty=format:%ai $FILE`"
MTIME="`echo $TIMES | head -n1`"
if [ ! -z $MTIME ]; then
echo touch -m -d "$MTIME" $FILE
touch -m -d "$MTIME" $FILE
fi
done
> --[[David_Riebenbauer]] > --[[David_Riebenbauer]]

View File

@ -20,10 +20,6 @@ How do I set up an ikiwiki system using a pre-existing repository (instead of cr
> recreate the ikiwiki srcdir > recreate the ikiwiki srcdir
> 3. `git clone` from the bare git repository a second time, > 3. `git clone` from the bare git repository a second time,
> to create a checkout you can manually edit (optional) > to create a checkout you can manually edit (optional)
> 4. run `ikiwiki --getctime --setup your.setup`
> The getctime will ensure page creation times are accurate
> by putting the info out of the git history,
> and only needs to be done once.
> >
> If you preserved your repository, but not the setup file, > If you preserved your repository, but not the setup file,
> the easiest way to make one is probably to run > the easiest way to make one is probably to run

View File

@ -1085,6 +1085,13 @@ it up in the history.
It's ok if this is not implemented, and throws an error. It's ok if this is not implemented, and throws an error.
#### `rcs_getmtime($)`
This is used to get the page modification time for a file from the RCS, by
looking it up in the history.
It's ok if this is not implemented, and throws an error.
#### `rcs_receive()` #### `rcs_receive()`
This is called when ikiwiki is running as a pre-receive hook (or This is called when ikiwiki is running as a pre-receive hook (or

View File

@ -14,8 +14,10 @@ use, some advanced or special features are not supported in all of them.
Lack of support in [[ikiwiki-makerepo]] or auto.setup can make it harder to Lack of support in [[ikiwiki-makerepo]] or auto.setup can make it harder to
set up a wiki using that revision control system. The `rcs_commit_staged` set up a wiki using that revision control system. The `rcs_commit_staged`
hook is needed to use [[attachments|plugins/attachment]] or hook is needed to use [[attachments|plugins/attachment]] or
[[plugins/comments]]. And so on. The table below summarises this for each [[plugins/comments]]. `rcs_getctime` may be implemented in a fast way
revision control system and links to more information about each. (ie, one log lookup for all files), or very slowly (one lookup per file).
And so on. The table below summarises this for each revision control
system and links to more information about each.
[[!table data=""" [[!table data="""
feature |[[git]]|[[svn]]|[[bzr]] |[[monotone]]|[[mercurial]]|[[darcs]]|[[tla]] |[[cvs]] feature |[[git]]|[[svn]]|[[bzr]] |[[monotone]]|[[mercurial]]|[[darcs]]|[[tla]] |[[cvs]]
@ -25,6 +27,8 @@ auto.setup |yes |yes |incomplete|yes |incomplete |yes
`rcs_rename` |yes |yes |yes |yes |no |yes |no |yes `rcs_rename` |yes |yes |yes |yes |no |yes |no |yes
`rcs_remove` |yes |yes |yes |yes |no |yes |no |yes `rcs_remove` |yes |yes |yes |yes |no |yes |no |yes
`rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes `rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes
`rcs_getctime` |fast |slow |slow |slow |slow |slow |slow |slow
`rcs_getmtime` |fast |no |no |no |no |no |no |no
anonymous push |yes |no |no |no |no |no |no |no anonymous push |yes |no |no |no |no |no |no |no
conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes
"""]] """]]

View File

@ -1,6 +1,6 @@
Use case: You want to move away from Wordpress to Ikiwiki as your blogging/website platform, but you want to retain your old posts. Use case: You want to move away from Wordpress to Ikiwiki as your blogging/website platform, but you want to retain your old posts.
[This](http://git.chris-lamb.co.uk/?p=ikiwiki-wordpress-import.git) is a simple tool that generates [git-fast-import](http://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html)-compatible data from a WordPress export XML file. It retains creation time of each post, so you can use Ikiwiki's <tt>--getctime</tt> to get the preserve creation times on checkout. [This](http://git.chris-lamb.co.uk/?p=ikiwiki-wordpress-import.git) is a simple tool that generates [git-fast-import](http://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html)-compatible data from a WordPress export XML file. It retains creation time of each post, so you can use Ikiwiki's <tt>--gettime</tt> to get the preserve creation times on checkout.
WordPress categories are mapped onto Ikiwiki tags. The ability to import comments is planned. WordPress categories are mapped onto Ikiwiki tags. The ability to import comments is planned.

View File

@ -6,14 +6,15 @@ My database appears corrupted:
No idea how this happened. I've blown it away and recreated it but, for future reference, is there any less violent way to recover from this situation? I miss having the correct created and last edited times. --[[sabr]] No idea how this happened. I've blown it away and recreated it but, for future reference, is there any less violent way to recover from this situation? I miss having the correct created and last edited times. --[[sabr]]
> update: fixed ctimes and mtimes using [these instructions](http://u32.net/Mediawiki_Conversion/Git_Import/#Correct%20Creation%20and%20Last%20Edited%20time) --[[sabr]] > update: fixed ctimes and mtimes using [these instructions](http://u32.net/Mediawiki_Conversion/Git_Import/#Correct%20Creation%20and%20Last%20Edited%20time) --[[sabr]]
> That's overly complex. Just run `ikiwiki -setup your.setup -getctime`. > That's overly complex. Just run `ikiwiki -setup your.setup -gettime`.
> BTW, I'd be interested in examining such a corrupt storable file to try > BTW, I'd be interested in examining such a corrupt storable file to try
> to see what happened to it. --[[Joey]] > to see what happened to it. --[[Joey]]
>> --getctime appears to only set the last edited date. It's not supposed to set the creation date, is it? The only place that info is stored is in the git repo. >> --gettime appears to only set the last edited date. It's not supposed to set the creation date, is it? The only place that info is stored is in the git repo.
>>> Pulling the page creation date out of the git history is exactly what >>> Pulling the page creation date out of the git history is exactly what
>>> --getctime does. --[[Joey]] >>> --gettime does. (It used to be called --getctime, and only do that; now
>>> it also pulls out the last modified date). --[[Joey]]
>> Alas, I seem to have lost the bad index file to periodic /tmp wiping; I'll send it to you if it happens again. --[[sabr]] >> Alas, I seem to have lost the bad index file to periodic /tmp wiping; I'll send it to you if it happens again. --[[sabr]]

View File

@ -1,9 +1,13 @@
[[!tag wishlist]] [[!tag wishlist]]
It might be a good idea to enable --getctime when `.ikiwiki` does not It might be a good idea to enable --gettime when `.ikiwiki` does not
exist. This way a new checkout of a `srcdir` would automatically get exist. This way a new checkout of a `srcdir` would automatically get
ctimes right. (Running --getctime whenever a rebuild is done would be too ctimes right. (Running --gettime whenever a rebuild is done would be too
slow.) --[[Joey]] slow.) --[[Joey]]
Could this be too annoying in some cases, eg, checking out a large wiki Could this be too annoying in some cases, eg, checking out a large wiki
that needs to get set up right away? --[[Joey]] that needs to get set up right away? --[[Joey]]
> Not for git with the new, optimised --getctime. For other VCS.. well,
> pity they're not as fast as git ;), but it is a one-time expense...
> [[done]] --[[Joey]]

View File

@ -320,13 +320,11 @@ also be configured using a setup file.
intercepted. If you enable this option then you must run at least the intercepted. If you enable this option then you must run at least the
CGI portion of ikiwiki over SSL. CGI portion of ikiwiki over SSL.
* --getctime * --gettime
Pull creation time for each new page out of the revision control Extract creation and modification times for each new page from the
system. This rarely used option provides a way to get the real creation the revision control's log. This is done automatically when building a
times of items in weblogs, such as when building a wiki from a new wiki for the first time, so you normally do not need to use this option.
VCS checkout. It is unoptimised and quite slow. It is best used
with --rebuild, to force ikiwiki to get the ctime for all pages.
* --set var=value * --set var=value

View File

@ -44,7 +44,8 @@ sub getconfig () {
"wrappergroup=s" => \$config{wrappergroup}, "wrappergroup=s" => \$config{wrappergroup},
"usedirs!" => \$config{usedirs}, "usedirs!" => \$config{usedirs},
"prefix-directives!" => \$config{prefix_directives}, "prefix-directives!" => \$config{prefix_directives},
"getctime" => \$config{getctime}, "getctime" => \$config{gettime},
"gettime" => \$config{gettime},
"numbacklinks=i" => \$config{numbacklinks}, "numbacklinks=i" => \$config{numbacklinks},
"rcs=s" => \$config{rcs}, "rcs=s" => \$config{rcs},
"no-rcs" => sub { $config{rcs}="" }, "no-rcs" => sub { $config{rcs}="" },

View File

@ -1,14 +0,0 @@
#!/bin/sh
# Sets mtimes of all files in the tree their last change date
# based on git's log. Useful to avoid too new dates after a
# fresh checkout, which lead to ikiwiki unnecessarily rebuilding
# basewiki files on upgrade.
if [ -d .git ]; then
for file in $(git ls-files); do
date="$(git log -1 --date=rfc "$file" | grep ^Date: | sed -e 's/Date://')"
if [ -n "$date" ]; then
echo "$date $file"
touch -d"$date" $file
fi
done
fi