Commit | Line | Data |
---|---|---|
384f7be5 GS |
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@umich.edu> | |
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; |