#!/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,$timestamp,$file) = split(/ /,$_,4); 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; # adjust the update time of the label my (@tm,$date); @tm=localtime($timestamp); $date=sprintf("%4d/%02d/%02d %02d:%02d:%02d",(($tm[5]>=70) ? $tm[5]+1900 : $tm[5]+2000), $tm[4]+1,$tm[3],$tm[2],$tm[1],$tm[0]); if ($form =~ /(\nUpdate:\s*)\d.*$/) { $form =~ s@(\nUpdate:\s*)\d.*$@$1$date@s; } else { $form =~ s@(\nLabel:.*?\n)@$1\nUpdate: $date\n@s; } convert::run("p4 label -i -f",$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 { my $addcmd = "p4 add -t $file_type{$vss_file} \"$depot_file\""; if ($convert::typemap_regexp) { # don't specify type when file is handled with p4 typemap if ($depot_file =~ /$convert::typemap_regexp/) { $addcmd = "p4 add \"$depot_file\""; } else { print "file $depot_file not matched by typemap.\n"; } } convert::run($addcmd) =~ /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 print "\nLabelling started " . scalar(localtime()) . "\n"; for (keys(%filesinlabel)) { convert::run("p4 -x - labelsync -l $_",join("\n",@{$filesinlabel{$_}})."\n"); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 1513 | Peter Steiner |
- writing to the logfile in verify.pl didn't work - convert.pm: get_vss_file failed sometimes (when there was a file in the working directory with the same name as one in the VSS archive) - the timestamp of a label is now set from the VSS label timestamp - files can be added using perforce typemaps for determining the file type (though this is disabled because it is likely to break verify.pl when the revisions are compared using different keyword expansion methods...). See convert::typemap_regexp - new option lowercase_extensions (similar to lowercase_filenames) - option convert::perform_verify (no more need to press a key during nightly conversion tests) - label name transformations to cope better with special character restrictions. You probably want to adjust for your own purposes; see readhist.pl line 169ff. - output of convert.pl adorned with timestamps - changes for Swiss time format are prepared (in the comments of readhist.pl), though this probably should be done with specifying a regexp in the config file - various fixes when using german umlauts, especially in Windows login names propagated to VSS, in labels and comments |
||
#1 | 1510 | Peter Steiner | integrated from Roberts vsstop4 branch | ||
//guest/robert_cowham/perforce/utils/vsstop4/mkdepot.pl | |||||
#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. |