[PATCH] Update git-tag-script to create the .git/refs/tags if it does not already...
[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 junio=`git-rev-parse --verify "$junio"`
57 linus=`git-rev-parse --verify "$linus"`
58
59 case "$outdir" in
60 */) ;;
61 *) outdir="$outdir/" ;;
62 esac
63 test -d "$outdir" || mkdir -p "$outdir" || exit
64
65 tmp=.tmp-series$$
66 trap 'rm -f $tmp-*' 0 1 2 3 15
67
68 series=$tmp-series
69
70 titleScript='
71         /./d
72         /^$/n
73         s/^\[PATCH[^]]*\] *//
74         s/[^-a-z.A-Z_0-9]/-/g
75         s/\.\.\.*/\./g
76         s/\.*$//
77         s/--*/-/g
78         s/^-//
79         s/-$//
80         s/$/./
81         p
82         q
83 '
84
85 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
86 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
87 stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
88
89 git-rev-list --merge-order "$junio" "^$linus" >$series
90 total=`wc -l <$series`
91 i=$total
92 while read commit
93 do
94     title=`git-cat-file commit "$commit" |
95     git-stripspace |
96     sed -ne "$titleScript"`
97     case "$numbered" in
98     '') num= ;;
99     *)
100         case $total in
101         1) num= ;;
102         *) num=' '`printf "%d/%d" $i $total` ;;
103         esac
104     esac
105     file=`printf '%04d-%stxt' $i "$title"`
106     i=`expr "$i" - 1`
107     echo "$file"
108     {
109         mailScript='
110         /./d
111         /^$/n
112         s|^|[PATCH'"$num"'] |
113         : body
114         p
115         n
116         b body'
117
118         git-cat-file commit "$commit" |
119         git-stripspace |
120         sed -ne "$mailScript"
121         echo '---'
122         echo
123         git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
124         echo
125         git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead"
126     } >"$outdir$file"
127 done <$series