]>
Commit | Line | Data |
---|---|---|
0acfc972 JH |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2005 Junio C Hamano | |
4 | # | |
5 | ||
4282c4fb JH |
6 | . git-sh-setup-script || die "Not a git archive." |
7 | ||
0acfc972 | 8 | usage () { |
d9ac9df4 | 9 | echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [--signoff] [-<diff options>...] upstream [ our-head ] |
0acfc972 JH |
10 | |
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. | |
15 | ||
16 | When -o is specified, output files are created in that directory; otherwise in | |
17 | the current working directory. | |
18 | ||
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. | |
5c2c972f JH |
21 | |
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. | |
0acfc972 JH |
25 | ' |
26 | exit 1 | |
27 | } | |
28 | ||
29 | diff_opts= | |
30 | IFS=' | |
31 | ' | |
32 | LF=' | |
33 | ' | |
0acfc972 | 34 | |
5c2c972f | 35 | outdir=./ |
0acfc972 JH |
36 | while case "$#" in 0) break;; esac |
37 | do | |
38 | case "$1" in | |
5c2c972f JH |
39 | -a|--a|--au|--aut|--auth|--autho|--author) |
40 | author=t ;; | |
41 | -c|--c|--ch|--che|--chec|--check) | |
42 | check=t ;; | |
44d2eb51 JH |
43 | -d|--d|--da|--dat|--date) |
44 | date=t ;; | |
5c2c972f JH |
45 | -m|--m|--mb|--mbo|--mbox) |
46 | date=t author=t mbox=t ;; | |
0acfc972 JH |
47 | -n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered) |
48 | numbered=t ;; | |
d9ac9df4 | 49 | -s|--s|--si|--sig|--sign|--signo|--signof|--signoff) |
b097584b | 50 | signoff=t ;; |
0acfc972 JH |
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 | |
66 | ||
4282c4fb | 67 | revpair= |
0acfc972 | 68 | case "$#" in |
4282c4fb JH |
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 ;; | |
0acfc972 JH |
80 | esac |
81 | ||
44d2eb51 JH |
82 | me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'` |
83 | ||
0acfc972 JH |
84 | case "$outdir" in |
85 | */) ;; | |
86 | *) outdir="$outdir/" ;; | |
87 | esac | |
88 | test -d "$outdir" || mkdir -p "$outdir" || exit | |
89 | ||
90 | tmp=.tmp-series$$ | |
91 | trap 'rm -f $tmp-*' 0 1 2 3 15 | |
92 | ||
93 | series=$tmp-series | |
44d2eb51 | 94 | commsg=$tmp-commsg |
5c2c972f | 95 | filelist=$tmp-files |
0acfc972 JH |
96 | |
97 | titleScript=' | |
1855c044 JH |
98 | /./d |
99 | /^$/n | |
100 | s/^\[PATCH[^]]*\] *// | |
0acfc972 JH |
101 | s/[^-a-z.A-Z_0-9]/-/g |
102 | s/\.\.\.*/\./g | |
103 | s/\.*$// | |
104 | s/--*/-/g | |
105 | s/^-// | |
106 | s/-$// | |
107 | s/$/./ | |
1855c044 | 108 | p |
0acfc972 JH |
109 | q |
110 | ' | |
111 | ||
44d2eb51 JH |
112 | whosepatchScript=' |
113 | /^author /{ | |
114 | s/author \(.*>\) \(.*\)$/au='\''\1'\'' ad='\''\2'\''/p | |
115 | q | |
116 | }' | |
117 | ||
0acfc972 JH |
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' | |
121 | ||
c35a7b8d JH |
122 | git-rev-list --no-merges --merge-order \ |
123 | $(git-rev-parse --revs-only "$revpair") >$series | |
9b75e9fa | 124 | total=`wc -l <$series | tr -dc "[0-9]"` |
0acfc972 JH |
125 | i=$total |
126 | while read commit | |
127 | do | |
44d2eb51 JH |
128 | git-cat-file commit "$commit" | git-stripspace >$commsg |
129 | title=`sed -ne "$titleScript" <$commsg` | |
0acfc972 JH |
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 | |
44d2eb51 | 138 | |
0acfc972 JH |
139 | file=`printf '%04d-%stxt' $i "$title"` |
140 | i=`expr "$i" - 1` | |
5c2c972f | 141 | echo >&2 "* $file" |
0acfc972 JH |
142 | { |
143 | mailScript=' | |
1855c044 JH |
144 | /./d |
145 | /^$/n | |
5c2c972f JH |
146 | s|^\[PATCH[^]]*\] *||' |
147 | ||
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 | |
44d2eb51 JH |
159 | |
160 | eval "$(sed -ne "$whosepatchScript" $commsg)" | |
5c2c972f | 161 | test "$author,$au" = ",$me" || { |
44d2eb51 JH |
162 | mailScript="$mailScript"' |
163 | a\ | |
164 | From: '"$au" | |
165 | } | |
166 | test "$date,$au" = ",$me" || { | |
167 | mailScript="$mailScript"' | |
168 | a\ | |
169 | Date: '"$ad" | |
170 | } | |
171 | ||
172 | mailScript="$mailScript"' | |
0acfc972 JH |
173 | : body |
174 | p | |
175 | n | |
176 | b body' | |
177 | ||
44d2eb51 | 178 | sed -ne "$mailScript" <$commsg |
b097584b JS |
179 | |
180 | test "$signoff" = "t" && { | |
181 | offsigner=`git-var GIT_COMMITTER_IDENT | sed -e 's/>.*/>/'` | |
d9ac9df4 JS |
182 | line="Signed-off-by: $offsigner" |
183 | grep -q "^$line\$" $commsg || { | |
184 | echo | |
185 | echo "$line" | |
186 | echo | |
187 | } | |
b097584b JS |
188 | } |
189 | ||
0acfc972 JH |
190 | echo '---' |
191 | echo | |
192 | git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary | |
193 | echo | |
194 | git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead" | |
5c2c972f JH |
195 | |
196 | case "$mbox" in | |
197 | t) | |
198 | echo | |
199 | ;; | |
200 | esac | |
0acfc972 | 201 | } >"$outdir$file" |
5c2c972f JH |
202 | case "$check" in |
203 | t) | |
204 | # This is slightly modified from Andrew Morton's Perfect Patch. | |
205 | # Lines you introduce should not have trailing whitespace. | |
206 | # Also check for an indentation that has SP before a TAB. | |
207 | grep -n '^+\([ ]* .*\|.*[ ]\)$' "$outdir$file" | |
208 | ||
209 | : do not exit with non-zero because we saw no problem in the last one. | |
210 | esac | |
0acfc972 | 211 | done <$series |