]> git.ipfire.org Git - thirdparty/git.git/blob - git-format-patch-script
[PATCH] git-format-patch: Prepare patches for e-mail submission.
[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] [-<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 exit 1
21 }
22
23 diff_opts=
24 IFS='
25 '
26 LF='
27 '
28 outdir=./
29
30 while case "$#" in 0) break;; esac
31 do
32 case "$1" in
33 -n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered)
34 numbered=t ;;
35 -o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\
36 --output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\
37 --output-direc=*|--output-direct=*|--output-directo=*|\
38 --output-director=*|--output-directory=*)
39 outdir=`expr "$1" : '-[^=]*=\(.*\)'` ;;
40 -o|--o|--ou|--out|--outp|--outpu|--output|--output-|--output-d|\
41 --output-di|--output-dir|--output-dire|--output-direc|--output-direct|\
42 --output-directo|--output-director|--output-directory)
43 case "$#" in 1) usage ;; esac; shift
44 outdir="$1" ;;
45 -*) diff_opts="$diff_opts$LF$1" ;;
46 *) break ;;
47 esac
48 shift
49 done
50
51 case "$#" in
52 2) linus="$1" junio="$2" ;;
53 1) linus="$1" junio=HEAD ;;
54 *) usage ;;
55 esac
56
57 case "$outdir" in
58 */) ;;
59 *) outdir="$outdir/" ;;
60 esac
61 test -d "$outdir" || mkdir -p "$outdir" || exit
62
63 tmp=.tmp-series$$
64 trap 'rm -f $tmp-*' 0 1 2 3 15
65
66 series=$tmp-series
67
68 titleScript='
69 1,/^$/d
70 : loop
71 /^$/b loop
72 s/[^-a-z.A-Z_0-9]/-/g
73 s/\.\.\.*/\./g
74 s/\.*$//
75 s/--*/-/g
76 s/^-//
77 s/-$//
78 s/$/./
79 q
80 '
81
82 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
83 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
84 stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
85
86 git-rev-list --merge-order "$junio" "^$linus" >$series
87 total=`wc -l <$series`
88 i=$total
89 while read commit
90 do
91 title=`git-cat-file commit "$commit" | sed -e "$titleScript"`
92 case "$numbered" in
93 '') num= ;;
94 *)
95 case $total in
96 1) num= ;;
97 *) num=' '`printf "%d/%d" $i $total` ;;
98 esac
99 esac
100 file=`printf '%04d-%stxt' $i "$title"`
101 i=`expr "$i" - 1`
102 echo "$file"
103 {
104 mailScript='
105 1,/^$/d
106 : loop
107 /^$/b loop
108 s|^|[PATCH'"$num"'] |
109 : body
110 p
111 n
112 b body'
113
114 git-cat-file commit "$commit" | sed -ne "$mailScript"
115 echo '---'
116 echo
117 git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
118 echo
119 git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead"
120 } >"$outdir$file"
121 done <$series