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/genmetadata#14 $ # # Richard Geiger # require 5.000; use bytes; 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 not done yet. Be patient. LIT exit 1; } sub mklabel { my ($label, @Revs) = @_; print "make label: $label\n"; $label = &atq($label); my $time = time; print DBLBLS "\@pv\@ 2 \@db.domain\@ $label 108 \@\@ \@\@ ". "\@cvs2p4\@ $time $time 8 0 \@Created by cvs2p4.\@\n"; foreach my $rev (@Revs) { my ($f, $r) = ($rev =~ /^(.*)#(\d+)$/); $f = &p4_esc($f); $f = &atq($f); print DBLBLS "\@pv\@ 0 \@db.label\@ $label $f $r\n"; } } # option switch variables get defaults here... $Convdir = ""; $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; } push(@Args, $ARGV[0]); shift; } if ($#Args ne 0) { &usage; } $Convdir = $Args[0]; #chdir $Convdir || die "$Myname: can't chdir \"$Convdir\": $!"; #$Convdir = `/bin/pwd`; chop $Convdir; #chdir $Here || die "$Myname: can't chdir \"$Here\": $!"; require "$Convdir/config"; my %labelmap; if (-e "$Convdir/labelmap") { if (! open(LBLMAP, "<$Convdir/labelmap")) { die "Could not open \"$Convdir/labelmap\": $!\n"; } while (<LBLMAP>) { my ($label, $branch) = split(/\t/, $_); $labelmap{$label} = $branch; } my @nmap = keys(%labelmap); my $n = $#nmap + 1; print "$Myname: loaded label map; $n labels.\n"; } $Metadata = "$Convdir/metadata"; $Labels = "$Convdir/labels"; $Rrevmap = "$Convdir/rrevmap"; #$DBlbls = "$P4ROOT/dblbls"; $Checkpoint = "checkpoint"; # Path the the p4 client command # if (! defined($P4)) { $P4 = "/usr/local/bin/p4"; } if (! -x ($P4)) { print "$Myname: No executable \"p4\" command at \"$P4\".\n"; exit 1; } $P4 = "$P4 -p $P4PORT -c cvs2p4 -u $P4USER"; use DB_File; $DBMCLASS="DB_File"; $myhashinfo = new DB_File::HASHINFO; $myhashinfo->{bsize} = 4096; if (! tie(%RREVMAP, $DBMCLASS, $Rrevmap, O_RDONLY, 0444, $myhashinfo)) { print "$Myname: can't tie \"$Rrevmap\": $!\n"; exit 1; } if (! open(LABELS, "<$Labels")) { print "$Myname: can't open \">$Labels\": $!\n"; exit 1; } # Open the db metadata (journal format) file we will write # #$DBlbls =~ s%^.*/%%; $P4D = "$P4D -r ."; if (! open(DBLBLS, "| (cd $P4ROOT && $P4D -jr -)")) { print "$Myname: can't open \"| (cd $P4ROOT && $P4D -jr -)\": $!\n"; exit 1; } #if (&s("cd $P4ROOT && $P4D -jr $DBlbls")) # { print "$Myname: \"$P4D -jr $DBlbls\" failed.\n"; exit 1; } #if (! open(DBLBLS, ">$DBlbls")) # { print "$Myname: can't open \"$DBlbls\": $!\n"; exit 1; } ################################################################################ # # branch_for_tag() # # Due to differences in the way Perforce and RCS/CVS work, Perforce # cannot know, by looking at the RCS archive alone, which branch(s) a # given label applies to. The default, in essence, is to make tags # for ALL branches to which it _could_ apply. This results in huge # numbers of often useless labels, and long "dolabels" phases. # # Often, however, the day can be saved, IF the user can provide a # mapping function that can take a label name and map it to a branch # name, along with a function that can take a Perforce revision # (pathname and revision number), and a branch name, and return an # indication of whether the revision given is in fact on the branch # given. (The latter function is usually trivially easy). # # If you want to use this feature, you will need to uncomment and # modify the following two functions to match your data. # # The first takes an RCS revision tag, and returns the name of the # branch that the revision is associated with: # sub branch_for_tag { my ($tag) = @_; # These are a couple of example mappings, in this case based # on the format of the tag names themselves (but your function # is free to use any method you can devise): # # if ($tag =~ /^v(\d+)_(\d+)_([dab])_(\d)+$/) { return "main"; } # if ($tag =~ /^(branch_.*)_\d\d\d$/) { return $1; } # ADD YOUR CODE HERE # Sorry, can't map this one I guess. # return ""; } # The second function you need to pay attention to is rev_on_branch(). # # Usually, this will be just as shown here, where it involves # comparing a component of the revision's pathname (i.e., the # "branch-level directory" in Perforce, with the given $tag_branch. # The result of the comparison is the result of the function. # # If your conversion uses the default arrangement in the cvs2p4 # config file, so that the third pathname component is the branch # name, e.g., # # //depot/<module>/<branch>/... # # you won't need to change this at all: # sub rev_on_branch { my ($rev, $tag_branch) = @_; my ($branch) = ($rev =~ /^\/\/depot\/[^\/]+\/([^\/]+)\//); return ($branch eq $tag_branch); } # # End of branch_for_tag() stuff... # ################################################################################ @Revs = (); while (<LABELS>) { if (/^([^\s]+)/) { if ($#Revs >= 0) { &mklabel($label, @Revs); } $label = $1; @Revs = (); } elsif (/^ (.*)/) { $tag = $1; if ($revs = $RREVMAP{$tag}) { # GOAL: determine the branch this tag is for # (which is encoded in the tag name), # and only do the push for the revision # in $revs that is on the branch it belongs # to.... # if (defined(&branch_for_tag)) { $tag_branch = &branch_for_tag($label); if (! $tag_branch) { next; } } foreach $rev (split(/\001/, $revs)) { if ((! defined(&branch_for_tag)) || &rev_on_branch($rev, $tag_branch)) { push (@Revs, $rev); } } } } } if ($#Revs >= 0) { &mklabel($label, @Revs); } close DBLBLS; close LABELS; untie %RREVMAP; #if (&s("cd $P4ROOT && rm -f $Checkpoint; $P4D -jd $Checkpoint")) # { print "$Myname: \"$P4D -jd $Checkpoint\" failed.\n"; exit 1; } exit 0;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#45 | 6301 | Richard Geiger |
These changes resulted from a recent customer conversion. A checkpoint, more or less. |
||
#44 | 5712 | Richard Geiger |
Handle Pathhacks in srcdiff & dolabels. Moves sub Pathhacks() into util.pl |
||
#43 | 5706 | Richard Geiger | Makes branch specs now. | ||
#42 | 5676 | Richard Geiger |
Add $CONVUSER to set owner for label and depot specs create dby the conversion. |
||
#41 | 5675 | Richard Geiger | Make labels unlocked. | ||
#40 | 5673 | Richard Geiger | checkpoint ironport latest. | ||
#39 | 5672 | Richard Geiger |
dochanges now remembers the list of known depots so dolabels can make explicit global mappings. |
||
#38 | 5622 | Richard Geiger | Yet another labels fix. | ||
#37 | 5618 | Richard Geiger | Fixes labels with unmodified "cvs imported" files. | ||
#36 | 5615 | Richard Geiger | more depot mapping fixes. | ||
#35 | 5599 | Richard Geiger | About to unleash 3.0 upon an unsuspecting world... | ||
#34 | 5588 | Richard Geiger |
checkpoint the latest. This includes a rework of the label-heursitical stuff that seems to work better. |
||
#33 | 5585 | Richard Geiger |
do complete branch determination in bin/genmetadata now... heh. |
||
#32 | 5584 | Richard Geiger | brmap loading is now a function in lib/util.pl | ||
#31 | 5574 | Richard Geiger |
This makes it so we really *do* $DISCARD_UNMAPPED_TAGS when it is set! This will discard the UNMAPPED-NOTFOUND, while preserving the desired spoofing behavior for UNMAPPED-COLLISIONs. |
||
#30 | 5567 | Richard Geiger |
Seems pretty close to right at this point. This change makes sure that we handle labels on "ambiguous" revisions (any 1.1.1.n, n > 1 revisions commited before any 1.2) as being present in *both* the import branch AND main correctly. |
||
#29 | 5563 | Richard Geiger |
Life is a corner case. "UNMAPPED-COLLISION tags in tags.txt now indicate what collided better. Fix srcdiff to handle odd Log expansion corner case that was causing flase positives. |
||
#28 | 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. |
||
#27 | 5509 | Richard Geiger | checkpoint | ||
#26 | 5480 | Richard Geiger |
Better vendor-branch handling... it's tricky! genmetadata now includes a flag in each line of the generated $Convdir/labels to indicate whether the file in question had "$Rcs_import_is_main" set. (The file had "branch: 1.1.1" as the default branch). |
||
#25 | 5470 | Richard Geiger | The Neverending Story. | ||
#24 | 5468 | Richard Geiger | remove some debug cruft. | ||
#23 | 5467 | Richard Geiger |
checkpoint. Need to update the docs prior to release! |
||
#22 | 5453 | Richard Geiger | checkpoint | ||
#21 | 5449 | Richard Geiger | gearing up for 2.6.0 release... | ||
#20 | 5442 | Richard Geiger |
A checkpoint commit on the way to a 2.6.0 release with the new IronPort inspired improvements. |
||
#19 | 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! |
||
#18 | 5291 | Richard Geiger | Handle incomplete external label -> branch maps... | ||
#17 | 5277 | Richard Geiger | Another fix for the labelmap stuff. | ||
#16 | 5276 | Richard Geiger | correction to the previous rev's agenda. | ||
#15 | 5275 | Richard Geiger |
Configured for QCSI's conversion. Not for public consumption in this form! |
||
#14 | 5274 | Richard Geiger | Fix the last checkpoint... | ||
#13 | 5273 | Richard Geiger | checkpoint | ||
#12 | 5271 | Richard Geiger |
Sleep in runtest to make it work more reliably on fast machines; And write to "p4 -jr -" instead of "p4root/dblabels", to save space and maybe go faster... "for now, at least". |
||
#11 | 5143 | Richard Geiger | prep for 2.5.5 | ||
#10 | 4352 | Richard Geiger | for the 2.4 release. | ||
#9 | 4327 | Richard Geiger |
Add a facility for smarter label-making, if the user can provide a mapping function between RCS/CVS tag names and and Perforce branches. This is experimental at this stage. |
||
#8 | 3708 | Richard Geiger | Changes for 2.3.6 | ||
#7 | 2061 | Richard Geiger |
changes for 2.3.2: - can adjust db hash bucket size; - Add $DEPOT config variable - Handle labels with '#' or '@' |
||
#6 | 1987 | Richard Geiger | Changes for 2.3.1 | ||
#5 | 1977 | Richard Geiger | Explicit p4d -r | ||
#4 | 1781 | Richard Geiger |
This change reintegrates cvs2p4 2.0 developement work (through 2.0b6) back into my mainline development. |
||
#3 | 1407 | Richard Geiger |
=== Release 1.3.2 - Reduce the memory footprint of bin/genmetadata. Previously, it was holding and sorting a complete copy of the metadata file "in-core" (as well as a copy of all of the RCS revision tags data!). This adds up quick, and some users saw genmetadata gobbling memory voraciously (and in some cases being running out, causing thrashing and/or process termination by the OS). genmetadata now keeps the metadata in a temp file, (sorting it in primary-key-sized chunks), and the revision tag information in a db-backed hash. - Fix the label handling so that _all_ perforce revisions based on the labeled cvs revision are included in the generated labels. Previously, one of the N "correct" Perforce revisions were being tagged (effectively, at random). This stems from the fact that lazy copying and branching are explicit in Perforce, but implicit in CVS. I.e., the "#1" revision in a new Perforce branch _appears_ to be a separate entity (identical to the revision from which it was branched. This means that to use the converted labels, it will be up to _you_ to remember what labels go with what branches: but that's the way it is in CVS, too. - A minor change in revmap to have a meaningful usage message, and properly handle the new rrevmap format. - dochanges correctly deletes revmap database files for either *.db or *.pag/*.dat style databases. |
||
#2 | 1203 | Richard Geiger |
Fix bug where dolables couldn't cope with tag in which the revision for a file was a delete Add the IMPORTTAGSPOOF switch. |
||
#1 | 1185 | Richard Geiger |
Changes for 1.3 (Labels!) |