eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' & eval 'exec perl -S $0 $argv:q' if 0; # THE PRECEEDING STUFF EXECS perl via $PATH # -*-Fundamental-*- # $Id: //guest/richard_geiger/utils/cvs2p4/bin/genchanges#10 $ # # Richard Geiger # require 5.000; #use bytes; sub report { printf "%6d %6d %6d\r", $n_changes, $n_meta_read, $n_changes_added; } sub dirname { local($dir) = @_; $dir =~ s%^$%.%; $dir = "$dir/"; if ($dir =~ m%^/[^/]*//*$%) { return "/"; } if ($dir =~ m%^.*[^/]//*[^/][^/]*//*$%) { $dir =~ s%^(.*[^/])//*[^/][^/]*//*$%$1%; { return $dir; } } return "."; } use Carp; # ...or flounder. (This will fail unless 'perl' is a perl5!) $| = 1; ($Myname = $0) =~ s%^.*/%%; $Mydir = &dirname($0); $Here = `/bin/pwd`; chop $Here; if ($Mydir ne ".") { chdir "$Mydir" || die "$Myname: can't chdir \"$Mydir\": $!"; } chdir ".." || die "$Myname: can't chdir \"..\": $!"; $Mydir = `/bin/pwd`; chop $Mydir; chdir $Here || die "$Myname: can't chdir \"$Here\": $!"; require "$Mydir/lib/util.pl"; $Usage = <<LIT; $Myname: usage: $Myname LIT sub usage { print STDERR $Usage; exit 1; } sub help { print STDERR <<LIT; $Usage $Myname is... LIT exit 1; } sub line_time { my($line) = @_; my($revkey, $time) = split(/$S/, $line); return $time; } if (! defined($WINDOW_SECS)) { $WINDOW_SECS = 15*60; } sub havewindow { if ($#Lines < 1) { return 0; } return ((&line_time($Lines[$#Lines]) - &line_time($Lines[0])) > $WINDOW_SECS); } $n_meta_read = 0; sub fillwindow { while ((! eof META) && ! &havewindow) { $l = <META>; chomp($l); $n_meta_read++; &report; my($filerev, $time, $who, $state, $line, $import_branch, $branches, $prevrev, $options) = split(/$S/, $l); my $doimportspoof = 0; if ($line =~ /(.*)\+$/) { $line = $1; $l = join("$S", ($filerev, $time, $who, $state, $line, $import_branch, $branches, $prevrev, $options)); $doimportspoof = 1; } push(@Lines, $l); # This is where we account for <import> branch revisions being implicitly # present in head until a change beyond 1.1 has been committed to $TRUNKLINE... # if ($doimportspoof) { $line = $TRUNKLINE; $branches = ""; $l = join("$S", ($filerev, $time, $who, $state, $line, $import_branch, $branches, $prevrev, $options)); push (@Lines, $l); } } } # (($l_time-$r_time) < $WINDOW_SECS) sub window_has_match { my($r) = @_; my($r_key, $r_time, $r_who, $r_state, $r_line, $r_import_branch, $r_branches, $r_prevrev, $r_options) = split(/$S/, $r); for ($i = $last_i; $i <= $#Lines; $i++) { my($l_key, $l_time, $l_who, $l_state, $l_line, $l_import_branch, $l_branches, $l_prevrev, $l_options) = split(/$S/, $Lines[$i]); my $l_file; ($l_file = $l_key) =~ s/\/[^\/]+$//; #if ($d) #{ # $t1 = (! defined $change_files{$l_file}); # $t2 = ($l_who eq $r_who); # $t3 = (($l_time-$r_time) < $WINDOW_SECS); # $t4 = &had_rev($l_file, $l_prevrev, $Lines[$i], 1); # $t5 = ($l_msg = $MSGS{$l_key}) eq ($r_msg = $MSGS{$r_key}); # #print <<EOM if $d; # if ( # ($t1) && # ($t2) && # ($t3) && # ($t4) && # ($t5) # ) #EOM #} if ( (! defined $change_files{$l_file}) && ($l_who eq $r_who) && (($l_time-$r_time) < $WINDOW_SECS) && &had_rev($l_file, $l_prevrev, $Lines[$i]) && ($l_msg = $MSGS{$l_key}) eq ($r_msg = $MSGS{$r_key}) ) { $change_files{$l_file} = 1; $last_i = $i; return splice(@Lines, $i, 1); } } return 0; } sub had_rev { my($file, $prevrev) = @_; if ($prevrev eq "-") { return 1; } my $val = defined(${$revs{$file}}{$prevrev}); if ($prevrev eq "1.1.1.1") { $val = $val || defined(${$revs{$file}}{"1.1"}) } return $val; } sub add_rev { my($file, $prevrev) = @_; ${$revs{$file}}{$prevrev} = 1; } $n_changes_added = 0; sub add_to_change { my($r) = @_; my($r_key, $r_time, $r_who, $r_state, $r_line, $r_import_branch, $r_branches, $r_prevrev, $r_options) = split(/$S/, $r); my $r_file; ($r_file = $r_key) =~ s/\/([^\/]+)$//; $r_rev = $1; #obs # # Turns out that we spoof the revision for the import branch when we # # see the 1.1 revision, so we toss the record for the 1.1.1.1 rev # # when we see it here... # # # if ($r_rev eq "1.1.1.1" && $r_line eq $r_import_branch) # { return 0; } &add_rev($r_file, $r_rev); push(@change, $r); $change_files{$r_file} = 1; $n_changes_added++; &report; return 1; } # option switch variables get defaults here... $Boolopt = 0; $Valopt = 0; while ($#ARGV >= 0) { if ($ARGV[0] eq "-boolopt") { $Boolopt = 1; shift; next; } elsif ($ARGV[0] eq "-valopt") { shift; if ($ARGV[0] < 0) { &usage; } $Valopt = $ARGV[0]; shift; next; } elsif ($ARGV[0] eq "-help") { &help; } elsif ($ARGV[0] =~ /^-/) { &usage; } if ($Args ne "") { $Args .= " "; } push(@Args, $ARGV[0]); shift; } if ($#Args ne 0) { &usage; } $Convdir = $Args[0]; $Metadata = "$Convdir/metadata"; $Logmsgs = "$Convdir/logmsgs"; $Changes = "$Convdir/changes"; require "$Convdir/config"; if (! open(META, "<$Metadata")) { print "$Myname: can't open \"$Metadata\": $!\n"; exit 1; } if (! open(CHGS, ">$Changes")) { print "$Myname: can't create \"$Changes\": $!\n"; exit 1; } use DB_File; $DBMCLASS="DB_File"; #$myhashinfo = new DB_File::HASHINFO; #$myhashinfo->{bsize}=4096; $myhashinfo = new DB_File::BTREEINFO; if (! tie(%MSGS, $DBMCLASS, $Logmsgs, O_RDONLY, 0444, $myhashinfo)) { print "$Myname: can't tie \"$Logmsgs\": $!\n"; exit 1; } #chdir $CVS_MODULE || die "$Myname: can't chdir \"$CVS_MODULE\": $!"; #$CVS_MODULE = `/bin/pwd`; chop $CVS_MODULE; #chdir $Here || die "$Myname: can't chdir \"$Here\": $!"; $n_changes = 1; while (1) { &fillwindow; undef @change; undef %change_files; &add_to_change(shift @Lines); $last_i = 0; while ($matchrev = &window_has_match($change[$#change])) { &add_to_change($matchrev); &fillwindow; } print CHGS "# $n_changes\n"; $n_changes++; while ($#change >= 0) { my $l = shift @change; print CHGS $l."\n"; } &report; if (eof META && $#Lines < 0) { last; } } print STDERR "\n"; untie %MSGS; close META; exit 0;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#10 | 5531 | Richard Geiger |
A significant checkpoint commit, with new improved handling of import vendor branches, and revisions present in main by virtue of multiple vendor drops to a file with no local mods. test/runtest works, with new refernece results pretty well scrutinized. |
||
#9 | 5442 | Richard Geiger |
A checkpoint commit on the way to a 2.6.0 release with the new IronPort inspired improvements. |
||
#8 | 5430 | Richard Geiger |
This is another "checkpoint" commit. It significantly rearranges how labels are done, so as to use a hueristic to divine label<->branch identifications. Not intended for release without further testing and tweakage! |
||
#7 | 3708 | Richard Geiger | Changes for 2.3.6 | ||
#6 | 2061 | Richard Geiger |
changes for 2.3.2: - can adjust db hash bucket size; - Add $DEPOT config variable - Handle labels with '#' or '@' |
||
#5 | 1987 | Richard Geiger | Changes for 2.3.1 | ||
#4 | 416 | Richard Geiger | Pull in Thomas Quinot <quinot@inf.enst.fr>'s UTC bugfix, for 1.2.12. | ||
#3 | 249 | Richard Geiger |
Changes in preparation for supporting spaces in filenames. (In fact, this may work as of this change, but is not yet tested.) Also, add "runtest -gengood" to allow easier generatino of new *.good files. (It just doesn't quick on a miscompare!). |
||
#2 | 240 | Richard Geiger |
Version 1.2.5, to account for post-1999 RCS behavior. (Courtesy of David Simon, Goldman Sachs) |
||
#1 | 130 | Richard Geiger |
CVS-to-Perforce converter. This is release 1.2.2 (first submit to the Perforce Public Depot) |