| 1 | #!/usr/bin/perl -wspi~
|
|---|
| 2 |
|
|---|
| 3 | #
|
|---|
| 4 | # reads a perforce style diff on stdin and outputs appropriate headers
|
|---|
| 5 | # so the diff can be applied with the patch program
|
|---|
| 6 | #
|
|---|
| 7 | # Gurusamy Sarathy <gsar@activestate.com>
|
|---|
| 8 | #
|
|---|
| 9 |
|
|---|
| 10 | BEGIN {
|
|---|
| 11 | $0 =~ s|.*/||;
|
|---|
| 12 | if ($h or $help) {
|
|---|
| 13 | print STDERR <<USAGE;
|
|---|
| 14 | Usage: $0 [-v] [-h] files
|
|---|
| 15 |
|
|---|
| 16 | -h print this help
|
|---|
| 17 | -v output progress messages
|
|---|
| 18 |
|
|---|
| 19 | Does inplace edit of diff files output by the perforce commands
|
|---|
| 20 | "p4 describe", "p4 diff", and "p4 diff2". The result is suitable
|
|---|
| 21 | for feeding to the "patch" program.
|
|---|
| 22 |
|
|---|
| 23 | If no files are specified, reads from stdin and writes to stdout.
|
|---|
| 24 |
|
|---|
| 25 | WARNING: It only handles context or unified diffs.
|
|---|
| 26 |
|
|---|
| 27 | Example: p4 describe -du 123 | $0 > change-123.patch
|
|---|
| 28 |
|
|---|
| 29 | USAGE
|
|---|
| 30 | exit(0);
|
|---|
| 31 | }
|
|---|
| 32 | unless (@ARGV) { @ARGV = '-'; undef $^I; }
|
|---|
| 33 | use vars qw($thisfile $time $file $fnum $v $h $help);
|
|---|
| 34 | $thisfile = "";
|
|---|
| 35 | $time = localtime(time);
|
|---|
| 36 | }
|
|---|
| 37 |
|
|---|
| 38 | my ($cur, $match);
|
|---|
| 39 | $cur = m<^==== //depot/(.+?)\#\d+.* ====( \w+)?$> ... m<^(\@\@.+\@\@|\*+)$>;
|
|---|
| 40 |
|
|---|
| 41 | $match = $1;
|
|---|
| 42 |
|
|---|
| 43 | if ($ARGV ne $thisfile) {
|
|---|
| 44 | warn "processing patchfile [$ARGV]\n" unless $ARGV eq '-';
|
|---|
| 45 | $thisfile = $ARGV;
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | # while we are within range
|
|---|
| 49 | if ($cur) {
|
|---|
| 50 | # set the file name after first line
|
|---|
| 51 | if ($cur == 1) {
|
|---|
| 52 | $file = $match;
|
|---|
| 53 | $fnum++;
|
|---|
| 54 | }
|
|---|
| 55 | # emit the diff header when we hit last line
|
|---|
| 56 | elsif ($cur =~ /E0$/) {
|
|---|
| 57 | my $f = $file;
|
|---|
| 58 |
|
|---|
| 59 | # special hack for perl so we can always use "patch -p1"
|
|---|
| 60 | $f =~ s<^.*?(perl.*?/)><$1>;
|
|---|
| 61 |
|
|---|
| 62 | # unified diff
|
|---|
| 63 | if ($match =~ /^\@/) {
|
|---|
| 64 | warn "emitting udiff header\n" if $v;
|
|---|
| 65 | $_ = "Index: $f\n--- $f.~1~\t$time\n+++ $f\t$time\n$_";
|
|---|
| 66 | }
|
|---|
| 67 | # context diff
|
|---|
| 68 | elsif ($match =~ /^\*/) {
|
|---|
| 69 | warn "emitting cdiff header\n" if $v;
|
|---|
| 70 | $_ = "Index: $f\n*** $f.~1~\t$time\n--- $f\t$time\n$_";
|
|---|
| 71 | }
|
|---|
| 72 | }
|
|---|
| 73 | # see if we hit another patch (i.e. previous patch was empty)
|
|---|
| 74 | elsif (m<^==== //depot/(.+?)\#\d+.* ====( \w+)?$>) {
|
|---|
| 75 | $file = $match = $1;
|
|---|
| 76 | }
|
|---|
| 77 | # suppress all other lines in the header
|
|---|
| 78 | else {
|
|---|
| 79 | $_ = "";
|
|---|
| 80 | }
|
|---|
| 81 | warn "file [$file] line [$cur] file# [$fnum]\n" if $v;
|
|---|
| 82 | }
|
|---|
| 83 |
|
|---|
| 84 | $_ .= "End of Patch.\n" if eof;
|
|---|