1 | #!/l/local/bin/perl -wspi.bak |
---|
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+.* ====$> ... 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+.* ====$>) { |
---|
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; |
---|