Author image Barrie Slaymaker


VCP::Dest - A base class for VCP destinations





Creates an instance, see subclasses for options. The options passed are usually native command-line options for the underlying repository's client. These are usually parsed and, perhaps, checked for validity by calling the underlying command line.


This class uses the fields pragma, so you'll need to use base and possibly fields in any subclasses.


These methods are intended to support subclasses.

    $self->digest( "/tmp/readers" ) ;

Returns the Base64 MD5 digest of the named file. Used to compare a base rev (which is the revision *before* the first one we want to transfer) of a file from the source repo to the existing head rev of a dest repo.

The Base64 version is returned because that's what RevML uses and we might want to cross-check with a .revml file when debugging.

   $self->compare_base_revs( $rev ) ;

Checks out the indicated revision fromt the destination repository and compares it (using digest()) to the file from the source repository (as indicated by $rev->work_path). Dies with an error message if the base revisions do not match.

Calls $self->checkout_file( $rev ), which the subclass must implement.

Gets/sets the $header passed to handle_header().

Generally not overridden: all error checking is done in new(), and no output should be generated until output() is called.


These methods are overloaded by subclasses.

   $dest->backfill( $rev ) ;

Checks the file indicated by VCP::Rev $rev out of the target repository if this destination supports backfilling. Currently, only the revml destination does not support backfilling.

The $rev->{workpath} must be set to the filename the backfill was put in.

This is used when doing an incremental update, where the first revision of a file in the update is encoded as a delta from the prior version. A digest of the prior version is sent along before the first version delta to verify it's presence in the database.

So, the source calls backfill(), which returns TRUE on success, FALSE if the destination doesn't support backfilling, and dies if there's an error in procuring the right revision.

If FALSE is returned, then the revisions will be sent through with no working path, but will have a delta record.


   $dest->handle_footer( $footer ) ;

Does any cleanup necessary. Not required. Don't call this from the override.

   $dest->handle_header( $header ) ;

Stows $header in $self->header. This should only rarely be overridden, since the first call to handle_rev() should output any header info.

   $dest->handle_rev( $rev ) ;

Outputs the item referred to by VCP::Rev $rev. If this is the first call, then $self->none_seen will be TRUE and any preamble should be emitted.

MUST BE OVERRIDDEN. Don't call this from the override.


   $dest->set_sort_spec( @key_names ) ;

@key_names specifies the list of fields to sort by. Each element in the array may be a comma separated list. Such elements are treated as though each name was passed in it's own element; so ( "a", "b,c" ) is equivalent to ("a", "b", "c"). This eases command line parameter parsing.

Sets the sort specification, checking to make sure that the field_names have corresponding parse_sort_field_... handlers in this object.

Legal field names include: name, change, change_id, rev, rev_id, comment, time.

If a field is not present in a rev, it is treated as being less than "".

Default ordering is by

  - change_id    (compared numerically using <=>, for now)
  - time         (commit time: simple numeric, since this is a simple number)
  - comment      (alphabetically, case sensitive)

This ordering benefits change number oriented systems while preserving commit order for non-change number oriented systems.

If change_id is undefined in either rev, it is not used.

If time is undefined in a rev, the value "-1" is used. This causes base revisions (ie digest-only) to precede real revisions.

That's not always good, though: one of commit time or change number should be defined!

Change ids are compared numerically, times by date order (ie numerically, since time-since-the-epoch is used internally). Comments are compared alphabetically.

Each sort field is split in to one or more segments, see the appropriate parse_sort_field_... documentation.

Here's the sorting rules: - Revisions are compared field by field. - The first non-equal field determines sort order. - Fields are compared segment by segment. - The first non-equal segment determines sort order. - A not-present segment compares as less-than any other segment, so fields that are leading substrings of longer fields come first, and not-present fields come before all present fields, including empty fields.

    push @sort_key_segs, $self->parse_sort_field_name( $rev ) ;

Splits the name of the revision in to segments suitable for sorting.

parse_sort_field_rev =item parse_sort_field_rev_id =item parse_sort_field_revision =item parse_sort_field_revision_id =item parse_sort_field_change =item parse_sort_field_change_id
    push @sort_key_segs, $self->parse_sort_field_name( $rev ) ;

These split the change_id or rev_id of the revision in to segments suitable for sorting. Several spellings of each method are provided for user convenience; all spellings for each field work the same way. This is because users may think of different names for each field depending on how much RevML they know (the _id variants come from RevML), or whether they like to spell "revision" or "rev".

The splits occur at the following points:

   1. Before and after each substring of consecutive digits
   2. Before and after each substring of consecutive letters
   3. Before and after each non-alpha-numeric character

The substrings are greedy: each is as long as possible and non-alphanumeric characters are discarded. So "11..22aa33" is split in to 5 segments: ( 11, "", 22, "aa", 33 ).

If a segment is numeric, it is left padded with 50 NUL characters.

This algorithm makes 1.52 be treated like revision 1, minor revision 52, not like a floating point 1.52. So the following sort order is maintained:


The substring "pre" might be treated specially at some point.

(At least) the following cases are not handled by this algorithm:

   1. floating point rev_ids: 1.0, 1.1, 1.11, 1.12, 1.2
   2. letters as "prereleases": 1.0a, 1.0b, 1.0, 1.1a, 1.1

Never returns (), since rev_id is a required field.


Pads and returns the seconds-since-epoch value that is the time.


Just returns the comment.

   $source->dest->sort_revs( $source->revs ) ;

This sorts the revisions that the source has identified in to whatever order is needed by the destination. The default ordering is set by "rev_cmp_sub".


Copyright 2000, Perforce Software, Inc. All Rights Reserved.

This module and the VCP package are licensed according to the terms given in the file LICENSE accompanying this distribution, a copy of which is included in vcp.


Barrie Slaymaker <>

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 64:

You forgot a '=back' before '=head1'

Around line 241:

You forgot a '=back' before '=head3'

Around line 546:

=back without =over