[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Errors with mtime-retaining import script: pre-revprop-change issue?

From: Alexander Shenkin <subversion_at_shenkin.org>
Date: Wed, 25 Jan 2012 15:07:11 -0500

Hello again,

So, I've left my computer running the script below all day long. My
understanding is that it imports files one at a time, in chronological
order, setting the svn:date revision property each time to the timestamp
of the file. Thus, in my case, I end up with thousands of revisions
(corresponding to my thousands of files), with a different svn:date
revprop value for each revision.

What I *thought* this was supposed to accomplish was that, if you were
to checkout a new working version of the repository (and if you had
TortoiseSVN "set file dates to the 'last commit time'", or perhaps ran
svn checkout -r COMMITTED), your files would have their original
last-modified dates (aka timestamps, aka mtimes). However, when I
delete a file and do an svn update, the replaced file has the timestamp
of the HEAD revision in the repository. That is, the most recent file
imported. It does *not* have the timestamp of the original file.

I hope this makes sense. I'm moving over from CVS, so perhaps I'm still
stuck thinking about files instead of revisions, and perhaps that's
messing me up. This script sets the svn:date revprop of the HEAD
revision just prior to committing each file. Should that theoretically
work to set the commit time of each file, or did something change in
subversion between 2006 and now that would have made such logic not
operate as expected?

I can go into the repository and get the dates for each revision, and
they are as expected. It's just that I would have to specifically check
out each file at it's corresponding revision (i.e. not the HEAD
revision) in order to get its timestamp set properly.

Apologies if this is convoluted. Any help is *greatly* appreciated!

Thanks again,
Alex

the script from http://svn.haxx.se/users/archive-2006-10/1345.shtml :

#!/usr/bin/perl
# import files to subversion one by one and adjust commit date to file's
mtime
# this method is rather slow!
# directory timestamps are set to the mtime of the oldest file

# 2005-07-15 Oliver Betz

# instructions:
# create an empty repository, make sure to have a "pre-revprop-change" hook
# check out a working copy from the empty repository
# copy the whole tree of files to the working copy
# run this script from the WC root

# caution:
# - stat() fails on filenames with foreign characters.
# maybe conflicting translations from svn and perl?
# - (stat())->mtime reports wrong data using ActivePerl with NTFS.
Cygwin works.

use strict;

use File::stat; # by-name access to mtime
use File::Find;

my $rev; # revision of committed file
my $svnstat; # response of "svn stat"
my %files;
my $filename; # path to current file
my $mtime; # mtime of current file

$ENV{Lang}="C"; # else we might get localized responses

find({wanted => \&getfile, no_chdir => 1}, '.'); # all files and
directories in the tree

$mtime = svntime((sort(values(%files)))[0]), "\n"; # oldest file
print "svn propset svn:date $mtime --revprop -r HEAD\n";
print `svn propset svn:date $mtime --revprop -r HEAD\n`;

# first add all directories, they receive the time of the oldest file
foreach $filename (sort keys(%files)){
  next unless (-d $filename);
  print "svn add -N \"$filename\"\n";
  print `svn add -N "$filename"`; # put the file under svn control,
print response
}

foreach $filename (sort { $files{$a} <=> $files{$b} } keys(%files)) {
  next if (-d $filename); # directories have already been added
  $svnstat = `svn stat "$filename"`;
  next unless $svnstat =~ m/^\?.....\s+(\S.*)$/;
  # skip if ignored or already under version control

  print `svn add -N "$filename"`; # put the file under svn control
  $rev=`svn ci -m "mtime keeping add of $filename"`; # commit the file
immediately
  print "$rev"; # show complete response (several lines)
  die "wrong response $rev" unless $rev =~ /Committed revision (\d+)\./;
  # this is rather restrictive - 'next' might be a good alternative
  $rev = $1; # numerical value -> $rev

  $mtime = svntime($files{$filename}); # special format of svn time:
2005-07-11T09:17:35.000000Z

  print `svn propset svn:date $mtime --revprop -r $rev`;
}
print "ready\n";

# add file dates and file/dir types to hash
sub getfile {
  return if $File::Find::name eq "."; # don't add "."
  return if $File::Find::name =~ m{/.svn}; # don't add svn directories
  $files{$File::Find::name} = (stat($File::Find::name))->mtime; # add
file to hash
}

sub svntime {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(@_[0]);
  return sprintf
"%4d-%02d-%02dT%02d:%02d:%02d.000000Z",1900+$year,$mon+1,$mday,$hour,$min,$sec;
}
__END__

On 1/25/2012 11:15 AM, Alexander Shenkin wrote:
> Thanks everyone for your replies. I ended up finding a solution for a
> windows-executable pre-revprop-change.bat script here:
>
> http://stackoverflow.com/questions/6155/common-types-of-subversion-hooks/68850#68850
>
> now to lobby the dev team to add mtime-handling options in future
> versions! Unfortunately, I don't see it in the plans for version 1.8,
> even though it was "1.8-consider" in the tigris bug tracker...
>
> alex
>
> On 1/25/2012 11:00 AM, Giulio Troccoli wrote:
>>
>> On 25/01/12 15:09, Alexander Shenkin wrote:
>>> Hello,
>>>
>>> I'm using the svn import script by Oliver Betz to retain file mtime
>>> upon initial import
>>> (http://svn.haxx.se/users/archive-2006-10/1345.shtml), but i'm
>>> getting some errors. I'm hoping someone might be able to help me out.
>>>
>>> when i run the script, i get the following error:
>>>
>>> $ perl importWithMtime.pl
>>> svn propset svn:date 2001-10-29T18:34:10.000000Z --revprop -r HEAD
>>> svn: E175002: DAV request failed; it's possible that the
>>> repository's pre-revprop-change hook either failed or is
>>> non-existent
>>> svn: E175008: At least one property change failed; repository is
>>> unchanged
>>> svn: E175002: Error setting property 'date':
>>> Repository has not been enabled to accept revision propchanges;
>>> ask the administrator to create a pre-revprop-change hook
>>>
>>> I do have a pre-revprop-change.tmpl hook in the repository. It
>>> contains the code below. I'm using VisualSVN 2.5.2 on a Windows 7
>>> x64 machine with Cygwin Perl and TortoiseSVN. Any help would be
>>> greatly appreciated!
>>>
>>> Thanks,
>>> Alex
>>>
>>>
>>> -------------------
>>>
>>> $ cat pre-revprop-change.tmpl
>>> #!/bin/sh
>>>
>>> # PRE-REVPROP-CHANGE HOOK
>>> #
>>> # The pre-revprop-change hook is invoked before a revision property
>>> # is added, modified or deleted. Subversion runs this hook by invoking
>>> # a program (script, executable, binary, etc.) named
>>> 'pre-revprop-change'
>>> # (for which this file is a template), with the following ordered
>>> # arguments:
>>> #
>>> # [1] REPOS-PATH (the path to this repository)
>>> # [2] REV (the revision being tweaked)
>>> # [3] USER (the username of the person tweaking the property)
>>> # [4] PROPNAME (the property being set on the revision)
>>> # [5] ACTION (the property is being 'A'dded, 'M'odified, or
>>> 'D'eleted)
>>> #
>>> # [STDIN] PROPVAL ** the new property value is passed via STDIN.
>>> #
>>> # If the hook program exits with success, the propchange happens; but
>>> # if it exits with failure (non-zero), the propchange doesn't happen.
>>> # The hook program can use the 'svnlook' utility to examine the
>>> # existing value of the revision property.
>>> #
>>> # WARNING: unlike other hooks, this hook MUST exist for revision
>>> # properties to be changed. If the hook does not exist, Subversion
>>> # will behave as if the hook were present, but failed. The reason
>>> # for this is that revision properties are UNVERSIONED, meaning that
>>> # a successful propchange is destructive; the old value is gone
>>> # forever. We recommend the hook back up the old value somewhere.
>>> #
>>> # On a Unix system, the normal procedure is to have 'pre-revprop-change'
>>> # invoke other programs to do the real work, though it may do the
>>> # work itself too.
>>> #
>>> # Note that 'pre-revprop-change' must be executable by the user(s)
>>> who will
>>> # invoke it (typically the user httpd runs as), and that user must
>>> # have filesystem-level permission to access the repository.
>>> #
>>> # On a Windows system, you should name the hook program
>>> # 'pre-revprop-change.bat' or 'pre-revprop-change.exe',
>>> # but the basic idea is the same.
>>> #
>>> # The hook program typically does not inherit the environment of
>>> # its parent process. For example, a common problem is for the
>>> # PATH environment variable to not be set to its usual value, so
>>> # that subprograms fail to launch unless invoked via absolute path.
>>> # If you're having unexpected problems with a hook program, the
>>> # culprit may be unusual (or missing) environment variables.
>>> #
>>> # Here is an example hook script, for a Unix /bin/sh interpreter.
>>> # For more examples and pre-written hooks, see those in
>>> # the Subversion repository at
>>> #
>>> http://svn.apache.org/repos/asf/subversion/trunk/tools/hook-scripts/ and
>>> # http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/
>>>
>>>
>>> REPOS="$1"
>>> REV="$2"
>>> USER="$3"
>>> PROPNAME="$4"
>>> ACTION="$5"
>>>
>>> if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
>>>
>>> echo "Changing revision properties other than svn:log is prohibited" >&2
>>> exit 1
>>
>> The hook has to be called pre-revprop-change on *nix systems and be
>> executable or pre-revprop-change.bat on Windows. So, no .tmpl extension.
Received on 2012-01-25 21:07:55 CET

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.