Write .editmsg in GIT_DIR to avoid being in git-status.
[git.git] / git-format-patch.sh
index cfba1de..09b635e 100755 (executable)
@@ -6,7 +6,7 @@
 . git-sh-setup || die "Not a git archive."
 
 usage () {
-    echo >&2 "usage: $0"' [-n] [-o dir] [--keep-subject] [--mbox] [--check] [--signoff] [-<diff options>...] upstream [ our-head ]
+    echo >&2 "usage: $0"' [-n] [-o dir | --stdout] [--keep-subject] [--mbox] [--check] [--signoff] [-<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
@@ -27,8 +27,6 @@ with applymbox.
 }
 
 diff_opts=
-IFS='
-'
 LF='
 '
 
@@ -51,6 +49,8 @@ do
     numbered=t ;;
     -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
     signoff=t ;;
+    --st|--std|--stdo|--stdou|--stdout)
+    stdout=t mbox=t date=t author=t ;;
     -o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\
     --output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\
     --output-direc=*|--output-direct=*|--output-directo=*|\
@@ -61,7 +61,10 @@ do
     --output-directo|--output-director|--output-directory)
     case "$#" in 1) usage ;; esac; shift
     outdir="$1" ;;
-    -*)        diff_opts="$diff_opts$LF$1" ;;
+    -*' '* | -*"$LF"* | -*'    '*)
+       # Ignore diff option that has whitespace for now.
+       ;;
+    -*)        diff_opts="$diff_opts$1 " ;;
     *) break ;;
     esac
     shift
@@ -72,16 +75,20 @@ tt)
        die '--keep-subject and --numbered are incompatible.' ;;
 esac
 
-revpair=
+rev1= rev2=
 case "$#" in
 2)
-    revpair="$1..$2" ;;
+    rev1="$1" rev2="$2" ;;
 1)
     case "$1" in
     *..*)
-       revpair="$1";;
+       rev1=`expr "$1" : '\(.*\)\.\.'`
+       rev2=`expr "$1" : '.*\.\.\(.*\)'`
+       ;;
     *)
-       revpair="$1..HEAD";;
+        rev1="$1"
+       rev2="HEAD"
+       ;;
     esac ;;
 *)
     usage ;;
@@ -123,31 +130,20 @@ whosepatchScript='
        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 --no-merges --merge-order \
-       $(git-rev-parse --revs-only "$revpair") >$series
-total=`wc -l <$series | tr -dc "[0-9]"`
-i=$total
-while read commit
+git-cherry -v "$rev1" "$rev2" |
+while read sign rev comment
 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` ;;
+       case "$sign" in
+       '-')
+               echo >&2 "Merged already: $comment"
+               ;;
+       *)
+               echo $rev
+               ;;
        esac
-    esac
+done >$series
 
-    file=`printf '%04d-%stxt' $i "$title"`
-    i=`expr "$i" - 1`
-    echo "* $file"
-    {
+process_one () {
        mailScript='
        /./d
        /^$/n'
@@ -166,6 +162,7 @@ do
            echo 'From nobody Mon Sep 17 00:00:00 2001' ;# UNIX "From" line
            ;;
        esac
+
        eval "$(sed -ne "$whosepatchScript" $commsg)"
        test "$author,$au" = ",$me" || {
                mailScript="$mailScript"'
@@ -184,7 +181,9 @@ Date: '"$ad"
        n
        b body'
 
-       sed -ne "$mailScript" <$commsg
+       (cat $commsg ; echo; echo) |
+       sed -ne "$mailScript" |
+       git-stripspace
 
        test "$signoff" = "t" && {
                offsigner=`git-var GIT_COMMITTER_IDENT | sed -e 's/>.*/>/'`
@@ -200,21 +199,49 @@ Date: '"$ad"
        echo
        git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
        echo
-       git-diff-tree -p $diff_opts "$commit" | sed -e "$stripCommitHead"
+       git-cat-file commit "$commit^" | sed -e 's/^tree /applies-to: /' -e q
+       git-diff-tree -p $diff_opts "$commit"
+       echo "---"
+       echo "@@GIT_VERSION@@"
 
        case "$mbox" in
        t)
                echo
                ;;
        esac
-    } >"$outdir$file"
-    case "$check" in
-    t)
-       # This is slightly modified from Andrew Morton's Perfect Patch.
-       # Lines you introduce should not have trailing whitespace.
-       # Also check for an indentation that has SP before a TAB.
-        grep -n '^+\([         ]*      .*\|.*[         ]\)$' "$outdir$file"
-
-       : do not exit with non-zero because we saw no problem in the last one.
+}
+
+total=`wc -l <$series | tr -dc "[0-9]"`
+i=1
+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"`
+    if test '' = "$stdout"
+    then
+           echo "* $file"
+           process_one >"$outdir$file"
+           if test t = "$check"
+           then
+               # This is slightly modified from Andrew Morton's Perfect Patch.
+               # Lines you introduce should not have trailing whitespace.
+               # Also check for an indentation that has SP before a TAB.
+               grep -n '^+\([  ]*      .*\|.*[         ]\)$' "$outdir$file"
+               :
+           fi
+    else
+           echo >&2 "* $file"
+           process_one
+    fi
+    i=`expr "$i" + 1`
 done <$series