#! perl.exe # P4 Script # Integrates a changelist from one branch to another, and puts # the integration into a new changelist with a comment and the same # job fixes attached. # Created: 11-DEC-2001 $| = 1; #my $p4 = "/usr/local/bin/p4-cygwin-2002.2_40318.exe"; my $p4 = "p4"; #my $debug = 1; my $debug = 0; my $DBGOUT = \*STDERR; my $cmd; ###################################################### # Parse the command-line my $branchChangelist = shift || ""; my $branchSpec = shift || ""; my $integOptions = ""; my $preview = 0; my $doPause = 0; if ($branchChangelist eq "" || $branchChangelist eq "-h" || $branchSpec eq "") { help(); } while (1) { $_ = shift || ""; last if ($_ eq ""); if ($_ eq "-pause") { $doPause = 1; } else { if ($_ eq "-n") { $preview = 1; } $integOptions = $integOptions . " " . $_; } } ###################################################### # Check that the branch spec exists my $branchLine = ""; $cmd = "$p4 branches"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "$cmd|" ) || die "Could not exec P4 command [$cmd]: $!"; while () { /^Branch (\S*)/; if ($branchSpec eq $1) { $branchLine = $1; } } if ($branchLine eq "") { print "Branch $branchSpec does not exist.\n"; print "Integration aborted.\n"; quit( 2 ); } ###################################################### # Find the branch spec view my $branchView = ""; $cmd = "$p4 branch -o $branchSpec"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "$cmd|" ) || die "Could not exec P4 command [$cmd]: $!"; while () { if (/^View:/) { $branchView = "Branch View:"; # read in a paragraph while () { last if !(/^\t(.*)/); $branchView = $branchView . "\n\t" . $1; } } } close P4; if ($branchView eq "") { print "Could not find branch $branchSpec\n"; print "Integration Aborted.\n"; quit( 2 ); } print $branchView . "\n"; ###################################################### # Find info about the old changelist my $olduser = ""; my $olddescription = ""; my $oldjobs = ""; $cmd = "$p4 change -o $branchChangelist"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "$cmd|" ) || die "Could not exec P4 command [$cmd]: $!"; while () { print $DBGOUT "change input: $_\n" if $debug; if (/^Client:\s*(\w*)/) { $oldclient = $1; } if (/^User:\s*(\w*)/) { $olduser = $1; } if (/^Description:/) { # read in a paragraph while () { last if !(/^\t(.*)/); $olddescription = $olddescription . "\n\t" . $1; } } if (/^Jobs:/) { # read in the job list while () { last if !(/^\t(.*)\t/); $oldjobs = $oldjobs . "\n\t" . $1; } } } close P4; if ($olduser eq "") { print "Could not find changelist $branchChangelist\n"; print "Integration aborted.\n"; quit( 2 ); } ###################################################### # Find info about the new changelist my $client = ""; my $user = ""; $cmd = "$p4 change -o"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "$cmd|" ) || die "Could not exec P4 command [$cmd]: $!"; while () { print $DBGOUT "new changelist out: $_\n" if $debug; if (/^Client:\s*(\w*)/) { $client = $1; } if (/^User:\s*(\w*)/) { $user = $1; } } close P4; if ($user eq "" || $client eq "") { print "Could not access a new changelist.\n"; print "Integration aborted.\n"; quit( 2 ); } ###################################################### # Create the changelist my $newChangelist = "Client:\t" . $client . "\n" . "User:\t" . $user . "\n" . "Change:\tnew\n" . "Status:\tnew\n" . "Description:" . "\n\tIntegrate changelist $branchChangelist using branchspec $branchSpec" . "\n\tChangelist $branchChangelist opened by $olduser" . "\n\t\n\tOriginal Description:" . $olddescription . "\nJobs:" . $oldjobs . "\n"; my $newChangeNumber = "x"; my $integChange = ""; $cmd = "$p4 change -i"; if ($preview) { print "$cmd\n"; print "\<\<\n"; print $newChangelist; print "\>\>\n"; } else { print "new changelist: [$newChangelist]\n" if $debug; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "|$cmd > .p4tmp" ) || die "Could not create a changelist: $!"; print P4 $newChangelist; close P4; open( P4OUT, ".p4tmp" ) || die "Could not open P4 output: $!"; while () { #print "P4 output: $_\n"; if (/Change (\d*) created/) { $newChangeNumber = $1; $integChange = "-c $newChangeNumber"; } } if ($newChangeNumber eq "") { print "No output found for P4 operation.\n"; print "Integration aborted.\n"; quit( 2 ); } close P4OUT; unlink( ".p4tmp" ); print "Created Change $newChangeNumber for the integration.\n"; } ###################################################### # Perform the integration print "Performing integration:\n"; $cmd = "$p4 integ $integChange -b $branchSpec $integOptions -s //...\@$branchChangelist,\@$branchChangelist //..."; print $DBGOUT "[[[$cmd]]]\n" if $debug; my $out = system( $cmd ); print $DBGOUT "execution returned [$out]\n" if $debug; if ($out != 0) { print "Failed on the integration step. Backing out of the new change.\n"; if (!($newChangeNumber eq "x")) { # Revert the integrated files, if any $cmd = "$p4 change -o $newChangeNumber"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "$cmd|" ); my @files = (); my $onFiles = 0; while () { if (/^Files:/) { $onFiles = 1; } elsif ($onFiles) { if (/^\s+([^#]+)\s#/) { push @files, $1; } } } $cmd = "$p4 revert " . join(" ",@files); print $DBGOUT "[[[$cmd]]]\n" if $debug; system( $cmd ); # Remove the Job fix(es) $cmd = "$p4 change -i"; print $DBGOUT "[[[$cmd]]]\n" if $debug; open( P4, "|$cmd" ); print P4 "Change:\t$newChangeNumber\n" . "Client:\t$client\n" . "User:\t$user\n" . "Status:\tpending\n" . "Description:\n\tremove\n" . "Jobs:\n"; close P4; # Delete the changelist $cmd = "$p4 change -d $newChangeNumber"; print $DBGOUT "[[[$cmd]]]\n" if $debug; system( $cmd ); } quit( 2 ); } print "--------------------------------------------------------------------------\n"; print "You need to submit changelist $newChangeNumber to complete this operation.\n"; # Quit the script quit( 0 ); ###################################################### sub help { print "Perform a branch integration based on another changelist, and\n"; print "modify the new changelist to imitate the original changelist.\n\n"; print 'Usage: branchchange.pl [-r] [-n]'; print "\nwhere\n"; print " Changelist \# the changelist to base the integration on.\n"; print " BranchSpec Name the name of the branchspec to base the \n"; print " integration to/from on.\n"; print " -r reverse the branchspec order (same as\n"; print " 'p4 integ -r').\n"; print " -n preview the change (same as 'p4 integ -n')\n"; quit( 1 ); } sub quit { my ($x) = @_; if ($doPause) { print "Press return to continue"; <>; } exit( $x ); }