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