package VCP::Revs ; =head1 NAME VCP::Revs - A collection of VCP::Rev objects. =head1 SYNOPSIS =head1 DESCRIPTION Right now, all revs are kept in memory, but we will enable storing them to disk and recovering them at some point so that we don't gobble huge tracts of RAM. =head1 METHODS =over =cut $VERSION = 1 ; use strict ; use VCP::Logger qw( BUG ); use VCP::Debug ":debug" ; use VCP::Rev ; use fields ( 'REVS', ## The revs, sorted or not 'BY_ID', ## A HASH of revisions, indexed by ID 'BY_NAME_BRANCH_ID', ## A HASH of revisions, indexed by name and branch_id ) ; =item new =cut sub new { my $class = CORE::shift ; $class = ref $class || $class ; my $self ; { no strict 'refs' ; $self = bless [ \%{"$class\::FIELDS"} ], $class ; } $self->{REVS} = [] ; $self->{BY_ID} = {} ; return $self ; } =item add $revs->add( $rev ) ; $revs->add( $rev1, $rev2, ... ) ; Adds a revision or revisions to the collection. The ( name, rev_id, branch_id ) tuple must be unique, if a second rev is C<add()>ed with the same values, an exception is thrown. =cut sub add { my VCP::Revs $self = CORE::shift ; Carp::confess "undef passed" if grep ! defined, @_; if ( debugging ) { debug "queuing ", $_->as_string for @_ ; } for my $r ( @_ ) { my $id = $r->id; ## CVS seems to allow multiple branch tags per branch ## so we can have multiple placeholder revs with the ## same name and rev_id. Sigh. die "vcp: can't add same revision twice: '" . $r->as_string if $self->{BY_ID}->{$id} && ! $r->is_placeholder_rev; push @{$self->{REVS}}, $r ; $self->{BY_ID}->{$id} = $r ; $self->{BY_NAME_BRANCH_ID}->{$r->_name_branch_id} = $r; } } =item set $revs->set( $rev ) ; $revs->set( $rev1, $rev2, ... ) ; Sets the list of revs. =cut sub set { my VCP::Revs $self = CORE::shift ; Carp::confess "undef passed" if grep !defined, @_; if ( debugging ) { require UNIVERSAL; BUG "unblessed ref passed" if grep !UNIVERSAL::can( $_, "as_string" ), @_; debug "queuing ", $_->as_string for @_ ; } @{$self->{REVS}} = @_ ; } =item get @revs = $revs->get ; ## return a list of all revs $rev = $revs->get( $id ) ; ## return the rev with a given ID (or die()) =cut sub get { my VCP::Revs $self = CORE::shift ; return @{$self->{REVS}} unless @_; my ( $id ) = @_; Carp::confess "Could not find revision with id='$id'" unless exists $self->{BY_ID}->{$id}; return $self->{BY_ID}->{$id}; } =item get_last_added my $previous_r = $revs->get_last_added; Returns most recently added revision. my $previous_r = $revs->get_last_added( $r ); Gets the last revision of the named file on this branch. This is used because most repositories output the most recent revision first, and we need to point each revision at its preceding revision for branching and for RevML to do diffs. die()s unless a previous revision is found. =cut sub get_last_added { my VCP::Revs $self = shift; my ( $r ) = @_; return @{$self->{REVS}} ? $self->{REVS}->[-1] : undef unless $r; my $nb = $r->_name_branch_id; die "Could not find revision with name(branch_id)='$nb'\n" unless exists $self->{BY_NAME_BRANCH_ID}->{$nb}; return $self->{BY_NAME_BRANCH_ID}->{$nb}; } =item sort # Using a custom sort function: $revs->sort( sub { ... } ) ; Note: Don't use $a and $b in your sort function. They're package globals and that's not your package. See L<VCP::Dest/rev_cmp_sub> for more details. =cut sub sort { my VCP::Revs $self = CORE::shift ; my ( $sort_func ) = @_ ; @{$self->{REVS}} = sort $sort_func, @{$self->{REVS}} ; } =item remove_all Returns and removes all as an array reference. A lot faster than ->shift()ing them out. =cut sub remove_all { my VCP::Revs $self = CORE::shift ; my $revs = $self->{REVS}; $self->{REVS} = []; %{$self->{BY_ID}} = (); %{$self->{BY_NAME_BRANCH_ID}} = (); return $revs; } =item as_array_ref Returns an ARRAY ref of all revs. =cut sub as_array_ref { my VCP::Revs $self = CORE::shift ; return $self->{REVS} ; } sub set_file_fetcher { warn "file_fetcher set by " . caller } ## TODO: delete sub fetch_files { ## TODO: remove this. ## DEPRECATED. Carp::confess( "fetch_files() not called in list context" ) unless wantarray; shift; map $_->fetch_file, @_; } =back =head1 SUBCLASSING This class uses the fields pragma, so you'll need to use base and possibly fields in any subclasses. =head1 COPYRIGHT 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 L<vcp>. =head1 AUTHOR Barrie Slaymaker <barries@slaysys.com> =cut 1
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#27 | 4508 | Barrie Slaymaker | - VCP::Revs::exists() removed | ||
#26 | 4021 | Barrie Slaymaker |
- Remove all phashes and all base & fields pragmas - Work around SWASHGET error |
||
#25 | 4012 | Barrie Slaymaker | - Remove dependance on pseudohashes (deprecated Perl feature) | ||
#24 | 3970 | Barrie Slaymaker |
- VCP::Source handles rev queing, uses disk to reduce RAM - Lots of other fixes |
||
#23 | 3805 | Barrie Slaymaker | - VCP::Revs::fetch_files() removed | ||
#22 | 3804 | Barrie Slaymaker | - Refactored to prepare way for reducing memory footprint | ||
#21 | 3742 | Barrie Slaymaker |
- VCP::Source::vss correctly links the first rev of a file to the the delete action its deleted predecessor. |
||
#20 | 3155 | Barrie Slaymaker |
Convert to logging using VCP::Logger to reduce stdout/err spew. Simplify & speed up debugging quite a bit. Provide more verbose information in logs. Print to STDERR progress reports to keep users from wondering what's going on. Breaks test; halfway through upgrading run3() to an inline function for speed and for VCP specific features. |
||
#19 | 3140 | Barrie Slaymaker | Remove deprecated function | ||
#18 | 3133 | Barrie Slaymaker |
Make destinations call back to sources to check out files to simplify the architecture (is_metadata_only() no longer needed) and make it more optimizable (checkouts can be batched). |
||
#17 | 3131 | Barrie Slaymaker |
Double the speed of the RCS file parser. Deprecate VCP::Revs::shift() in favor of remove_all(). |
||
#16 | 2975 | Barrie Slaymaker |
Deal with CVS' propensity to have multiple branch tags on the same version. |
||
#15 | 2232 | Barrie Slaymaker | Major memory and sort speed enhancements. | ||
#14 | 2059 | Barrie Slaymaker | Support for branching in p4->p4 added | ||
#13 | 2026 | Barrie Slaymaker | VCP::8::cvs now supoprt branching | ||
#12 | 2017 | Barrie Slaymaker |
Interim checkin of id=/base_version_id for revml: and branch_diagram: |
||
#11 | 2015 | Barrie Slaymaker | submit changes | ||
#10 | 1855 | Barrie Slaymaker |
Major VSS checkin. Works on Win32 |
||
#9 | 1809 | Barrie Slaymaker | VCP::Patch should ignore lineends | ||
#8 | 1055 | Barrie Slaymaker |
add sorting, revamp test suite, misc cleanup. Dest/revml is not portable off my system yet (need to release ...::Diff) |
||
#7 | 687 | Barrie Slaymaker | remove -f, tweak deduce_rev_root | ||
#6 | 628 | Barrie Slaymaker | Cleaned up POD in bin/vcp, added BSD-style license. | ||
#5 | 608 | Barrie Slaymaker |
Lots of changes to get vcp to install better, now up to 0.066. Many thanks to Matthew Attaway for testing & suggestions. |
||
#4 | 480 | Barrie Slaymaker |
0.06 Wed Dec 20 23:19:15 EST 2000 - bin/vcp: Added --versions, which loads all modules and checks them for a $VERSION and print the results out. This should help with diagnosing out-of-sync modules. - Added $VERSION vars to a few modules :-). Forgot to increment any $VERSION strings. - VCP::Dest::cvs: The directory "deeply" was not being `cvs add`ed on paths like "a/deeply/nested/file", assuming "deeply" had no files in it. - VCP::Dest::revml: fixed a bug that was causing files with a lot of linefeeds to be emitted in base64 instead of deltaed. This means most text files. - Various minor cleanups of diagnostics and error messages, including exposing "Can't locate Foo.pm" when a VCP::Source or VCP::Dest module depends on a module that's not installed, as reported by Jeff Anton. |
||
#3 | 478 | Barrie Slaymaker |
0.05 Mon Dec 18 07:27:53 EST 2000 - Use `p4 labels //...@label` command as per Rober Cowham's suggestion, with the '-s' flag recommended by Christopher Siewald and Amaury.FORGEOTDARC@atsm.fr. Though it's actually something like vcp: running /usr/bin/p4 -u safari -c safari -p localhost:5666 -s files //.../NtLkly //...@compiler_a3 //.../NtLkly //...@compiler_may3 and so //on //for 50 parameters to get the speed up. I use the //.../NtLkly "file" as //a separator between the lists of files in various //revisions. Hope nobody has any files named that :-). What I should do is choose a random label that doesn't occur in the labels list, I guess. - VCP::Source::revml and VCP::Dest::revml are now binary, control code, and "hibit ASCII" (I know, that's an oxymoron) clean. The <comment>, <delta>, and <content> elements now escape anything other than tab, line feed, space, or printable chars (32 <= c <= ASCII 126) using a tag like '<char code="0x09">'. The test suite tests all this. Filenames should also be escaped this way, but I didn't get to that. - The decision whether to do deltas or encode the content in base64 is now based on how many characters would need to be escaped. - We now depend on the users' diff program to have a "-a" option to force it to diff even if the files look binary to it. I need to use Diff.pm and adapt it for use on binary data. - VCP::Dest::cvs now makes sure that no two consecutive revisions of the same file have the same mod_time. VCP::Source::p4 got so fast at pulling revisions from the repositories the test suite sets up that CVS was not noticing that files had changed. - VCP::Plugin now allows you to set a list of acceptable result codes, since we now use p4 in ways that make it return non-zero result codes. - VCP::Revs now croaks if you try to add two entries of the same VCP::Rev (ie matching filename and rev_id). - The <type> tag is now limited to "text" or "binary", and is meant to pass that level of info between foreign repositories. - The <p4_info> on each file now carries the one line p4 description of the file so that p4->p4 transferes can pick out the more detailed info. VCP::Source::p4, VCP::Dest::p4 do this. - VCP::{Source,Dest}::{p4,cvs} now set binaryness on added files properly, I think. For p4->p4, the native p4 type is preserved. For CVS sources, seeing the keyword substitution flag 'o' or 'b' implies binaryness, for p4, seeing a filetype like qr/u?x?binary/ or qr/x?tempobj/ or "resource" implies binaryness (to non-p4 destinations). NOTE: Seeing a 'o' or 'b' in a CVS source only ends up setting the 'b' option on the destination. That should be ok for most uses, but we can make it smarter for cvs->cvs transfers if need be. |
||
#2 | 468 | Barrie Slaymaker |
- VCP::Dest::p4 now does change number aggregation based on the comment field changing or whenever a new revision of a file with unsubmitted changes shows up on the input stream. Since revisions of files are normally sorted in time order, this should work in a number of cases. I'm sure we'll need to generalize it, perhaps with a time thresholding function. - t/90cvs.t now tests cvs->p4 replication. - VCP::Dest::p4 now doesn't try to `p4 submit` when no changes are pending. - VCP::Rev now prevents the same label from being applied twice to a revision. This was occuring because the "r_1"-style label that gets added to a target revision by VCP::Dest::p4 could duplicate a label "r_1" that happened to already be on a revision. - Added t/00rev.t, the beginnings of a test suite for VCP::Rev. - Tweaked bin/gentrevml to comment revisions with their change number instead of using a unique comment for every revision for non-p4 t/test-*-in-0.revml files. This was necessary to test cvs->p4 functionality. |
||
#1 | 467 | Barrie Slaymaker | Version 0.01, initial checkin in perforce public depot. |