5 # Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 # Email: <neilb@cse.unsw.edu.au>
25 # School of Computer Science and Engineering
26 # The University of New South Wales
31 # metadata is in .patches
33 # files: list of all files checked out
34 # name: name of current patch
35 # status: status of current patch
36 # notes: notes on current patch
37 # applied/ patches applied nnn-name
38 # removed/ patches removed nnn-name
39 # included/ patches that have been included upstream
40 # patch: a recent copy of the 'current' patch
41 # get-version: a script which will report the version number of the base dist
42 # dest/ symlink to directory to publish snapshots to
43 # mail/ composed mail messages ready for sending
44 # maintainer who to email patches to (Linus etc)
45 # cc who to CC patches to: prefix address
47 # the nnn in names in applied and removed are sequence numbers
48 # whenever we add a file we choose one more than the highest used number
49 # patch files contain then name implicitly and start with
51 # then a blank line, normally a one line description, another blank, and more detail.
55 # Todo - auto bk pull:
57 # bk export -t patch -r DEVEL, > /tmp/apatch
59 # while p open last && p discard ; do : ; done
61 # patch -p1 -f < /tmp/apatch
65 # walk up directory tree until a .patches directory
67 # set OrigDir to name of where we were .. not dots.
70 while [ ! -d .patches
-a " $dir" != " /" ]
78 OrigDir
=$base/$OrigDir
86 name
=`cat .patches/name 2> /dev/null`
87 status
=`cat .patches/status 2> /dev/null`
99 [ -f .patches
/config
] ||
>> .patches
/config
103 '[global]' ) _active
=yes ;;
104 "[$_context]") _active
=yes ;;
105 "["*"]" ) _active
= ;;
106 * ) if [ " $b" == " =" -a " $a" = " $_name" -a -n "$_active" ];
111 _result
="$_result$_sep$c"
117 done < .patches
/config
118 _result
=$
(echo "$_result" |
sed 's/^"//' )
119 eval $_name=\"\
$_result\"
124 # move $1~current~ to .patches/current/$1 and same for orig
126 for f
in current orig
130 mkdir
-p ".patches/$f${fl%/*}"
131 mv "$1~$f~" ".patches/$f/$1"
139 if true
# || cmp -s "$1" ".patches/curent/$1~" && cmp -s "$1" ".patches/orgi/$1"
141 rm -f ".patches/current/$1" ".patches/orig/$1"
144 echo >&2 "ERROR $1 doesn't match original"
151 mkdir
-p .patches
/orig
${f%/*}
152 mkdir
-p .patches
/current
${f%/*}
153 rm -f .patches
/orig
$f .patches
/current
$f
154 cp -p $1 .patches
/orig
$f
155 cp -p $1 .patches
/current
$f
160 cp "$1" "$1~snapshot~"
165 diff -u "$1" "$1~snapshot~"
169 cp "$1~snapshot~" "$1"
177 [ -f $file ] ||
>> $file
180 if [ ! -f ".patches/orig/$file" ] ; then
181 mkdir
-p .patches
/orig
/$f
182 mv "$file" ".patches/orig/$file"
183 cp ".patches/orig/$file" "$file"
184 echo $file >> .patches
/files
185 sort -o .patches
/files .patches
/files
188 if [ ! -f ".patches/current/$file" ] ; then
189 mkdir
-p .patches
/current
/$f
190 mv "$file" ".patches/current/$file"
191 cp ".patches/current/$file" "$file"
194 echo >&2 Cannot checkout
$file
203 done < .patches
/files
208 if cmp -s ".patches/current/$1" "$1" ||
[ ! -f "$1" -a ! -f ".patches/current/$1" ]
212 echo "diff .prev/$1 ./$1"
215 diff -N --show-c-function -u "./$1" "./.patches/current/$1"
217 diff -N --show-c-function -u "./.patches/current/$1" "./$1"
224 if cmp -s ".patches/orig/$1" "$1"
228 echo "diff ./.patches/orig/$1 ./$1"
229 diff --show-c-function -u "./.patches/orig/$1" "./$1"
235 rm -f ".patches/current/$1"
236 if [ -f "$1" ] ; then
237 mv "$1" ".patches/current/$1"
238 cp -p ".patches/current/$1" $1
245 cmp -s ".patches/current/$1" $1 ||
{ rm -f "$1" ; cp ".patches/current/$1" $1; }
252 mv ".patches/current/$1" "$1"
253 mv "$1.tmp" ".patches/current/$1"
261 [ -s .patches
/status
] && echo "Status: `cat .patches/status`"
262 [ -s .patches
/notes
] && { echo; cat .patches
/notes
; }
263 if [ -z "$tagline" ] ||
grep -F "$tagline" .patches
/notes
> /dev
/null
2>&1
268 all_files diff_one
$1 > .patches
/tmp
269 echo "### Diffstat output"
270 diffstat
-p0 2> /dev
/null
< .patches
/tmp
272 [ -s .patches
/tmp
] ||
rm .patches
/patch
274 } |
sed 's,^--- ./.patches/current/,--- .prev/,' ; } > .patches
/patch
281 # move .patches/patch to $dir/nnn$name
283 [ -d $dir ] || mkdir
$dir ||
exit 1
284 largest
=`ls $dir | sed -n -e 's/^\([0-9][0-9][0-9]\).*/\1/p' | sort -n | tail -1`
285 if [ "0$largest" -eq 999 ]
286 then echo >&2 'ARRG - too many patches!' ; exit 1
288 new
=`expr "0$largest" + 1001`
290 mv .patches
/patch $dir/$new$name
295 # set "prefix" to number for -pn by looking at first file in given patch.
297 file=`lsdiff $1 | head -$n | tail -1`
301 b
/* ) prefix
=1; return
303 while [ \
( -n "$file" -a ! -f "$file" \
) -o " $file" != " ${file#/}" ]
305 file=`expr "$file" : '[^/]*/\(.*\)'`
306 prefix
=`expr $prefix + 1`
309 then echo "Cannot find $orig" >&2
312 else find_prefix
"$1" $
[n
+1]
315 if [ " $orig" != " $file" ]
317 echo "Found $orig as $file - prefix $prefix"
323 # remove first line, Status: line, leading blanks,
324 # everything from ' *---' and trailing blanks
326 BEGIN { head= 1; blanks=0 ; }
327 head == 1 && ( $1 == "Status:" || $0 == "" ) {
331 $0 == "" { blanks++; next; }
332 $0 ~ /^ *---/ { exit }
334 { while (blanks > 0) {
345 echo >&2 'Usage: p [help|co|make|discard|commit|status|name|...] args'
351 if [ " $cmd" = " help" ] || find_home
353 else echo >&2 "p $cmd: cannot find .patches directory"
359 if [ $# -ne 1 ] ; then
360 echo >&2 Usage
: p co
file; exit 1
363 if [ ! -f "$OrigDir$file" ]
365 echo >&2 "p co: file $file not found"; exit 1;
367 check_out
"$OrigDir$file"
374 if [ -s .patches
/patch ] ; then
377 echo >&2 "No current patch" ; exit 1;
382 * ) pfile
=`echo .patches/[ra][ep][mp]*/*$1*`
385 then echo >&2 "Cannot find unique patch '$1' - found: $pfile"; exit 1;
387 ptn
='^\+.*(( |[^ ].{7}){10}.|[ ]$)'
388 if grep -E -s "$ptn" $pfile > /dev
/null
390 ${PAGER-less -p "$ptn"} $pfile
397 all_files diff_one_orig
403 if [ $cmd = name
] ; then
404 if [ -n "$name" ]; then
405 echo "changing name from '$name' to '$1'"
407 echo "Setting name to '$1'"
409 echo "$1" > .patches
/name
411 if [ $cmd = status
] ; then
412 if [ -n "$status" ]; then
413 echo "changing status from '$status' to '$1'"
415 echo "Setting status to '$1'"
417 echo "$1" > .patches
/status
422 echo -n "Name ($name)? " ; read name
423 echo -n "Status ($status)? " ; read status
424 [ -n "$name" ] && { echo $name > .patches
/name
; }
425 [ -n "$status" ] && { echo $status > .patches
/status
; }
428 echo "Usage: p $cmd [new-$cmd]"; exit 1;
433 ${EDITOR:-vi} .patches
/notes
437 if [ -s .patches
/patch ]
439 else echo >&2 No
patch to
$cmd ; exit 1
441 if grep -s '^+.*[ ]$' .patches
/patch > /dev
/null
443 echo >&2 remove trailing spaces
/tabs first
!!
446 if [ $cmd == "commit" -a -f scripts
/checkpatch.pl
] ; then
447 perl
scripts
/checkpatch.pl .patches
/patch
449 if [ -s .patches
/to-resolve
]
450 then echo "Please resolve outstanding conflicts first with 'p resolve'"
454 if [ -z "$name" ] ; then
455 echo -n "Name? " ; read name
456 if [ -z "$name" ] ; then
457 echo >&2 "No current name, please set with 'p name'"
460 echo $name > .patches
/name
462 if [ -z "$status" ] ; then
463 echo -n "Status? " ; read status
464 if [ -z "$status" ] ; then
465 echo >&2 "No current status, please set with 'p status'"
468 echo $status > .patches
/status
470 if [ -s .patches
/notes
]
475 echo "Description..."
477 echo "====Do Not Remove===="
480 ${EDITOR-vi} .patches
/notes
481 mv .patches
/notes .patches
/tmp
482 sed '/^====Do Not Remove====/,$d' .patches
/tmp
> .patches
/notes
487 if [ $cmd = commit
] ; then
488 save_patch applied
"$name"
489 echo Saved as
$new$name
492 save_patch removed
"$name"
493 echo Saved as
$new$name
494 all_files discard_one
496 rm -f .patches
/name .patches
/status .patches
/notes
501 mv .patches
/patch .patches
/last-purge
502 all_files discard_one
503 rm -f .patches
/name .patches
/status .patches
/notes
508 if [ -s .patches
/patch ]
510 echo >&2 Patch
$name already open
- please commit
; exit 1;
514 echo "Available patches are:"
519 then echo >&2 "Usage: p open patchname" ; exit 1
521 if [ " $1" = " last" ]
523 pfile
=`ls -d .patches/applied/[0-9]* | tail -1`
525 pfile
=`echo .patches/applied/*$1*`
528 then echo >&2 "Cannot find unique patch '$1' - found: $pfile"; exit 1
530 # lets see if it applies cleanly
531 if patch -s --fuzz=0 --dry-run -R -f -p0 < "$pfile"
532 then echo Ok
, it seems to apply
533 else echo >&2 "Sorry, that patch doesn't apply" ; exit 1
536 patch --fuzz=0 -R -f -p0 < "$pfile"
538 sed -n -e '2q' -e 's/^Status: *//p' $pfile > .patches
/status
539 base
=${pfile##*/[0-9][0-9][0-9]}
540 [ -s .patches
/name
] ||
echo $base > .patches
/name
541 extract_notes
$pfile >> .patches
/notes
542 mv $pfile .patches
/patch
547 if [ " $1" = " -f" ] ; then
551 if [ -s .patches
/patch ]
553 echo >&2 Patch
$name already open
, please commit
; exit 1;
557 echo "Unapplied patches are:"
563 echo >&2 "Usage: p included patchname"; exit 1
566 last
) pfile
=`ls -d .patches/removed/[0-9]* | tail -1` ;;
567 */* ) echo >&2 "Only local patches can have been included"; exit 1 ;;
568 *) pfile
=`echo .patches/removed/*$1*`
571 then echo >&2 "Cannot find unique patch '$1' - found $pfile"; exit 1
573 echo "Using $pfile..."
575 # make sure patch applies in reverse
576 if patch -s --fuzz=2 -l --dry-run -f -p0 -R < "$pfile"
577 then echo "Yep, that seems to be included"
579 then echo "It doesn't apply reverse-out cleanly, but you asked for it..."
580 else echo >&2 "Sorry, patch cannot be removed"; exit 1
582 mv "$pfile" .patches
/patch
583 name
=${pfile##*/[0-9][0-9][0-9]}
584 save_patch included
$name
585 echo "Moved to $new$name"
588 # there are some patches in .removed that may be included in the current source
589 # we try to backout each one. If it backs out successfully, we move it to
590 # .reviewed and continue, else we abort
591 # Once this has been done often enough, 'reviewed' should be run to
592 # move stuff to 'included' and to revert those patches
594 if [ " $1" = " -f" ] ; then
598 if [ -s .patches
/patch ]
600 echo >&2 Patch
$name already open
, please deal with it
; exit 1;
602 if [ -f .patches
/in-review
]
605 applied
=`ls .patches/applied`
608 echo >&2 Cannot review patches
while any are applied.
615 echo "Pending patches are:"
621 echo >&2 "Usage: p review patchname"; exit 1
624 */* ) echo >&2 "Only local patches can have been included"; exit 1 ;;
625 *) pfile
=`echo .patches/removed/*$1*`
628 then echo >&2 "Cannot find unique patch '$1' - found $pfile"; exit 1
630 echo "Starting from $pfile..."
632 for fl
in .patches
/removed
/*
634 if [ " $fl" = " $pfile" ]; then found
=yes ; fi
635 if [ -n "$found" ]; then
638 lsdiff
--strip=$prefix "$fl" |
grep -v 'file.*changed' |
while read a b
641 if patch -s --fuzz=0 --dry-run -f -p$prefix -R < "$fl"
642 then echo Looks good..
644 then echo "It doesn't backout cleanly, but you asked for it..."
645 cp $fl .patches
/last-backed
646 else echo "Patch won't back out, sorry"
649 patch --fuzz=0 -f -p$prefix -R < "$fl" |
tee .patches
/tmp
650 sed -n -e '2q' -e 's/^Status: *//p' $fl > .patches
/status
652 base
=${base##[0-9][0-9][0-9]}
653 base
=${base##patch-?-}
654 [ -s .patches
/name
] ||
echo $base > .patches
/name
655 extract_notes
$fl >> .patches
/notes
656 rm -f .patches
/wiggled
657 sed -n -e 's/.*saving rejects to file \(.*\).rej/\1/p' .patches
/tmp |
659 do echo Wiggling
$file.rej into place
662 wiggle
--replace --merge $file $file.rej ||
663 echo $file >> .patches
/to-resolve
666 mv $fl .patches
/patch
667 save_patch reviewed
$base
668 if [ -f .patches
/wiggled
]
669 then echo 'Some wiggling was needed. Please review and commit'
678 # all the currently applied patches are patches that have been
679 # reviewed as included.
680 # rip them out and stick them (reversed) into included.
681 if [ ! -f .patches
/in-review
]
683 echo >&2 Not currently reviewing patches
!
690 save_patch included
"$name"
691 echo Saved as
"$new$name"
692 all_files discard_one
693 rm -f .patches
/name .patches
/status .patches
/notes
695 rm .patches
/in-review
698 echo "Applied patches are:"
701 echo "Unapplied patches are:"
706 echo "Applied patches are:"
711 if [ -f .patches
/in-review
]
713 echo >&2 Cannot apply patches
while reviewing other
- use p reviewed
717 if [ " $1" = " -f" ]; then
720 if [ " $1" = " -a" ]; then
725 if [ -s .patches
/patch -a -z "$append" ]
727 echo >&2 Patch
$name already open
- please commit
; exit 1;
731 echo "Unapplied patches are:"
736 then echo >&2 "Usage: p apply patchname"; exit 1
739 last
) pfile
=`ls -d .patches/removed/[0-9]* | tail -1` ; echo last is
"$pfile";;
741 * ) pfile
=`echo .patches/removed/*$1*`
744 then echo >&2 "Cannot find unique patch '$1' - found: $pfile"; exit 1
747 lsdiff
--strip=$prefix "$pfile" |
grep -v 'file.*changed' |
while read a b
750 # lets see if it applies cleanly
751 if patch -s --fuzz=0 --dry-run -f -p$prefix < "$pfile"
752 then echo OK
, it seems to apply
754 then echo "It doesn't apply cleanly, but you asked for it...."
755 echo "Saving original at .patches/last-conflict"
756 cp $pfile .patches
/last-conflict
757 else echo >&2 "Sorry, patch doesn't apply"; exit 1
760 cp $pfile .patches
/last-applied
761 patch --fuzz=0 -f -p$prefix < "$pfile" |
tee .patches
/tmp
762 sed -n -e '2q' -e 's/^Status: *//p' $pfile > .patches
/status
764 base
=${base##[0-9][0-9][0-9]}
765 base
=${base##patch-?-}
766 [ -s .patches
/name
] ||
echo $base > .patches
/name
767 extract_notes
$pfile >> .patches
/notes
769 sed -n -e 's/.*saving rejects to file \(.*\).rej/\1/p' .patches
/tmp |
771 do echo Wiggling
$file.rej into place
773 wiggle
--replace --merge $file $file.rej ||
774 echo $file >> .patches
/to-resolve
779 mv $pfile .patches
/patch
785 mv .patches
/last-applied .patches
/patch
786 save_patch removed
$name
787 echo Restored to
$new$name
789 mv .patches
/patch .patches
/last-purge
790 all_files discard_one
791 rm -f .patches
/name .patches
/status .patches
/notes
794 name
=`date -u +%Y-%m-%d-%H`
795 if [ -d .patches
/dest
]
797 else echo >&2 No destination specified
at .patches
/dest
; exit 1;
799 if [ -d .patches
/dest
/$name ]
801 echo >&2 $name already exists
; exit 1
803 target
=.patches
/dest
/$name
805 if [ -f .patches
/get-version
] ;
806 then .
/.patches
/get-version
> $target/version
808 [ -f .config
] && cp .config
$target
809 cp .patches
/applied
/* $target
811 cp 2> /dev
/null .patches
/removed
/* $target/misc ||
rmdir $target/misc
812 chmod -R a
+rX
$target
813 all_files diff_one_orig
> $target/patch-all-
$name
815 echo Published
at `/bin/pwd`
822 while $0 open last
&& $0 discard
; do : ; done
827 if [ -s .patches
/patch ]
829 echo >&2 Patch
$name already open
- please commit
; exit 1;
833 echo "Unapplied patches are:"
838 then echo >&2 "Usage: p recommit patchname"; exit 1
841 last
) pfile
=`ls -d .patches/removed/[0-9]* | tail -1` ; echo last is
"$pfile";;
843 * ) pfile
=`echo .patches/removed/*$1*`
846 then echo >&2 "Cannot find unique patch '$1' - found: $pfile"; exit 1
848 while [ -s "$pfile" ] &&
849 $0 apply last
&& $0 commit
; do : ; done
854 if [ -s .patches
/patch ]
856 echo >&2 Patch
$name already open
- please commit
; exit 1;
860 echo "Applied patches are:"
865 then echo >&2 "Usage: p decommit patchname"; exit 1
868 last
) pfile
=`ls -d .patches/applied/[0-9]* | tail -1` ; echo last is
"$pfile";;
870 * ) pfile
=`echo .patches/applied/*$1*`
873 then echo >&2 "Cannot find unique patch '$1' - found: $pfile"; exit 1
875 while [ -s "$pfile" ] &&
876 $0 open last
&& $0 discard
; do : ; done
880 # move all applied patches to included, and
881 # copy current to orig and current
883 if [ -s .patches
/patch ]
885 echo >&2 Patch already open
- please commit
; exit 1;
887 for p
in `ls .patches/applied`
889 name
=${p##[0-9][0-9][0-9]}
890 mv .patches
/applied
/$p .patches
/patch
891 save_patch included
$name
905 all_files upgrade_one
908 if [ ! -s .patches
/resolving
]
909 then sort -u .patches
/to-resolve
> .patches
/resolving
; > .patches
/to-resolve
911 if [ ! -s .patches
/resolving
]
912 then echo "Nothing to resolve" ; exit 0;
914 echo "Resolving: " ; cat .patches
/resolving
915 for file in `cat .patches/resolving`
919 wiggle
--replace --merge $file ||
920 echo $file >> .patches
/to-resolve
926 # there must be only one patch. We
927 # git commit, p commit, p rebase
928 if [ -n "`ls .patches/applied`" ]
930 echo 'Cannot export when there are applied patches'
934 if [ -s .patches
/patch ]
937 git add
`cat .patches/files`
938 author
=`grep '^From:' .patches/notes | head -n 1 | sed 's/From: *//'`
940 then git commit
--author="$author" -a -F .patches
/notes
941 else git commit
-a -F .patches
/notes
948 cd .patches
/SOURCE
&& bk pull
953 if [ -s .patches
/patch ]
955 echo >&2 Patch
$name already open
- please commit
; exit 1;
957 p openall
&& p clean
&&
958 (cd .patches
/SOURCE
; bk
export -tpatch -rLATEST, ) > .patches
/imported-patch
&&
959 patch --dry-run -f -p1 < .patches
/imported-patch
&&
960 patch -f -p1 < .patches
/imported-patch
&&
961 ( rm .patches
/imported-patch
; cd .patches
/SOURCE
; bk tag LATEST
)
965 # Convert some applied patches into email messages.
966 # Select patches that start with $1. Look in .patches/cc for who to Cc: to
967 rmdir .patches
/mail 2>/dev
/null
968 if [ -d .patches
/mail ] ; then
969 echo >&2 There is already some email
- run
"email" or
"nomail"
979 headers
="From: $author"
980 if [ -n "$header" ] ; then
981 headers
="$headers$nl$header"
983 elif [ -s .patches
/owner
]; then
984 headers
=`cat .patches/owner`;
986 echo Please add author information to .patches
/config
989 get_conf maintainer
$1
990 if [ -z "$maintainer" -a -s .patches
/maintainer
]
992 maintainer
=`cat .patches/maintainer`
995 if [ -z "$maintainer" ] ; then
996 echo "No maintainer - please add one"
1000 messid
="<`date +'%Y%m%d%H%M%S'`.$$.patches@`uname -n`>"
1003 for patch in .patches
/applied
/???
${1}*
1007 if [ -n "$2" ] && [ $2 -gt $n ] ; then continue; fi
1008 if [ -n "$3" ] && [ $3 -lt $n ] ; then continue; fi
1009 if [ -n "$4" ]; then
1010 case ,$4, in *,$n,* ) ;; *) continue; esac
1012 cnt
=$
(expr $cnt + 1 )
1013 sed -n -e 's/^\(Signed-[Oo]ff-[Bb]y\|Acked-[Bb]y\|Cc\|From\): */Cc: /p' $patch |
grep -v neilb
>> .patches
/.tmp.cc
1022 echo "To: $maintainer"
1024 if [ -n "$cc" ]; then
1027 if [ -n "$tag" ]; then
1030 if [ -s .patches
/.tmp.cc
]
1031 then sort -u .patches
/.tmp.cc
1033 if [ -s .patches
/cc
] ; then
1034 while read word prefix addr
1035 do if [ " $word" = " $1" ] ; then
1043 echo "Subject: [PATCH] ${sprefix}Intro"
1045 echo "Subject: [PATCH 000 of $cnt] ${sprefix}Introduction EXPLAIN PATCH SET HERE"
1047 echo "Message-ID: $messid"
1049 echo PUT COMMENTS HERE
1050 } > .patches
/mail
/000Intro
1053 for patch in .patches
/applied
/???
${1}*
1057 if [ -n "$2" ] && [ $2 -gt $n ] ; then continue; fi
1058 if [ -n "$3" ] && [ $3 -lt $n ] ; then continue; fi
1059 if [ -n "$4" ]; then
1060 case ,$4, in *,$n,* ) ;; *) continue; esac
1062 if [ -f .
/scripts
/checkpatch.pl
]
1063 then perl .
/scripts
/checkpatch.pl
$patch
1068 echo "To: $maintainer"
1069 if [ -n "$cc" ]; then
1072 sed -n -e 's/^\(Signed-[Oo]ff-[Bb]y\|Acked-[Bb]y\|Cc\|From\): */Cc: /p' $patch |
grep -v neilb |
sort -u
1073 if [ -n "$tag" ]; then
1076 if [ -s .patches
/cc
] ; then
1077 while read word prefix addr
1078 do if [ " $word" = " $1" ] ; then
1084 head=`sed -e '/^Status/d' -e '/^$/d' -e q $patch`
1085 zerothis
=$
(expr $this + 1000)
1088 echo "Subject: [PATCH] $sprefix$head"
1090 echo "Subject: [PATCH ${zerothis#1} of $cnt] $sprefix$head"
1092 echo "References: $messid"
1094 if [ $cnt = 1 ] ; then
1095 echo "### Comments for Changeset"
1097 sed -e '1,3d' $patch
1098 } > .patches
/mail
/${patch#.patches/applied/}
1099 this
=$
(expr $this + 1)
1101 if [ -f .patches
/mail
/000Intro
]; then cat .patches
/mail
/* |
sed -n -e 's/^Subject://p' >> .patches
/mail
/000Intro
; fi
1106 echo "Removing .patches/mail directory"
1107 rm -rf .patches
/mail
1111 PATH
=$HOME/bin
:/usr
/lib
:/usr
/sbin
:$PATH
1112 for i
in .patches
/mail
/*
1117 sendmail
-t < $i && rm $i
1123 # test all removed patches to see which ones are clearly included
1124 for p
in .patches
/removed
/*
1126 if patch -R --dry-run -p0 --fuzz=0 -s -f < "$p" > /dev
/null
2>&1
1133 if [ ! -f $helpfile ]
1134 then echo >&2 $helpfile not found
: no
help available
; exit 2;
1136 if [ -z "$1" ] ; then
1138 sed -n -e '/^ /p' -e '/^[^ ]/q' $helpfile
1140 echo "Available help topics are:"
1141 sed -n '/^[^ ]/p' $helpfile |
sort |
column
1144 awk '$0 ~ /^[^ ]/ && printed {doprint=0; printed=0}
1145 doprint && $0 !~ /^[^ ]/ {print; printed=1;}
1146 $0 == "'$1'" {doprint=1; found=1}
1147 END { if (!found) print "No help available for '$1'"; }
1153 echo >&2 "p $cmd - unknown command - try 'p help'"; exit 1;