+++ /dev/null
-#!/l/local/bin/perl -wspi.bak
-
-#
-# reads a perforce style diff on stdin and outputs appropriate headers
-# so the diff can be applied with the patch program
-#
-# Gurusamy Sarathy <gsar@activestate.com>
-#
-
-BEGIN {
- $0 =~ s|.*/||;
- if ($h or $help) {
- print STDERR <<USAGE;
-Usage: $0 [-v] [-h] files
-
- -h print this help
- -v output progress messages
-
-Does inplace edit of diff files output by the perforce commands
-"p4 describe", "p4 diff", and "p4 diff2". The result is suitable
-for feeding to the "patch" program.
-
-If no files are specified, reads from stdin and writes to stdout.
-
-WARNING: It only handles context or unified diffs.
-
-Example: p4 describe -du 123 | $0 > change-123.patch
-
-USAGE
- exit(0);
- }
- unless (@ARGV) { @ARGV = '-'; undef $^I; }
- use vars qw($thisfile $time $file $fnum $v $h $help);
- $thisfile = "";
- $time = localtime(time);
-}
-
-my ($cur, $match);
-$cur = m<^==== //depot/(.+?)\#\d+.* ====$> ... m<^(\@\@.+\@\@|\*+)$>;
-
-$match = $1;
-
-if ($ARGV ne $thisfile) {
- warn "processing patchfile [$ARGV]\n" unless $ARGV eq '-';
- $thisfile = $ARGV;
-}
-
-# while we are within range
-if ($cur) {
- # set the file name after first line
- if ($cur == 1) {
- $file = $match;
- $fnum++;
- }
- # emit the diff header when we hit last line
- elsif ($cur =~ /E0$/) {
- my $f = $file;
-
- # special hack for perl so we can always use "patch -p1"
- $f =~ s<^.*?(perl.*?/)><$1>;
-
- # unified diff
- if ($match =~ /^\@/) {
- warn "emitting udiff header\n" if $v;
- $_ = "Index: $f\n--- $f.~1~\t$time\n+++ $f\t$time\n$_";
- }
- # context diff
- elsif ($match =~ /^\*/) {
- warn "emitting cdiff header\n" if $v;
- $_ = "Index: $f\n*** $f.~1~\t$time\n--- $f\t$time\n$_";
- }
- }
- # see if we hit another patch (i.e. previous patch was empty)
- elsif (m<^==== //depot/(.+?)\#\d+.* ====$>) {
- $file = $match = $1;
- }
- # suppress all other lines in the header
- else {
- $_ = "";
- }
- warn "file [$file] line [$cur] file# [$fnum]\n" if $v;
-}
-
-$_ .= "End of Patch.\n" if eof;
+++ /dev/null
-#!/usr/bin/perl -wpi.bak
-
-#
-# Munge "p4 describe ..." output to include new files.
-#
-# Gurusamy Sarathy <gsar@activestate.com>
-#
-
-use vars qw($thisfile $change $file $fnum $h $v $p4port @addfiles
- $branches $skip);
-
-BEGIN {
- $0 =~ s|^.*/||;
- $p4port = $ENV{P4PORT} || 'localhost:1666';
- for (@ARGV) {
- if ($p4port =~ /^\s+$/) {
- $p4port = $_;
- }
- elsif (/^-p(.*)$/) {
- $p4port = $1 || ' ';
- }
- elsif (/^-b(.*)$/) {
- $branches = $1;
- }
- elsif (/^-v$/) {
- $v++;
- }
- elsif (/^-h/) {
- $h++;
- }
- else {
- push @files, $_;
- }
- }
- unless (@files) { @files = '-'; undef $^I; }
- @ARGV = @files;
- $branches = '//depot/perl/' unless defined $branches;
- if ($h) {
- print STDERR <<USAGE;
-Usage: $0 [-p \$P4PORT] [-v] [-h] [files]
-
- -phost:port p4 port (e.g. myhost:1666)
- -h print this help
- -v output progress messages
- -bbranch(es) which branches to include (regex)
- (default: //depot/perl/)
- -h show this help
-
-A smart 'cat'. When fed the spew from "p4 describe ..." on STDIN,
-spits it right out on STDOUT, followed by patches for any new files
-detected in the spew. Can also be used to edit insitu a bunch of
-files containing said spew.
-
-WARNING 1: Currently only emits unified diffs (diff -u).
-
-WARNING 2: By default only the changes in the //depot/perl branch
-are shown. To include all the branches, supply "-b." arguments
-to $0.
-
-Examples:
- p4 describe -du 123 | $0 > change-123.desc
- p4 describe -du 123 | $0 | p4d2p > change-123.patch
-
-USAGE
- exit(0);
- }
- $thisfile = "";
-}
-
-
-if ($ARGV ne $thisfile) {
- warn "processing patchfile [$ARGV]\n" unless $ARGV eq '-';
- $thisfile = $ARGV;
-}
-
-my $cur = m|^Affected files| ... m|^Differences|;
-
-# while we are within range
-if ($cur) {
- if (m|^\.\.\. |) {
- if (m|$branches|) {
- if (m{^\.\.\. (//depot/.+?\#\d+) (add|branch)$}) {
- my $newfile = $1;
- push @addfiles, $newfile;
- warn "$newfile add, revision != 1!\n" unless $newfile =~ /#1$/;
- }
- } else {
- push @skipped, "# $_";
- $_ = '';
- }
- }
- warn "file [$file] line [$cur] file# [$fnum]\n" if $v;
-}
-
-if (m|^==== //depot/|) {
- $skip = !m|$branches|;
- print "# Skipped because not under branches: $branches\n" if $skip;
-}
-
-$_ = "# $_" if $skip;
-
-if (/^Change (\d+) by/) {
- $_ = "\n\n" . $_ if $change; # start of a new change list
- $change = $1;
- my $new = newfiles();
- if ($new) {
- $_ = $new . $_;
- }
-}
-
-if (eof) {
- $_ .= newfiles();
- $_ .= join('', "\n",
- "# Skipped because not under branches: $branches\n",
- @skipped, "\n") if @skipped;
-}
-
-sub newfiles {
- my $addfile;
- my $ret = "";
- for $addfile (@addfiles) {
- my $type = `p4 -p $p4port files '$addfile'`;
- if ($?) {
- warn "$0: `p4 -p $p4port print '$addfile'` failed, status[$?]\n";
- next;
- }
- $type =~ m|^//.*\((.+)\)$| or next;
- $type = $1;
- unless ($type =~ /text/) {
- $ret .= "\n==== $addfile ($type) ====\n\n";
- next;
- }
- my @new = `p4 -p $p4port print '$addfile'`;
- if ($?) {
- die "$0: `p4 -p $p4port print '$addfile'` failed, status[$?]\n";
- }
- my $desc = shift @new; # discard initial description
- $ret .= "\n==== $addfile ($type) ====\n\n";
- my $lines = "," . @new;
- $lines = "" if @new < 2;
- $ret .= "\@\@ -0,0 +1$lines \@\@\n";
- $ret .= join("+","",@new);
- $ret .= "\n\\ No newline at end of file\n" if $ret !~ /\n$/;
- }
- @addfiles = ();
- return $ret;
-}
Generating a patch for change#42 is done as follows:
- % p4 describe -du 42 | p4desc | p4d2p > change-42.patch
+ % p4genpatch 42 > change-42.patch
-F<p4desc> and F<>p4d2p> are to be found in //depot/perl/Porting/.
+F<p4genpatch> is to be found in //depot/perl/Porting/.
The usual routine to apply a patch is
% p4 describe -du 12345 # show change 12345
Note: the output of "p4 describe" is not in proper diff format, use
-the F<Porting/p4d2p> to convert.
+the F<Porting/p4genpatch> to get a diff-compatible format.
% p4 diff -se ./... # have I modified something but forgotten
# to "p4 edit", easy faux pas with autogenerated