Skip to content

Commit 0c15cc9

Browse files
author
Junio C Hamano
committed
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>
1 parent 92927ed commit 0c15cc9

File tree

1 file changed

+53
-12
lines changed

1 file changed

+53
-12
lines changed

git-am.sh

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,10 @@
33
#
44
. git-sh-setup || die "Not a git archive"
55

6-
files=$(git-diff-index --cached --name-only HEAD) || exit
7-
if [ "$files" ]; then
8-
echo "Dirty index: cannot apply patches (dirty: $files)" >&2
9-
exit 1
10-
fi
11-
126
usage () {
137
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>"
148
echo >&2 " or, when resuming"
15-
echo >&2 " $0 [--skip]"
9+
echo >&2 " $0 [--skip | --resolved]"
1610
exit 1;
1711
}
1812

@@ -104,7 +98,7 @@ fall_back_3way () {
10498
}
10599

106100
prec=4
107-
dotest=.dotest sign= utf8= keep= skip= interactive=
101+
dotest=.dotest sign= utf8= keep= skip= interactive= resolved=
108102

109103
while case "$#" in 0) break;; esac
110104
do
@@ -128,6 +122,9 @@ do
128122
-k|--k|--ke|--kee|--keep)
129123
keep=t; shift ;;
130124

125+
-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
126+
resolved=t; shift ;;
127+
131128
--sk|--ski|--skip)
132129
skip=t; shift ;;
133130

@@ -140,6 +137,8 @@ do
140137
esac
141138
done
142139

140+
# If the dotest directory exists, but we have finished applying all the
141+
# patches in them, clear it out.
143142
if test -d "$dotest" &&
144143
last=$(cat "$dotest/last") &&
145144
next=$(cat "$dotest/next") &&
@@ -155,9 +154,9 @@ then
155154
die "previous dotest directory $dotest still exists but mbox given."
156155
resume=yes
157156
else
158-
# Make sure we are not given --skip
159-
test ",$skip," = ,, ||
160-
die "we are not resuming."
157+
# Make sure we are not given --skip nor --resolved
158+
test ",$skip,$resolved," = ,,, ||
159+
die "we are not resuming."
161160

162161
# Start afresh.
163162
mkdir -p "$dotest" || exit
@@ -170,12 +169,24 @@ else
170169
exit 1
171170
}
172171

172+
# -s, -u and -k flags are kept for the resuming session after
173+
# a patch failure.
174+
# -3 and -i can and must be given when resuming.
173175
echo "$sign" >"$dotest/sign"
174176
echo "$utf8" >"$dotest/utf8"
175177
echo "$keep" >"$dotest/keep"
176178
echo 1 >"$dotest/next"
177179
fi
178180

181+
case "$resolved" in
182+
'')
183+
files=$(git-diff-index --cached --name-only HEAD) || exit
184+
if [ "$files" ]; then
185+
echo "Dirty index: cannot apply patches (dirty: $files)" >&2
186+
exit 1
187+
fi
188+
esac
189+
179190
if test "$(cat "$dotest/utf8")" = t
180191
then
181192
utf8=-u
@@ -216,6 +227,15 @@ do
216227
go_next
217228
continue
218229
}
230+
231+
# If we are not resuming, parse and extract the patch information
232+
# into separate files:
233+
# - info records the authorship and title
234+
# - msg is the rest of commit log message
235+
# - patch is the patch body.
236+
#
237+
# When we are resuming, these files are either already prepared
238+
# by the user, or the user can tell us to do so by --resolved flag.
219239
case "$resume" in
220240
'')
221241
git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
@@ -263,6 +283,13 @@ do
263283
fi
264284
} >"$dotest/final-commit"
265285
;;
286+
*)
287+
case "$resolved,$interactive" in
288+
tt)
289+
# This is used only for interactive view option.
290+
git-diff-index -p --cached HEAD >"$dotest/patch"
291+
;;
292+
esac
266293
esac
267294

268295
resume=
@@ -310,7 +337,21 @@ do
310337
echo "Applying '$SUBJECT'"
311338
echo
312339

313-
git-apply --index "$dotest/patch"; apply_status=$?
340+
case "$resolved" in
341+
'')
342+
git-apply --index "$dotest/patch"
343+
apply_status=$?
344+
;;
345+
t)
346+
# Resolved means the user did all the hard work, and
347+
# we do not have to do any patch application. Just
348+
# trust what the user has in the index file and the
349+
# working tree.
350+
resolved=
351+
apply_status=0
352+
;;
353+
esac
354+
314355
if test $apply_status = 1 && test "$threeway" = t
315356
then
316357
if (fall_back_3way)

0 commit comments

Comments
 (0)