#!/usr/bin/perl -w # # VSS to Perforce converter, phase III: construct Perforce depot # # Copyright 1998 Perforce Software. All rights reserved. # Written by James Strickland, April 1998 # # This script uses the metadata produced by earlier phases to direct a loop # which extracts VSS revisions and performs the required Perforce commands # to construct a Perforce depot corresponding to the (improved) VSS data. # # RHGC - Modifed to use new depot and depot_root as specified in config. require 5.0; use strict; use integer; use lib '.'; use convert; use Change; # open all our input files my $msg="can't open for read"; open(FILES, "<$convert::metadata_dir/files") or die $msg; open(LABELS, "<$convert::metadata_dir/labels") or die $msg; open(CHANGES, "<$convert::metadata_dir/changes") or die $msg; open(MAPPING, ">$convert::metadata_dir/mapping.ns") or die "can't open for write: $!"; # variables to be initialized with metadata read from files my (%file_type, # maps archive -> file type # e.g. "$/foo" -> "text" %labels, # maps "revision archive" -> list of labels # e.g. "1 $/foo" -> "itworks","bobsyouruncle" %filesinlabel, # maps label name -> list of "file#rev" %added, # maps depot file -> true/false # e.g. "//depot/foo" -> 1 ); # initialize %file_type while(<FILES>) { chomp; my ($file_type,$file) = split(/ /,$_,2); $file_type{$file} = $file_type; } close(FILES); # initialize %label and run p4 label once for each label which is not a # "delete" label my %created; while(<LABELS>) { chomp; my ($revision,$label,$file) = split(/ /,$_,3); my $index = "$revision $file"; $labels{$index} = defined($labels{$index}) ? [ @{$labels{$index}} , $label ] : [ $label ]; my $comment = ''; $comment .= <LABELS> while ($comment !~ /\*{10}\n/); $comment =~ s/\*{10}\n$//; $comment = "vsstop4 label" if ($comment =~ /^\s*$/); # Set default comment. next if($created{$label}); my $form=convert::run("p4 label -o $label"); # label names cannot contain spaces $comment =~ s@\n@\n\t@gs; my $label_view = "//$convert::depot/$convert::depot_root/..."; # Update the Description field in the label. $form =~ s@(\nDescription:\s*)\n\s+\S[^\n]*\n@$1\n\t$comment@s; # RHGC - Create a more specific view for the label - not just all depots which is the default. $form =~ s@(\nView:\s*)\n\s+.*\n$@$1\n\t$label_view@s; convert::run("p4 label -i",$form); $created{$label}=1; } close(LABELS); undef %created; # we're finished with this hash, so free up the space # print timestamp print "Depot creation started " . scalar(localtime()) . "\n"; # For each change, # - retrieve revisions from VSS using 'get' # - mark files as added or edited with 'p4 add' or 'p4 edit', # followed by 'p4 submit' # - update list of file#rev associated with any pertinent labels my ($c,$op); while( $c = get Change(\*CHANGES) ) { my ($change_number,@checkins); my $index; foreach $index (@{$c->changelist}) { my $p4rev; my ($revision,$vss_file) = split(/ /,$index,2); my ($client_rel_dir,$client_file) = convert::p4dir_and_file( $vss_file); my $client_dir = convert::join_paths( $convert::client_root, $client_rel_dir ); # create all needed directories on the path convert::emkdir($client_dir); # for p4 - could use $client_file, but I'd rather make sure we use # the same string that's written out to the mapping file my $depot_file = convert::join_paths("//$convert::depot", $client_rel_dir, $client_file ); # get the file from VSS convert::get_vss_file($vss_file,($file_type{$vss_file} eq "tempobj") ? "" : $revision,$client_dir,$client_file); # see if the file is indeed there now if (-f "${client_dir}/${client_file}") { # schedule p4 add or edit operation # depending on whether file has already been added push(@checkins, [ $vss_file,$revision,$depot_file ] ); my $operation; if($added{$depot_file}) { convert::run("p4 edit \"$depot_file\"") =~ /#(\d+) - opened for edit/ or die "p4 edit $depot_file failed"; $p4rev=$1 +1; } else { convert::run("p4 add -t $file_type{$vss_file} \"$depot_file\"") =~ /opened for add/ or die "p4 add $depot_file failed"; $added{$depot_file}=1; $p4rev=1; } # check if this revision is labelled if(exists($labels{$index})) { for (@{$labels{$index}}) { $filesinlabel{$_} = defined($filesinlabel{$_}) ? [ @{$filesinlabel{$_}} , "$depot_file#$p4rev" ] : [ "$depot_file#$p4rev" ]; } } } else { # the file isn't there - the ss get failed if ($convert::skip_ss_get_errors) { print STDERR "ERROR: VSS file not found: ${vss_file}#${revision}\n"; } else { die "get_vss_file() revision $revision to $client_dir/$client_file failed"; } } } # submit the change, and write out the association between VSS # archive and revision number and Perforce file and change number $change_number = $c->submit; # submit the change my $checkin; foreach $checkin (@checkins) { my ($vss_file,$r,$depot_filename) = @$checkin; # write change number#filename to avoid confusion with filename#revision print MAPPING "$r#$change_number#$depot_filename#$vss_file\n"; # NOTE: $vss_file has to go last since it can contain # characters } } # now do the labelling for (keys(%filesinlabel)) { convert::run("p4 -x - labelsync -l $_",join("\n",@{$filesinlabel{$_}})."\n"); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#14 | 3607 | Robert Cowham |
Put use of DB_File inside eval so it doesn't matter if not installed. Updated README for Performance Tips. |
||
#13 | 3604 | Robert Cowham |
Added VSS OLE Automation back in but as a configurable option. Tidied up logging. |
||
#12 | 3603 | Robert Cowham | Added back VSS OLE Automation with check for if not installed. | ||
#11 | 3601 | Robert Cowham | Use P4Perl interface if installed. | ||
#10 | 3593 | Robert Cowham | Shifted 2 more hashes into DB files. | ||
#9 | 3592 | Robert Cowham | Back out previous change as it is slower (but leave for posterity)... | ||
#8 | 3591 | Robert Cowham |
Example using VSS OLE Automation to get versions. Unfortunately this seems slower than spawning ss.exe from command line - go figure.... |
||
#7 | 3590 | Robert Cowham | Use DB_File to store label info rather than large hashes in memory. | ||
#6 | 3589 | Robert Cowham | Merge in changes from Main branch. | ||
#5 | 2046 | Robert Cowham |
Add logging of a couple of extra things. Fix problem with spaces in author names. |
||
#4 | 1702 | Robert Cowham |
Extra check re adding new files or editing existing ones. Also prompt for confirmation if start_time specified. |
||
#3 | 1695 | Robert Cowham | Integrated Peter's changes in - note not fully tested... | ||
#2 | 1691 | Robert Cowham |
Latest changes, e.g. - allow restarts (from date and time) - add client name to config options |
||
#1 | 237 | Robert Cowham |
Improved version of vsstop4. Makes life easier if importing into a depot which already contains stuff you want to keep. Also handles other people updating the depot at the same time. See changes labelled RHGC, and new items in config file. |