X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;ds=inline;f=git-am.sh;h=660b3a4b6113f58ff33fd2db2cdeac25ce32f95d;hb=650e4be59b9f385f56e5829d97d09e8440f174b8;hp=115ebaddf595f49059208ac890308b6ebe01aa42;hpb=1301c6eb412e7c5511b952a12e42c70ad56f028b;p=git.git
diff --git a/git-am.sh b/git-am.sh
index 115ebadd..660b3a4b 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -1,18 +1,12 @@
#!/bin/sh
#
#
-. git-sh-setup || die "Not a git archive"
-
-files=$(git-diff-index --cached --name-only HEAD) || exit
-if [ "$files" ]; then
- echo "Dirty index: cannot apply patches (dirty: $files)" >&2
- exit 1
-fi
+. git-sh-setup
usage () {
- echo >&2 "usage: $0 [--signoff] [--dotest=
] [--utf8] [--3way] "
+ echo >&2 "usage: $0 [--signoff] [--dotest=] [--utf8] [--binary] [--3way] "
echo >&2 " or, when resuming"
- echo >&2 " $0 [--skip]"
+ echo >&2 " $0 [--skip | --resolved]"
exit 1;
}
@@ -46,7 +40,7 @@ fall_back_3way () {
cd "$dotest/patch-merge-tmp-dir" &&
GIT_INDEX_FILE="../patch-merge-tmp-index" \
GIT_OBJECT_DIRECTORY="$O_OBJECT" \
- git-apply --index <../patch
+ git-apply $binary --index <../patch
)
then
echo Using index info to reconstruct a base tree...
@@ -77,7 +71,7 @@ fall_back_3way () {
GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
git-read-tree "$base" &&
- git-apply --index &&
+ git-apply $binary --index &&
mv ../patch-merge-tmp-index ../patch-merge-index &&
echo "$base" >../patch-merge-base
) <"$dotest/patch" 2>/dev/null && break
@@ -104,7 +98,7 @@ fall_back_3way () {
}
prec=4
-dotest=.dotest sign= utf8= keep= skip= interactive=
+dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary=
while case "$#" in 0) break;; esac
do
@@ -119,6 +113,9 @@ do
--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)
@@ -128,6 +125,9 @@ do
-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 ;;
@@ -140,6 +140,8 @@ do
esac
done
+# If the dotest directory exists, but we have finished applying all the
+# patches in them, clear it out.
if test -d "$dotest" &&
last=$(cat "$dotest/last") &&
next=$(cat "$dotest/next") &&
@@ -155,9 +157,9 @@ then
die "previous dotest directory $dotest still exists but mbox given."
resume=yes
else
- # Make sure we are not given --skip
- test ",$skip," = ,, ||
- die "we are not resuming."
+ # Make sure we are not given --skip nor --resolved
+ test ",$skip,$resolved," = ,,, ||
+ die "we are not resuming."
# Start afresh.
mkdir -p "$dotest" || exit
@@ -170,12 +172,29 @@ else
exit 1
}
+ # -b, -s, -u and -k flags are kept for the resuming session after
+ # a patch failure.
+ # -3 and -i can and must be given when resuming.
+ echo "$binary" >"$dotest/binary"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
echo 1 >"$dotest/next"
fi
+case "$resolved" in
+'')
+ files=$(git-diff-index --cached --name-only HEAD) || exit
+ if [ "$files" ]; then
+ echo "Dirty index: cannot apply patches (dirty: $files)" >&2
+ exit 1
+ fi
+esac
+
+if test "$(cat "$dotest/binary")" = t
+then
+ binary=--allow-binary-replacement
+fi
if test "$(cat "$dotest/utf8")" = t
then
utf8=-u
@@ -216,6 +235,15 @@ do
go_next
continue
}
+
+ # If we are not resuming, parse and extract the patch information
+ # into separate files:
+ # - info records the authorship and title
+ # - msg is the rest of commit log message
+ # - patch is the patch body.
+ #
+ # When we are resuming, these files are either already prepared
+ # 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" \
@@ -224,29 +252,33 @@ do
git-stripspace < "$dotest/msg" > "$dotest/msg-clean"
;;
esac
- resume=
GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"
- SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+ SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
case "$keep_subject" in -k) SUBJECT="[PATCH] $SUBJECT" ;; esac
- if test '' != "$SIGNOFF"
- then
+
+ case "$resume" in
+ '')
+ if test '' != "$SIGNOFF"
+ then
LAST_SIGNED_OFF_BY=`
- sed -ne '/^Signed-off-by: /p' "$dotest/msg-clean" |
- tail -n 1
+ sed -ne '/^Signed-off-by: /p' \
+ "$dotest/msg-clean" |
+ tail -n 1
`
- ADD_SIGNOFF=$(test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
+ ADD_SIGNOFF=`
+ test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
test '' = "$LAST_SIGNED_OFF_BY" && echo
echo "$SIGNOFF"
- })
- else
+ }`
+ else
ADD_SIGNOFF=
- fi
- {
+ fi
+ {
echo "$SUBJECT"
if test -s "$dotest/msg-clean"
then
@@ -257,8 +289,18 @@ do
then
echo "$ADD_SIGNOFF"
fi
- } >"$dotest/final-commit"
+ } >"$dotest/final-commit"
+ ;;
+ *)
+ case "$resolved,$interactive" in
+ tt)
+ # This is used only for interactive view option.
+ git-diff-index -p --cached HEAD >"$dotest/patch"
+ ;;
+ esac
+ esac
+ resume=
if test "$interactive" = t
then
test -t 0 ||
@@ -303,7 +345,21 @@ do
echo "Applying '$SUBJECT'"
echo
- git-apply --index "$dotest/patch"; apply_status=$?
+ case "$resolved" in
+ '')
+ git-apply $binary --index "$dotest/patch"
+ apply_status=$?
+ ;;
+ t)
+ # Resolved means the user did all the hard work, and
+ # we do not have to do any patch application. Just
+ # trust what the user has in the index file and the
+ # working tree.
+ resolved=
+ apply_status=0
+ ;;
+ esac
+
if test $apply_status = 1 && test "$threeway" = t
then
if (fall_back_3way)