a few more p4genpatch fixes:
Gurusamy Sarathy [Sun, 5 May 2002 17:00:33 +0000 (17:00 +0000)]
don't assume previous revision exists, let p4 compute it from
the one-less-change number instead

the time part in timestamps were always 00:00:00; fix by
fetching metadata via "p4 fsync" rather than "p4 filelog"

quote all file names used in external commands to make them
them work when there are spaces in those file names

looks production worthy now :)

p4raw-id: //depot/perl@16416

Porting/p4genpatch

index 3b0bae3..74595b8 100644 (file)
@@ -26,13 +26,14 @@ Getopt::Long::Configure("no_ignore_case");
 GetOptions(\%OPT, "b=s", "p=s", "d=s", "D=s", "h", "v", "V") or die Usage;
 print Usage and exit if $OPT{h};
 print "$VERSION\n" and exit if $OPT{V};
-die Usage unless @ARGV == 1;
+die Usage unless @ARGV == 1 && $ARGV[0] =~ /^\d+$/;
+my $CHANGE = shift;
 
 for my $p4opt (qw(p)) {
   push @P4opt, "-$p4opt $OPT{$p4opt}" if $OPT{$p4opt};
 }
 
-my $system = "p4 @P4opt describe -s @ARGV |";
+my $system = "p4 @P4opt describe -s $CHANGE |";
 open my $p4, $system or die "Could not run $system";
 my @action;
 while (<$p4>) {
@@ -53,27 +54,31 @@ for my $a (@action) {
   $tempdir ||= tempdir( "tmp-XXXX", CLEANUP => 1, TMPDIR => 1 );
   my($action,$file,$prefix) = @$a;
   my($path,$basename,$number) = $file =~ m|\Q$prefix\E/(.+/)?([^/]+)#(\d+)|;
-  my($prevfile) = $file =~ m|^(.+)#\d+\z|;
+  my($depotfile) = $file =~ m|^(.+)#\d+\z|;
   die "Panic: Could not parse file[$file]" unless $number;
   $path = "" unless defined $path;
-  my($d1,$d2,$prev);
+  my($d1,$d2,$prev,$prevchange,$prevfile);
   $prev = $number-1;
-  $prevfile .= "#$prev";
-  if ($prev==0 or $action =~ /^(add|branch)$/) {
+  $prevchange = $CHANGE-1;
+  # can't assume previous rev == $number-1 due to obliterated revisions
+  $prevfile = "$depotfile\@$prevchange";
+  if ($number == 1 or $action =~ /^(add|branch)$/) {
     $d1 = "/dev/null";
   } elsif ($action =~ /^(edit|integrate)$/) {
-    $d1 = "$path$basename#$prev";
+    $d1 = "$path$basename-$prevchange";
     warn "==> $d1 <==\n" if $OPT{v};
-    my $system = "p4 @P4opt print -o $tempdir/$d1 $prevfile";
+    my $system = qq[p4 @P4opt print -o "$tempdir/$d1" "$prevfile"];
     my $status = `$system`;
     if ($?) {
       warn "$0: system[$system] failed, status[$?]\n";
       next;
     }
     chmod 0644, "$tempdir/$d1";
-    if (my($prevch) = $status =~ / \s change \s (\d+) \s /x) {
+    if ($status =~ /\#(\d+) \s - \s \w+ \s change \s (\d+) \s /x) {
+      ($prev,$prevchange) = ($1,$2);
+      $prevfile = "$depotfile#$prev";
       my $oldd1 = $d1;
-      $d1 .= "~$prevch~";
+      $d1 =~ s/-\d+$/#$prev~$prevchange~/;
       rename "$tempdir/$oldd1", "$tempdir/$d1";
     }
   } else {
@@ -81,7 +86,7 @@ for my $a (@action) {
   }
   $d2 = "$path$basename";
   warn "==> $d2#$number <==\n" if $OPT{v};
-  my $system = "p4 @P4opt print -o $tempdir/$d2 $file";
+  my $system = qq[p4 @P4opt print -o "$tempdir/$d2" "$file"];
   # warn "system[$system]";
   my $type = `$system`;
   if ($?) {
@@ -97,9 +102,8 @@ for my $a (@action) {
       next;
     }
     print "Index: $path$basename\n";
-    my @filelog = `p4 @P4opt filelog $file`;
-    correctmtime(\@filelog,$prev,"$tempdir/$d1");
-    correctmtime(\@filelog,$number,"$tempdir/$d2");
+    correctmtime($prevfile,$prev,"$tempdir/$d1");
+    correctmtime($file,$number,"$tempdir/$d2");
     chdir $tempdir or warn "Could not chdir '$tempdir': $!";
     $system = qq[$OPT{D} -$OPT{d} "$d1" "$d2"];
     system($system); # no return check because diff doesn't always return 0
@@ -112,26 +116,10 @@ for my $a (@action) {
 print "End of Patch.\n";
 
 sub correctmtime ($$$) {
-  my($filelog,$nr,$file) = @_;
-  for my $line (@$filelog) {
-    my($rev,$change,$action,$date) =
-        $line =~ m{ ^ \.\.\. \s
-                    \#
-                    (\d+)            # rev
-                    \s change \s
-                    (\d+)            # change
-                    \s (\w+) \s      # action
-                    on \s (\S+)      # date
-                  }x or next;
-    # warn "rev[$rev]";
-    next unless $rev == $nr;
-    my(@date) = split m|/|, $date;
-    $date[0] -= 1900;
-    $date[1]--;
-    my $time = timelocal(0,0,0,reverse @date);
-    utime $time, $time, $file;
-    last;
-  }
+  my($depotfile,$nr,$localfile) = @_;
+  my %fstat = map { /^\.\.\. (\w+) (.*)$/ } `p4 @P4opt fstat "$depotfile"`;
+  return unless $fstat{headRev} == $nr;
+  utime $fstat{headTime}, $fstat{headTime}, $localfile;
 }
 
 sub Usage () {