#
# Copyright (c) 2005, 2006 Junio C Hamano
-USAGE='[--signoff] [--dotest=<dir>] [--utf8 | --no-utf8] [--binary] [--3way]
- [--interactive] [--whitespace=<option>] <mbox>...
- or, when resuming [--skip | --resolved]'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-am [options] <mbox>|<Maildir>...
+git-am [options] --resolved
+git-am [options] --skip
+--
+d,dotest= use <dir> and not .dotest
+i,interactive run interactively
+b,binary pass --allo-binary-replacement to git-apply
+3,3way allow fall back on 3way merging if needed
+s,signoff add a Signed-off-by line to the commit message
+u,utf8 recode into utf8 (default)
+k,keep pass -k flag to git-mailinfo
+whitespace= pass it through git-apply
+C= pass it through git-apply
+p= pass it through git-apply
+resolvemsg= override error message when patch failure occurs
+r,resolved to be used after a patch failure
+skip skip the current patch"
+
. git-sh-setup
set_reflog_action am
require_work_tree
stop_here_user_resolve () {
if [ -n "$resolvemsg" ]; then
- echo "$resolvemsg"
+ printf '%s\n' "$resolvemsg"
stop_here $1
fi
cmdline=$(basename $0)
mkdir "$dotest/patch-merge-tmp-dir"
# First see if the patch records the index info that we can use.
- git-apply -z --index-info "$dotest/patch" \
- >"$dotest/patch-merge-index-info" &&
- GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
- git-update-index -z --index-info <"$dotest/patch-merge-index-info" &&
+ git apply --build-fake-ancestor "$dotest/patch-merge-tmp-index" \
+ "$dotest/patch" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
- git-write-tree >"$dotest/patch-merge-base+" ||
- cannot_fallback "Patch does not record usable index information."
+ git write-tree >"$dotest/patch-merge-base+" ||
+ cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
echo Using index info to reconstruct a base tree...
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
- git-apply $binary --cached <"$dotest/patch"
+ git apply $binary --cached <"$dotest/patch"
then
mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
fi
test -f "$dotest/patch-merge-index" &&
- his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git-write-tree) &&
+ his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) &&
orig_tree=$(cat "$dotest/patch-merge-base") &&
rm -fr "$dotest"/patch-merge-* || exit 1
eval GITHEAD_$his_tree='"$SUBJECT"'
export GITHEAD_$his_tree
git-merge-recursive $orig_tree -- HEAD $his_tree || {
- if test -d "$GIT_DIR/rr-cache"
- then
- git-rerere
- fi
+ git rerere
echo Failed to merge in the changes.
exit 1
}
unset GITHEAD_$his_tree
}
+reread_subject () {
+ git stripspace <"$1" | sed -e 1q
+}
+
prec=4
-dotest=.dotest sign= utf8=t keep= skip= interactive= resolved= binary= ws= resolvemsg=
+dotest=.dotest sign= utf8=t keep= skip= interactive= resolved= binary=
+resolvemsg= resume=
+git_apply_opt=
-while case "$#" in 0) break;; esac
+while test $# != 0
do
case "$1" in
- -d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*)
- dotest=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;;
- -d|--d|--do|--dot|--dote|--dotes|--dotest)
- case "$#" in 1) usage ;; esac; shift
- dotest="$1"; shift;;
-
- -i|--i|--in|--int|--inte|--inter|--intera|--interac|--interact|\
- --interacti|--interactiv|--interactive)
- interactive=t; shift ;;
-
- -b|--b|--bi|--bin|--bina|--binar|--binary)
- binary=t; shift ;;
-
- -3|--3|--3w|--3wa|--3way)
- threeway=t; shift ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- sign=t; shift ;;
- -u|--u|--ut|--utf|--utf8)
- utf8=t; shift ;; # this is now default
- --no-u|--no-ut|--no-utf|--no-utf8)
- utf8=; shift ;;
- -k|--k|--ke|--kee|--keep)
- keep=t; shift ;;
-
- -r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
- resolved=t; shift ;;
-
- --sk|--ski|--skip)
- skip=t; shift ;;
-
- --whitespace=*)
- ws=$1; shift ;;
-
- --resolvemsg=*)
- resolvemsg=$(echo "$1" | sed -e "s/^--resolvemsg=//"); shift ;;
-
+ -i|--interactive)
+ interactive=t ;;
+ -b|--binary)
+ binary=t ;;
+ -3|--3way)
+ threeway=t ;;
+ -s|--signoff)
+ sign=t ;;
+ -u|--utf8)
+ utf8=t ;; # this is now default
+ --no-utf8)
+ utf8= ;;
+ -k|--keep)
+ keep=t ;;
+ -r|--resolved)
+ resolved=t ;;
+ --skip)
+ skip=t ;;
+ -d|--dotest)
+ shift; dotest=$1;;
+ --resolvemsg)
+ shift; resolvemsg=$1 ;;
+ --whitespace)
+ git_apply_opt="$git_apply_opt $1=$2"; shift ;;
+ -C|-p)
+ git_apply_opt="$git_apply_opt $1$2"; shift ;;
--)
- shift; break ;;
- -*)
- usage ;;
+ shift; break ;;
*)
- break ;;
+ usage ;;
esac
+ shift
done
# If the dotest directory exists, but we have finished applying all the
# Start afresh.
mkdir -p "$dotest" || exit
- git-mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || {
+ git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || {
rm -fr "$dotest"
exit 1
}
case "$resolved" in
'')
- files=$(git-diff-index --cached --name-only HEAD) || exit
+ files=$(git diff-index --cached --name-only HEAD --) || exit
if [ "$files" ]; then
echo "Dirty index: cannot apply patches (dirty: $files)" >&2
exit 1
this=`cat "$dotest/next"`
if test "$skip" = t
then
- if test -d "$GIT_DIR/rr-cache"
- then
- git-rerere clear
- fi
+ git rerere clear
this=`expr "$this" + 1`
resume=
fi
# by the user, or the user can tell us to do so by --resolved flag.
case "$resume" in
'')
- git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
+ git mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
<"$dotest/$msgnum" >"$dotest/info" ||
stop_here $this
- git-stripspace < "$dotest/msg" > "$dotest/msg-clean"
+
+ # skip pine's internal folder data
+ grep '^Author: Mail System Internal Data$' \
+ <"$dotest"/info >/dev/null &&
+ go_next && continue
+
+ test -s $dotest/patch || {
+ echo "Patch is empty. Was it split wrong?"
+ stop_here $this
+ }
+ git stripspace < "$dotest/msg" > "$dotest/msg-clean"
;;
esac
ADD_SIGNOFF=
fi
{
- echo "$SUBJECT"
+ printf '%s\n' "$SUBJECT"
if test -s "$dotest/msg-clean"
then
echo
case "$resolved$interactive" in
tt)
# This is used only for interactive view option.
- git-diff-index -p --cached HEAD >"$dotest/patch"
+ git diff-index -p --cached HEAD -- >"$dotest/patch"
;;
esac
esac
[yY]*) action=yes ;;
[aA]*) action=yes interactive= ;;
[nN]*) action=skip ;;
- [eE]*) "${VISUAL:-${EDITOR:-vi}}" "$dotest/final-commit"
+ [eE]*) git_editor "$dotest/final-commit"
+ SUBJECT=$(reread_subject "$dotest/final-commit")
action=again ;;
[vV]*) action=again
LESS=-S ${PAGER:-less} "$dotest/patch" ;;
stop_here $this
fi
- echo
- echo "Applying '$SUBJECT'"
- echo
+ printf 'Applying %s\n' "$SUBJECT"
case "$resolved" in
'')
- git-apply $binary --index $ws "$dotest/patch"
+ git apply $git_apply_opt $binary --index "$dotest/patch"
apply_status=$?
;;
t)
# trust what the user has in the index file and the
# working tree.
resolved=
- changed="$(git-diff-index --cached --name-only HEAD)"
- if test '' = "$changed"
- then
+ git diff-index --quiet --cached HEAD -- && {
echo "No changes - did you forget to use 'git add'?"
stop_here_user_resolve $this
- fi
- unmerged=$(git-ls-files -u)
+ }
+ unmerged=$(git ls-files -u)
if test -n "$unmerged"
then
echo "You still have unmerged paths in your index"
stop_here_user_resolve $this
fi
apply_status=0
- if test -d "$GIT_DIR/rr-cache"
- then
- git rerere
- fi
+ git rerere
;;
esac
then
# Applying the patch to an earlier tree and merging the
# result may have produced the same tree as ours.
- changed="$(git-diff-index --cached --name-only HEAD)"
- if test '' = "$changed"
- then
- echo No changes -- Patch already applied.
- go_next
- continue
- fi
+ git diff-index --quiet --cached HEAD -- && {
+ echo No changes -- Patch already applied.
+ go_next
+ continue
+ }
# clear apply_status -- we have successfully merged.
apply_status=0
fi
"$GIT_DIR"/hooks/pre-applypatch || stop_here $this
fi
- tree=$(git-write-tree) &&
- echo Wrote tree $tree &&
- parent=$(git-rev-parse --verify HEAD) &&
- commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") &&
- echo Committed: $commit &&
- git-update-ref -m "$GIT_REFLOG_ACTION: $SUBJECT" HEAD $commit $parent ||
+ tree=$(git write-tree) &&
+ parent=$(git rev-parse --verify HEAD) &&
+ commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") &&
+ git update-ref -m "$GIT_REFLOG_ACTION: $SUBJECT" HEAD $commit $parent ||
stop_here $this
if test -x "$GIT_DIR"/hooks/post-applypatch
go_next
done
+git gc --auto
+
rm -fr "$dotest"