44d2eb51b1
- avoid duplicating [PATCH] in the commit message body if the original commit has it already (happens for commits done from mails via applymbox). - check if the commit author is different from the one who is running the script, and emit an appropriate "From:" and "Date: " lines to the output. - with '--date', emit "Date: " line to preserve the original author date even for the user's own commit. - teach mailinfo to grok not just "From: " but "Date: ". The patch e-mail output by format-patch starts with the first line from the original commit message, prefixed with [PATCH], and optionally a From: line if you are reformatting a patch obtained from somebody else, a Date: line from the original commit if (1) --date is specified or (2) for somebody else's patch, and the rest of the commit message body. Expected use of this is to move the title line from the commit to Subject: when sending it via an e-mail, and leave the From: and the Date: lines as the first lines of your message. The mailinfo command has been changed to read Date: (in addition to From: it already understands) and do sensible things when running applymbox. Signed-off-by: Junio C Hamano <junkio@cox.net> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
152 lines
3.2 KiB
Bash
Executable File
152 lines
3.2 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Copyright (c) 2005 Junio C Hamano
|
|
#
|
|
|
|
usage () {
|
|
echo >&2 "usage: $0"' [-n] [-o dir] [-<diff options>...] upstream [ our-head ]
|
|
|
|
Prepare each commit with its patch since our-head forked from upstream,
|
|
one file per patch, for e-mail submission. Each output file is
|
|
numbered sequentially from 1, and uses the first line of the commit
|
|
message (massaged for pathname safety) as the filename.
|
|
|
|
When -o is specified, output files are created in that directory; otherwise in
|
|
the current working directory.
|
|
|
|
When -n is specified, instead of "[PATCH] Subject", the first line is formatted
|
|
as "[PATCH N/M] Subject", unless you have only one patch.
|
|
'
|
|
exit 1
|
|
}
|
|
|
|
diff_opts=
|
|
IFS='
|
|
'
|
|
LF='
|
|
'
|
|
outdir=./
|
|
|
|
while case "$#" in 0) break;; esac
|
|
do
|
|
case "$1" in
|
|
-d|--d|--da|--dat|--date)
|
|
date=t ;;
|
|
-n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered)
|
|
numbered=t ;;
|
|
-o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\
|
|
--output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\
|
|
--output-direc=*|--output-direct=*|--output-directo=*|\
|
|
--output-director=*|--output-directory=*)
|
|
outdir=`expr "$1" : '-[^=]*=\(.*\)'` ;;
|
|
-o|--o|--ou|--out|--outp|--outpu|--output|--output-|--output-d|\
|
|
--output-di|--output-dir|--output-dire|--output-direc|--output-direct|\
|
|
--output-directo|--output-director|--output-directory)
|
|
case "$#" in 1) usage ;; esac; shift
|
|
outdir="$1" ;;
|
|
-*) diff_opts="$diff_opts$LF$1" ;;
|
|
*) break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
case "$#" in
|
|
2) linus="$1" junio="$2" ;;
|
|
1) linus="$1" junio=HEAD ;;
|
|
*) usage ;;
|
|
esac
|
|
junio=`git-rev-parse --verify "$junio"`
|
|
linus=`git-rev-parse --verify "$linus"`
|
|
|
|
me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`
|
|
|
|
case "$outdir" in
|
|
*/) ;;
|
|
*) outdir="$outdir/" ;;
|
|
esac
|
|
test -d "$outdir" || mkdir -p "$outdir" || exit
|
|
|
|
tmp=.tmp-series$$
|
|
trap 'rm -f $tmp-*' 0 1 2 3 15
|
|
|
|
series=$tmp-series
|
|
commsg=$tmp-commsg
|
|
|
|
titleScript='
|
|
/./d
|
|
/^$/n
|
|
s/^\[PATCH[^]]*\] *//
|
|
s/[^-a-z.A-Z_0-9]/-/g
|
|
s/\.\.\.*/\./g
|
|
s/\.*$//
|
|
s/--*/-/g
|
|
s/^-//
|
|
s/-$//
|
|
s/$/./
|
|
p
|
|
q
|
|
'
|
|
|
|
whosepatchScript='
|
|
/^author /{
|
|
s/author \(.*>\) \(.*\)$/au='\''\1'\'' ad='\''\2'\''/p
|
|
q
|
|
}'
|
|
|
|
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
|
|
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
|
|
stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
|
|
|
|
git-rev-list --merge-order "$junio" "^$linus" >$series
|
|
total=`wc -l <$series`
|
|
i=$total
|
|
while read commit
|
|
do
|
|
git-cat-file commit "$commit" | git-stripspace >$commsg
|
|
title=`sed -ne "$titleScript" <$commsg`
|
|
case "$numbered" in
|
|
'') num= ;;
|
|
*)
|
|
case $total in
|
|
1) num= ;;
|
|
*) num=' '`printf "%d/%d" $i $total` ;;
|
|
esac
|
|
esac
|
|
|
|
file=`printf '%04d-%stxt' $i "$title"`
|
|
i=`expr "$i" - 1`
|
|
echo "$file"
|
|
{
|
|
mailScript='
|
|
/./d
|
|
/^$/n
|
|
s|^\[PATCH[^]]*\] *||
|
|
s|^|[PATCH'"$num"'] |'
|
|
|
|
eval "$(sed -ne "$whosepatchScript" $commsg)"
|
|
test "$au" = "$me" || {
|
|
mailScript="$mailScript"'
|
|
a\
|
|
From: '"$au"
|
|
}
|
|
test "$date,$au" = ",$me" || {
|
|
mailScript="$mailScript"'
|
|
a\
|
|
Date: '"$ad"
|
|
}
|
|
|
|
mailScript="$mailScript"'
|
|
: body
|
|
p
|
|
n
|
|
b body'
|
|
|
|
sed -ne "$mailScript" <$commsg
|
|
echo '---'
|
|
echo
|
|
git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
|
|
echo
|
|
git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead"
|
|
} >"$outdir$file"
|
|
done <$series
|