Enclosed is a solution to continuous import the FreeBSD Project's
Subversion repository as a vendor branch of Perforce.  It's still a
bit rough around the edges, but hasn't broken on me yet.

I am not a Perl expert, so I'm sure there's lots of room for improvement
in the Perl portions of this solution.

The components are:

p4convert-svn_freebsd7x86_64
============================
This is Perforce's conversion utility.  They didn't have a version that
would run on my 8-stable system, so I worked with Marc Tooley of
Perforce support to get this built.  The tool processes an xml svn log
and svn repository and imports changesets with high fidelity into
Perforce (e.g. branches/merges become p4 integrations).  It does not
preserve author or date information.  For that, you need changemap_search.pl

changemap_search.pl
===================
This is a modified version of a script I got from Marc Tooley.  It
scans p4 revsions looking for those that include a "tag line" inserted
by p4convert-svn into the description text of imported revisions.  The
author and date information are extracted from the tag, used to update
the p4 change data (script must run as a user that has "change -f" privledges)
and moves/changes the tag to be at the end of the description text.  This
last step avoids having the conversion tag render the one line change summary
in p4v or "p4 changes", useless.

Since I wanted to guarantee that user names could not collide with local P4
users at Spectra Logic where I work, I added the ability to modify the user
name for the change with a prefix and/or suffix.  We use "-fbsd" here.

To avoid consuming license slots, the script dynamically creates and removes
user accounts for users that do not already exist during the change -f update.
According to Marc, having a valid user for a "change -f" operation didn't
use to be necessary, but with 2009.2 it is.

The original "changemap.pl" script doesn't search through committed change
sets for it's data.  Instead it relies on the revmap.csv and changemap.csv
files that are created during p4convert-svn's run.  Unfortunately, some
imported SVN revisions are mapped to multiple P4 revisions.  In this case,
the converter only records the first p4 change number.  Since commits
due to normal developer activity can be interleaved with those from the
converter, I didn't want to make any assumption that imported revisions
would be contiguous.  Hence the need to do a search.

FreeBSD-importer.pl
===================
This is a wrapper around the converter and changemap pieces to drive the
whole show.  At SpectraLogic we run this script every 5 minutes from
cron via the following /etc/crontab entry:

*/5	*	*	*	*	p4importer	lockf -t 0 -k /vmpool/FreeBSD-importer/lockfile /vmpool/FreeBSD-importer/perforce/FreeBSD-importer.pl > /dev/null

The steps executed by the script are:

 1) Use svnsync to update a local version of the FreeBSD repository to
    include the latest revisions from the master.

    I had two problems with going straight to the project's repository;

     o When extracting the log from the FreeBSD repository, early revisions
       didn't include the "kind" attribute required by p4convert-svn.  This
       attribute didn't exist in the version of SVN first used by the
       project.  svnsync from a recent version of SVN will add this missing
       meta-data during the copy.

     o p4convert_svn will bail out if svn dies due to a dropped network
       connection.  On large svn updates (e.g. a whole branch of head
       to a project or user tree) this would happen often.  I haven't
       seen a problem yet when operating on a local repository.

 2) Determine the SVN revision range to import

 3) Extract an XML SVN log for this revision range.

 4) Run p4convert_svn to pull in the new revisions.

 5) Run changemap_search.pl to update author/date information.

What the script doesn't do
==========================
You'll need to bootstrap the process:

 1) Initialize the SVN repo for your local copy of FreeBSD's SVN:

    echo Fixing pre-revprop-change hook to prep for svnsync init
    echo "#!/bin/sh" > /svnroot/hooks/pre-revprop-change
    echo "exit 0" >> /svnroot/hooks/pre-revprop-change
    chmod 0755 /svnroot/hooks/pre-revprop-change
    svnsync --non-interactive --trust-server-cert init file://svnroot/
            svn://svn.freebsd.org/base

 2) Create a suitable P4 client.  You can find more info about the
    requirements by reading the p4convert-svn readme file here:

    ftp://ftp.perforce.com/private/tools/p4convert/p4convert-svn-README.txt

    Here's my current client which places all FreeBSD data under
    //depot/vendor/FreeBSD:

    Client: justing-svnconvert

    Update: 2010/05/04 08:11:52

    Access: 2010/05/21 16:29:35

    Owner:  justing

    Description:
            Client workspace for SVN -> P4 imports of the FreeBSD
            SVN repostory.

    Root:   /vmpool/FreeBSD-importer/perforce

    Options:        allwrite noclobber nocompress unlocked nomodtime rmdir

    SubmitOptions:  submitunchanged

    LineEnd:        local

    View:
            //depot/vendor/FreeBSD/... //justing-svnconvert/svn/...

