Changeset 340
- Timestamp:
- 04/29/2008 10:53:04 PM
- Files:
-
- trunk/script/Vss2Svn/ActionHandler.pm (modified) (13 diffs)
- trunk/script/Vss2Svn/Dumpfile.pm (modified) (2 diffs)
- trunk/script/vss2svn.pl (modified) (39 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/script/Vss2Svn/ActionHandler.pm
r319 r340 114 114 if (!defined $version ) { 115 115 $self->{errmsg} .= "Attempt to add entry '$row->{physname}' with " 116 . "unknown version number (probably destroyed) \n";116 . "unknown version number (probably destroyed) parent: $row->{parentphys} itemtype: $row->{itemtype}\n"; 117 117 118 118 $gOrphanedInfo {$row->{physname} } = 1; … … 264 264 my $itempath = $parentpath . $row->{itemname}; 265 265 266 # a SHARE *can* rename a file if the parent is no longer present. 267 $row->{info} = $row->{itemname}; 268 $self->_rename_handler(); 269 266 270 # 'sourceinfo' contains the source path 267 271 my $sourceinfo = $self->_get_valid_path ($physname, $row->{parentphys}, $version); … … 273 277 274 278 $self->{action} = 'ADD'; 275 # $self->{version} = $version; 276 # return $self->_add_handler(); 277 } 278 279 # if this is a share from orphan, and not a share+pin action either, we can treat it as a move 280 elsif (!defined $row->{version} && # share+pin? 281 defined $physinfo->{orphaned} # orphaned? 282 # scalar @{$physinfo->{order}} == 1 # only one parent? 283 ) { 284 $physinfo->{parents}->{'_' . $row->{physname}}->{deleted} = 1; 285 undef $physinfo->{orphaned}; 286 $self->{action} = 'MOVE'; 287 } 288 279 } 280 289 281 # track the addition of the new parent 290 282 $self->_add_parent ($physname, $row->{parentphys}); … … 330 322 } 331 323 332 # # First delete this parentphys from the old shared object; see333 # # _delete_handler for details334 # if ($oldphysinfo->{parentphys} eq $row->{parentphys}) {335 # $oldphysinfo->{parentphys} = shift( @{ $oldphysinfo->{sharedphys} } );336 # } else {337 # my $sharedphys = [];338 #339 # foreach my $oldparent (@{ $oldphysinfo->{sharedphys} }) {340 # push @$sharedphys, $oldparent341 # unless $oldparent eq $row->{parentphys};342 # }343 #344 # $oldphysinfo->{sharedphys} = $sharedphys;345 # }346 347 324 my $version = defined $row->{version} ? $row->{version} 348 325 : $self->{version}; … … 389 366 return $result; 390 367 391 392 # # Now create a new entry for this branched item393 # $gPhysInfo{$physname} =394 # {395 # type => $row->{itemtype},396 # name => $row->{itemname},397 ## parentphys => $row->{parentphys},398 ## sharedphys => [],399 # parents => {},400 # };401 402 # $self->_add_parent ($physname, $row->{parentphys});403 # $self->{itempaths} = $self->_get_current_item_paths(1);404 405 # return 1;406 407 368 } # End _branch_handler 408 369 … … 411 372 ############################################################################### 412 373 sub _move_handler { 413 my($self ) = @_;374 my($self, $oldName) = @_; 414 375 my $row = $self->{row}; 415 376 … … 440 401 } 441 402 442 # '$sourceinfo' is the path for the old location (the move source);443 my $sourceparent = $self->_get_parent_path ($row->{info});444 my $sourceinfo = $sourceparent . $row->{itemname};445 446 447 403 # check the target path 448 404 if (!defined ($row->{parentphys})) { … … 453 409 } 454 410 411 # '$sourceinfo' is the path for the old location (the move source); 412 my $sourceparent = $self->_get_parent_path ($row->{info}); 413 my $sourceinfo; 414 if (defined $oldName) 415 { 416 $sourceinfo = $sourceparent . $oldName; 417 } 418 else 419 { 420 $sourceinfo = $sourceparent . $row->{itemname}; 421 } 422 455 423 # '$itempath' contains the move target path 456 424 my $parentpath = $self->_get_current_parent_path (); … … 495 463 $self->{action} = 'MOVE'; 496 464 $row->{actiontype} = 'MOVE'; 497 $row->{info} = $row->{parentphys}; 498 $row->{parentphys} = '_' . $row->{physname}; 499 return $self->_move_handler (); 465 # $row->{info} = $row->{parentphys}; 466 # $row->{parentphys} = '_' . $row->{physname}; 467 468 $gPhysInfo{ $row->{physname} } = 469 { 470 type => $row->{itemtype}, 471 name => $row->{itemname}, 472 parents => {}, 473 first_version => 1, 474 last_version => 1, 475 orphaned => 1, 476 was_binary => $row->{is_binary}, 477 }; 478 479 my $newName = $row->{info}; 480 481 undef $row->{info}; 482 483 return $self->_move_handler ($newName); 500 484 } 501 485 … … 524 508 my $itempaths = [$parentpath . $physinfo->{name}]; 525 509 526 # if ($physinfo->{parentphys} eq $row->{parentphys}) {527 # # Deleting from the "main" parent; find a new one by shifting off the528 # # first shared path, if any; if none exists this will leave a null529 # # parent entry. We could probably just delete the whole node at this530 # # point.531 #532 # $physinfo->{parentphys} = shift( @{ $physinfo->{sharedphys} } );533 #534 # } else {535 # my $sharedphys = [];536 #537 # foreach my $parent (@{ $physinfo->{sharedphys} }) {538 # push @$sharedphys, $parent539 # unless $parent eq $row->{parentphys};540 # }541 #542 # $physinfo->{sharedphys} = $sharedphys;543 # }544 545 510 # protect for delete/purge cycles: if the parentphys isn't in the shares 546 511 # anymore, the file was already deleted from the parent and is now purged … … 577 542 return 0; 578 543 } 579 580 # if (defined $physinfo->{parentphys}) {581 # # Item still has other shares, so recover it by pushing this parent582 # # onto its shared list583 #584 # push( @{ $physinfo->{sharedphys} }, $row->{parentphys} );585 #586 # } else {587 # # Recovering its only location; set the main parent back to this588 # $physinfo->{parentphys} = $row->{parentphys};589 # }590 544 591 545 # recover this item within the current parent … … 896 850 $self->{physname_seen} .= "$physname, "; 897 851 898 # my @pathstoget =899 # ($physinfo->{parentphys}, @{ $physinfo->{sharedphys} } );900 852 my @pathstoget = @parents; 901 853 902 854 my $paths; 903 855 my $result; 904 # if (defined $physinfo->{parents}->{$row->{parentphys}}->{deleted}) {905 # return 0;906 # }907 856 908 857 PARENT: … … 964 913 $self->_track_item_path ($row->{physname}, $parent, $row->{version}, $result); 965 914 966 # my $versions = \@{$physinfo->{parents}->{$parent}->{versions}};967 #968 # # in the case of pinning and sharing with pinning, the version number969 # # denotes a version in the past. So if there is already an entry for970 # # this version number skip this parent.971 # if (exists $versions->[$row->{version}]) {972 # next PARENT;973 # }974 975 # # remember the last version, in which the file was modified976 # $physinfo->{last_version} = $row->{version};977 978 # $result = $self->_get_parent_path ($parent) . $physinfo->{name};979 980 # if(!defined($result)) {981 # next PARENT;982 # }983 984 # $versions->[$row->{version}] = $result;985 915 } 986 916 } trunk/script/Vss2Svn/Dumpfile.pm
r336 r340 206 206 } 207 207 else { 208 $self->add_error("Attempt to re-add directory '$itempath' at " 209 . "revision $data->{revision_id}, skipping action: possibly " 210 . "missing delete"); 208 #creating a new VSS database can cause a "ADD" for a "/" item which will fail. 209 if (!($itempath eq "/")) { 210 $self->add_error("Attempt to re-add directory '$itempath' at " 211 . "revision $data->{revision_id}, skipping action: possibly " 212 . "missing delete"); 213 } 214 211 215 return 0; 212 216 } … … 220 224 } 221 225 elsif ($success == 0) { 222 $self->add_error("Parent path missing while trying to add " 223 . "item '$itempath' at revision $data->{revision_id}: adding missing " 224 . "parents"); 226 if (!($itempath =~ m/^\/orphaned\/_.*/)) 227 { 228 $self->add_error("Parent path missing while trying to add " 229 . "item '$itempath' at revision $data->{revision_id}: adding missing " 230 . "parents"); 231 } 225 232 $self->_create_svn_path ($nodes, $itempath); 226 233 } trunk/script/vss2svn.pl
r338 r340 69 69 next => 'MERGEMOVEDATA'}, 70 70 71 # Merge data from move actions 71 # Merge data from move actions 72 72 MERGEMOVEDATA => {handler => \&MergeMoveData, 73 73 next => 'REMOVETMPCHECKIN'}, … … 253 253 254 254 if (!defined $filesegment[0] || !defined $filesegment[1] 255 || !defined $filesegment[2]) {255 || !defined $filesegment[2]) { 256 256 # physical file doesn't exist; it must have been destroyed later 257 257 &ThrowWarning("Can't retrieve info from physical file " … … 310 310 $tphysname, $itemname, $itemtype, $parent, $user, $timestamp, $comment, 311 311 $is_binary, $info, $priority, $sortkey, $label, $cachename); 312 312 313 313 my $last_timestamp = 0; 314 314 315 315 VERSION: 316 316 foreach $version (@{ $xml->{Version} }) { … … 342 342 } 343 343 $last_timestamp = $timestamp; 344 344 345 345 $itemtype = $info->{type}; 346 346 $actiontype = $info->{action}; … … 356 356 $priority = 5; 357 357 $label = undef; 358 358 359 359 if ($version->{Comment} && !ref($version->{Comment})) { 360 360 $comment = $version->{Comment} || undef; … … 380 380 $comment .= "\n"; 381 381 } 382 382 383 383 $comment .= $action->{LabelComment} || undef; 384 384 } … … 439 439 } elsif ($actiontype eq 'BRANCH') { 440 440 $info = $action->{Parent}; 441 } 441 } 442 442 443 443 $vernum = ($parentdata)? undef : $version->{VersionNumber}; … … 474 474 && $actiontype ne 'LABEL') { 475 475 my ($labelComment); 476 476 477 477 if ($version->{LabelComment} && !ref($version->{LabelComment})) { 478 478 $labelComment = $version->{LabelComment}; … … 590 590 # Get the row(s) corresponding to the parent(s) of this row, and work out 591 591 # the maximum depth 592 592 593 593 my $sql = <<"EOSQL"; 594 594 SELECT … … 657 657 $parentdata = 0 unless defined $parentdata; 658 658 $parentdata = 1 if $parentdata != 0; 659 659 660 660 my $sql = <<"EOSQL"; 661 661 SELECT … … 723 723 724 724 my($sth, $rows, $row); 725 725 726 $sth = $gCfg{dbh}->prepare('SELECT * FROM PhysicalAction ' 726 727 . 'WHERE actiontype = "MOVE_FROM"'); … … 739 740 my $target = $row->{parentphys}; 740 741 741 if (scalar @$childrecs > 1) { 742 &ThrowWarning("Multiple child recs for parent MOVE rec " 743 . "'$row->{action_id}'"); 744 } 745 746 if (scalar @$childrecs >= 1) { 747 # only merge MOVE records that have the same timestamp 748 if ($row->{timestamp} == @$childrecs[0]->{timestamp}) { 749 $source = @$childrecs[0]->{parentphys}; 750 &DeleteChildRec(@$childrecs[0]->{action_id}); 742 my $chosenChildRecord; 743 my $childRecord; 744 745 foreach $childRecord (@$childrecs) { 746 if (!(defined $chosenChildRecord) 747 && $childRecord->{timestamp} == $row->{timestamp} 748 && !($childRecord->{parentphys} eq $row->{parentphys})) { 749 750 $chosenChildRecord = $childRecord; 751 751 } 752 752 } 753 754 my $sql = <<"EOSQL"; 753 754 if (defined $chosenChildRecord) { 755 $source = $chosenChildRecord->{parentphys}; 756 &DeleteChildRec($chosenChildRecord->{action_id}); 757 758 my $sql = <<"EOSQL"; 755 759 UPDATE 756 760 PhysicalAction … … 762 766 action_id = ? 763 767 EOSQL 764 my $update; 765 $update = $gCfg{dbh}->prepare($sql); 766 767 $update->execute( $target, $source, $row->{action_id}); 768 my $update; 769 $update = $gCfg{dbh}->prepare($sql); 770 771 $update->execute( $target, $source, $row->{action_id}); 772 } else { 773 #the record did not have a matching MOVE_TO. call it a RESTORE 774 print "Changing $row->{action_id} to a RESTORE\n"; 775 776 my $sql = <<"EOSQL"; 777 UPDATE 778 PhysicalAction 779 SET 780 actiontype = 'RESTORE' 781 WHERE 782 action_id = ? 783 EOSQL 784 my $update; 785 $update = $gCfg{dbh}->prepare($sql); 786 787 $update->execute( $row->{action_id}); 788 } 768 789 } 769 790 … … 785 806 } 786 807 808 $sth = $gCfg{dbh}->prepare('SELECT * FROM PhysicalAction WHERE actiontype = "RESTORE"'); 809 $sth->execute(); 810 $rows = $sth->fetchall_arrayref( {} ); 811 812 foreach $row (@$rows) { 813 #calculate last name of this file. Store it in $info 814 815 my $sql = "SELECT * FROM PhysicalAction WHERE physname = ? AND timestamp < ? ORDER BY timestamp DESC"; 816 817 $sth = $gCfg{dbh}->prepare($sql); 818 $sth->execute( $row->{physname}, $row->{timestamp} ); 819 820 my $myOlderRecords = $sth->fetchall_arrayref( {} ); 821 822 if (scalar @$myOlderRecords > 0) { 823 my $update = $gCfg{dbh}->prepare('UPDATE PhysicalAction SET info = ? WHERE action_id = ?'); 824 $update->execute(@$myOlderRecords[0]->{itemname}, $row->{action_id}); 825 } 826 } 787 827 788 828 1; … … 807 847 foreach $row (@$rows) { 808 848 my $physname = $row->{physname}; 809 849 810 850 my $sql = 'SELECT * FROM PhysicalAction WHERE physname = ?'; 811 851 my $update = $gCfg{dbh}->prepare($sql); 812 852 813 853 $update->execute( $physname ); 814 854 815 # need to pull in all recs at once, since we'll be updating/deleting data816 my $recs = $update->fetchall_arrayref( {} );817 818 foreach my $rec (@$recs) {819 print "Remove action_id $rec->{action_id}, $rec->{physname}, $rec->{actiontype}, $rec->{itemname}\n";820 print " $rec->{comment}\n" if defined ($rec->{comment});821 &DeleteChildRec($rec->{action_id});822 } 823 }855 # need to pull in all recs at once, since we'll be updating/deleting data 856 my $recs = $update->fetchall_arrayref( {} ); 857 858 foreach my $rec (@$recs) { 859 print "Remove action_id $rec->{action_id}, $rec->{physname}, $rec->{actiontype}, $rec->{itemname}\n"; 860 print " $rec->{comment}\n" if defined ($rec->{comment}); 861 &DeleteChildRec($rec->{action_id}); 862 } 863 } 824 864 825 865 1; … … 835 875 $sth = $gCfg{dbh}->prepare($sql); 836 876 $sth->execute(); 837 877 838 878 # need to pull in all recs at once, since we'll be updating/deleting data 839 879 $rows = $sth->fetchall_arrayref( {} ); 840 880 841 881 return if ($rows == -1); 842 882 return if (@$rows < 2); 843 883 844 884 my @delchild = (); 845 885 846 886 for $r (0 .. @$rows-2) { 847 887 $row = $rows->[$r]; 848 888 849 889 if ($row->{actiontype} eq 'PIN' && !defined $row->{version}) # UNPIN 850 { 890 { 851 891 # Search for a matching pin action 852 892 my $u; … … 854 894 $next_row = $rows->[$u]; 855 895 856 if ( $next_row->{actiontype} eq 'PIN' 896 if ( $next_row->{actiontype} eq 'PIN' 857 897 && defined $next_row->{version} # PIN 858 898 && $row->{physname} eq $next_row->{physname} … … 863 903 print "found UNPIN/PIN combination for $row->{parentphys}/$row->{physname}" 864 904 . "($row->{itemname}) @ ID $row->{action_id}\n" if $gCfg{verbose}; 865 905 866 906 # if we have a unpinFromVersion number copy this one to the PIN handler 867 907 if (defined $row->{info}) … … 871 911 $sth2->execute($row->{info}, $next_row->{action_id}); 872 912 } 873 913 874 914 push (@delchild, $row->{action_id}); 875 915 } … … 880 920 } 881 921 } 882 922 883 923 my $id; 884 924 foreach $id (@delchild) { 885 925 &DeleteChildRec($id); 886 926 } 887 927 888 928 1; 889 929 890 930 } # End MergeUnpinPinData 891 931 … … 898 938 $sth = $gCfg{dbh}->prepare($sql); 899 939 $sth->execute(); 900 940 901 941 # need to pull in all recs at once, since we'll be updating/deleting data 902 942 $rows = $sth->fetchall_arrayref( {} ); 903 943 904 944 foreach $row (@$rows) { 905 945 … … 912 952 # UNPIN/PIN with unknown UNPIN version: we are lost in this case and we 913 953 # can not distinguish this case from the PIN only case. 914 954 915 955 my $sql2; 916 956 my $prefix; … … 928 968 $prefix = "reverted changes for: \n"; 929 969 } 930 970 931 971 # UNPIN only 932 972 if ( !defined $row->{version} # no PIN version number … … 941 981 } 942 982 943 # UNPIN/PIN 983 # UNPIN/PIN 944 984 if ( defined $row->{version} # PIN version number 945 985 && defined $row->{info}) { # UNPIN version number … … 951 991 . ' AND version<=' . $row->{version} 952 992 . ' ORDER BY version '; 953 993 954 994 if ($row->{info} > $row->{version}) { 955 995 $sql2 .= "DESC"; … … 963 1003 964 1004 next if !defined $sql2; 965 1005 966 1006 my $sth2 = $gCfg{dbh}->prepare($sql2); 967 1007 $sth2->execute(); 968 1008 969 1009 my $comments = $sth2->fetchall_arrayref( {} ); 970 my $comment; 1010 my $comment; 971 1011 print "merging comments for $row->{physname}" if $gCfg{verbose}; 972 1012 print " from $row->{info}" if ($gCfg{verbose} && defined $row->{info}); 973 1013 print " to $row->{version}" if ($gCfg{verbose} && defined $row->{version}); 974 1014 print "\n" if $gCfg{verbose}; 975 1015 976 1016 foreach my $c(@$comments) { 977 1017 print " $c->{version}: $c->{comment}\n" if $gCfg{verbose}; … … 980 1020 $comment =~ s/\n+$//; 981 1021 } 982 1022 983 1023 if (defined $comment && !defined $row->{comment}) { 984 1024 $comment = $prefix . $comment if defined $prefix; … … 990 1030 } 991 1031 1; 992 1032 993 1033 } # End BuildComments 994 1034 … … 1095 1135 # prematurally call the next row. Otherwise, we get an empty revision. 1096 1136 $svnrevs->check($row); 1097 1137 1098 1138 # May contain add'l info for the action depending on type: 1099 1139 # RENAME: the new name (without path) 1100 1140 # SHARE: the source path which was shared 1101 1141 # MOVE: the old path 1102 # PIN: the path of the version that was pinned 1142 # PIN: the path of the version that was pinned 1103 1143 # LABEL: the name of the label 1104 1144 $row->{info} = $handler->{info}; … … 1108 1148 $row->{version} = $handler->{version}; 1109 1149 } 1110 1150 1111 1151 $allitempaths = join("\t", @$itempaths); 1112 1152 $row->{itempaths} = $allitempaths; … … 1115 1155 itemtype is_binary info) }); 1116 1156 $joincache->add( $svnrevs->{revnum}, $vsscache->{pkey} ); 1117 1157 1118 1158 if (defined $row->{label}) { 1119 1159 $labelcache->add(@$row{ qw(physname version label itempaths) }); … … 1126 1166 $joincache->commit(); 1127 1167 $labelcache->commit(); 1128 1168 1129 1169 } # End BuildVssActionHistory 1130 1170 … … 1199 1239 || $action->{action} eq 'COMMIT')) { 1200 1240 &ThrowWarning("'$physname': no version specified for retrieval"); 1201 1241 1202 1242 # fall through and try with version 1. 1203 1243 $version = 1; 1204 1244 } 1205 1245 1206 1246 if ($itemtype == 2 && defined $version) { 1207 1247 $exported{$physname} = &ExportVssPhysFile($physname, $version); … … 1495 1535 # Build numbers look like: 1496 1536 # a.) ssphys 0.20.0, Build 123 1497 # b.) ssphys 0.20.0, Build 123:150 1537 # b.) ssphys 0.20.0, Build 123:150 1498 1538 # c.) ssphys 0.20.0, Build 123:150 (locally modified) 1499 $out =~ m/^ssphys (.*?), Build (.*?)[ \n]/m; 1539 $out =~ m/^ssphys (.*?), Build (.*?)[ \n]/m; 1500 1540 1501 1541 # turn it into … … 1701 1741 RecoveredFile => {type => 2, action => 'RECOVER'}, 1702 1742 ArchiveVersionsofFile => {type => 2, action => 'ADD'}, 1703 ArchiveVersionsofProject => {type => 1, action => 'ADD'},1743 ArchiveVersionsofProject => {type => 1, action => 'ADD'}, 1704 1744 ArchiveFile => {type => 2, action => 'DELETE'}, 1705 1745 RestoredFile => {type => 2, action => 'RESTORE'}, … … 1934 1974 sub Initialize { 1935 1975 $| = 1; 1936 1976 1937 1977 GetOptions(\%gCfg,'vssdir=s','tempdir=s','dumpfile=s','resume','verbose', 1938 1978 'debug','timing+','task=s','revtimerange=i','ssphys=s', … … 1988 2028 1989 2029 $gCfg{errortasks} = []; 1990 2030 1991 2031 { 1992 2032 no warnings 'once'; … … 2034 2074 XML::SAX->load_parsers($INC[1]); 2035 2075 } 2036 2076 2037 2077 $gCfg{xmlParser} = 'XML::SAX::Expat'; 2038 2078 $XML::SAX::ParserPackage = $gCfg{xmlParser}; … … 2107 2147 --task <task> : specify the task to resume; task is one of the following 2108 2148 INIT, LOADVSSNAMES, FINDDBFILES, GETPHYSHIST, 2109 MERGEPARENTDATA, MERGEMOVEDATA, REMOVETMPCHECKIN, 2149 MERGEPARENTDATA, MERGEMOVEDATA, REMOVETMPCHECKIN, 2110 2150 MERGEUNPINPIN, BUILDACTIONHIST, IMPORTSVN 2111 2151
