Code

Adjust binary packaging to dest=>DESTDIR change.
[git.git] / git-format-patch-script
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
6 . git-sh-setup-script || die "Not a git archive."
8 usage () {
9     echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [--sign] [-<diff options>...] upstream [ our-head ]
11 Prepare each commit with its patch since our-head forked from upstream,
12 one file per patch, for e-mail submission.  Each output file is
13 numbered sequentially from 1, and uses the first line of the commit
14 message (massaged for pathname safety) as the filename.
16 When -o is specified, output files are created in that directory; otherwise in
17 the current working directory.
19 When -n is specified, instead of "[PATCH] Subject", the first line is formatted
20 as "[PATCH N/M] Subject", unless you have only one patch.
22 When --mbox is specified, the output is formatted to resemble
23 UNIX mailbox format, and can be concatenated together for processing
24 with applymbox.
25 '
26     exit 1
27 }
29 diff_opts=
30 IFS='
31 '
32 LF='
33 '
35 outdir=./
36 while case "$#" in 0) break;; esac
37 do
38     case "$1" in
39     -a|--a|--au|--aut|--auth|--autho|--author)
40     author=t ;;
41     -c|--c|--ch|--che|--chec|--check)
42     check=t ;;
43     -d|--d|--da|--dat|--date)
44     date=t ;;
45     -m|--m|--mb|--mbo|--mbox)
46     date=t author=t mbox=t ;;
47     -n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered)
48     numbered=t ;;
49     -s|--s|--si|--sig|--sign)
50     signoff=t ;;
51     -o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\
52     --output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\
53     --output-direc=*|--output-direct=*|--output-directo=*|\
54     --output-director=*|--output-directory=*)
55     outdir=`expr "$1" : '-[^=]*=\(.*\)'` ;;
56     -o|--o|--ou|--out|--outp|--outpu|--output|--output-|--output-d|\
57     --output-di|--output-dir|--output-dire|--output-direc|--output-direct|\
58     --output-directo|--output-director|--output-directory)
59     case "$#" in 1) usage ;; esac; shift
60     outdir="$1" ;;
61     -*) diff_opts="$diff_opts$LF$1" ;;
62     *) break ;;
63     esac
64     shift
65 done
67 revpair=
68 case "$#" in
69 2)
70     revpair="$1..$2" ;;
71 1)
72     case "$1" in
73     *..*)
74         revpair="$1";;
75     *)
76         revpair="$1..HEAD";;
77     esac ;;
78 *)
79     usage ;;
80 esac
82 me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`
84 case "$outdir" in
85 */) ;;
86 *) outdir="$outdir/" ;;
87 esac
88 test -d "$outdir" || mkdir -p "$outdir" || exit
90 tmp=.tmp-series$$
91 trap 'rm -f $tmp-*' 0 1 2 3 15
93 series=$tmp-series
94 commsg=$tmp-commsg
95 filelist=$tmp-files
97 titleScript='
98         /./d
99         /^$/n
100         s/^\[PATCH[^]]*\] *//
101         s/[^-a-z.A-Z_0-9]/-/g
102         s/\.\.\.*/\./g
103         s/\.*$//
104         s/--*/-/g
105         s/^-//
106         s/-$//
107         s/$/./
108         p
109         q
112 whosepatchScript='
113 /^author /{
114         s/author \(.*>\) \(.*\)$/au='\''\1'\'' ad='\''\2'\''/p
115         q
116 }'
118 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
119 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
120 stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
122 git-rev-list --no-merges --merge-order \
123         $(git-rev-parse --revs-only "$revpair") >$series
124 total=`wc -l <$series | tr -dc "[0-9]"`
125 i=$total
126 while read commit
127 do
128     git-cat-file commit "$commit" | git-stripspace >$commsg
129     title=`sed -ne "$titleScript" <$commsg`
130     case "$numbered" in
131     '') num= ;;
132     *)
133         case $total in
134         1) num= ;;
135         *) num=' '`printf "%d/%d" $i $total` ;;
136         esac
137     esac
139     file=`printf '%04d-%stxt' $i "$title"`
140     i=`expr "$i" - 1`
141     echo >&2 "* $file"
142     {
143         mailScript='
144         /./d
145         /^$/n
146         s|^\[PATCH[^]]*\] *||'
148         case "$mbox" in
149         t)
150             echo 'From nobody Mon Sep 17 00:00:00 2001' ;# UNIX "From" line
151             mailScript="$mailScript"'
152             s|^|Subject: [PATCH'"$num"'] |'
153             ;;
154         *)
155             mailScript="$mailScript"'
156             s|^|[PATCH'"$num"'] |'
157             ;;
158         esac
160         eval "$(sed -ne "$whosepatchScript" $commsg)"
161         test "$author,$au" = ",$me" || {
162                 mailScript="$mailScript"'
163         a\
164 From: '"$au"
165         }
166         test "$date,$au" = ",$me" || {
167                 mailScript="$mailScript"'
168         a\
169 Date: '"$ad"
170         }
172         mailScript="$mailScript"'
173         : body
174         p
175         n
176         b body'
178         sed -ne "$mailScript" <$commsg
180         test "$signoff" = "t" && {
181                 offsigner=`git-var GIT_COMMITTER_IDENT | sed -e 's/>.*/>/'`
182                 echo
183                 echo "Signed-off-by: $offsigner"
184                 echo
185         }
187         echo '---'
188         echo
189         git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
190         echo
191         git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead"
193         case "$mbox" in
194         t)
195                 echo
196                 ;;
197         esac
198     } >"$outdir$file"
199     case "$check" in
200     t)
201         # This is slightly modified from Andrew Morton's Perfect Patch.
202         # Lines you introduce should not have trailing whitespace.
203         # Also check for an indentation that has SP before a TAB.
204         grep -n '^+\([  ]*      .*\|.*[         ]\)$' "$outdir$file"
206         : do not exit with non-zero because we saw no problem in the last one.
207     esac
208 done <$series