git-am: --resolved.

After failed patch application, you can manually apply the patch
(this includes resolving the conflicted merge after git-am falls
back to 3-way merge) and run git-update-index on necessary paths
to prepare the index file in a shape a successful patch
application should have produced.  Then re-running git-am --resolved
would record the resulting index file along with the commit log
information taken from the patch e-mail.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2005-11-16 00:19:32 -08:00
parent 92927ed0aa
commit 0c15cc921a

View File

@ -3,16 +3,10 @@
# #
. git-sh-setup || die "Not a git archive" . 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
usage () { usage () {
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>" echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>"
echo >&2 " or, when resuming" echo >&2 " or, when resuming"
echo >&2 " $0 [--skip]" echo >&2 " $0 [--skip | --resolved]"
exit 1; exit 1;
} }
@ -104,7 +98,7 @@ fall_back_3way () {
} }
prec=4 prec=4
dotest=.dotest sign= utf8= keep= skip= interactive= dotest=.dotest sign= utf8= keep= skip= interactive= resolved=
while case "$#" in 0) break;; esac while case "$#" in 0) break;; esac
do do
@ -128,6 +122,9 @@ do
-k|--k|--ke|--kee|--keep) -k|--k|--ke|--kee|--keep)
keep=t; shift ;; keep=t; shift ;;
-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
resolved=t; shift ;;
--sk|--ski|--skip) --sk|--ski|--skip)
skip=t; shift ;; skip=t; shift ;;
@ -140,6 +137,8 @@ do
esac esac
done done
# If the dotest directory exists, but we have finished applying all the
# patches in them, clear it out.
if test -d "$dotest" && if test -d "$dotest" &&
last=$(cat "$dotest/last") && last=$(cat "$dotest/last") &&
next=$(cat "$dotest/next") && next=$(cat "$dotest/next") &&
@ -155,9 +154,9 @@ then
die "previous dotest directory $dotest still exists but mbox given." die "previous dotest directory $dotest still exists but mbox given."
resume=yes resume=yes
else else
# Make sure we are not given --skip # Make sure we are not given --skip nor --resolved
test ",$skip," = ,, || test ",$skip,$resolved," = ,,, ||
die "we are not resuming." die "we are not resuming."
# Start afresh. # Start afresh.
mkdir -p "$dotest" || exit mkdir -p "$dotest" || exit
@ -170,12 +169,24 @@ else
exit 1 exit 1
} }
# -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 "$sign" >"$dotest/sign" echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8" echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep" echo "$keep" >"$dotest/keep"
echo 1 >"$dotest/next" echo 1 >"$dotest/next"
fi 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/utf8")" = t if test "$(cat "$dotest/utf8")" = t
then then
utf8=-u utf8=-u
@ -216,6 +227,15 @@ do
go_next go_next
continue 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 case "$resume" in
'') '')
git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \ git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
@ -263,6 +283,13 @@ do
fi 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 esac
resume= resume=
@ -310,7 +337,21 @@ do
echo "Applying '$SUBJECT'" echo "Applying '$SUBJECT'"
echo echo
git-apply --index "$dotest/patch"; apply_status=$? case "$resolved" in
'')
git-apply --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 if test $apply_status = 1 && test "$threeway" = t
then then
if (fall_back_3way) if (fall_back_3way)