3 # Copyright (c) 2005, 2006 Junio C Hamano
8 git am [options] [<mbox>|<Maildir>...]
9 git am [options] (--resolved | --skip | --abort)
11 i,interactive run interactively
12 b,binary* (historical option -- no-op)
13 3,3way allow fall back on 3way merging if needed
15 s,signoff add a Signed-off-by line to the commit message
16 u,utf8 recode into utf8 (default)
17 k,keep pass -k flag to git-mailinfo
18 whitespace= pass it through git-apply
19 directory= pass it through git-apply
20 C= pass it through git-apply
21 p= pass it through git-apply
22 patch-format= format the patch(es) are in
23 reject pass it through git-apply
24 resolvemsg= override error message when patch failure occurs
25 r,resolved to be used after a patch failure
26 skip skip the current patch
27 abort restore the original branch and abort the patching operation.
28 committer-date-is-author-date lie about committer date
29 ignore-date use current timestamp for author date
30 rebasing* (internal use for git-rebase)"
33 prefix
=$
(git rev-parse
--show-prefix)
38 git var GIT_COMMITTER_IDENT
>/dev
/null ||
39 die
"You need to set your committer info first"
51 stop_here_user_resolve
() {
52 if [ -n "$resolvemsg" ]; then
53 printf '%s\n' "$resolvemsg"
57 if test '' != "$interactive"
61 if test '' != "$threeway"
65 echo "When you have resolved this problem run \"$cmdline --resolved\"."
66 echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"."
67 echo "To restore the original branch and stop patching run \"$cmdline --abort\"."
74 msg
="$GIT_DIR/sequencer/message"
75 patch="$GIT_DIR/sequencer/patch"
76 # we rely on sequencer here
79 die
"cannot be interactive without stdin connected to a terminal."
80 action
=$
(cat "$dotest/interactive")
81 while test "$action" = again
84 echo "Commit Body is:"
85 echo "--------------------------"
87 echo "--------------------------"
90 printf "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
92 echo 'Patch does not apply cleanly!'
93 printf "Apply+fix? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
102 # pretend we never tried to apply
104 test conflict
= "$1" ||
106 git read-tree
-m -u HEAD
$to
107 git
reset -q $to >/dev
/null
112 git commit
--amend --file="$msg" --no-verify >/dev
/null
115 LESS
=-S ${PAGER:-less} "$patch"
118 echo 'accept' >"$dotest/interactive"
126 test "$action" = accept
&&
127 sed -n -e '1s/^/Applying &/p' <"$msg"
132 output
=$
(git sequencer
$seqopts \
133 --caller='git am|--abort|--resolved|--skip' "$@")
135 test -z "$output" ||
printf '%s\n' "$output"
136 # we want this "printf" stuff to suppress sequencer's
137 # "Sequencing..." messages
144 stop_here_user_resolve
147 die_abort
'git-sequencer died unexpected. Aborting.'
156 output
=$
(git sequencer
$seqopts \
157 --caller='git am -i|--abort|--resolved|--skip' \
165 if test -f "$dotest/conflict"
167 rm "$dotest/conflict"
173 : >"$dotest/conflict"
174 be_interactive conflict
177 printf '%s\n' "$output" 1>&2
178 stop_here_user_resolve
190 escape_double_quotes
() {
191 printf %s
"$*" |
sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
195 test $# = 0 ||
echo >&2 "$@"
202 check_patch_format
() {
203 # early return if patch_format was set from the command line
204 if test -n "$patch_format"
209 # we default to mbox format if input is from stdin and for
211 if test $# = 0 ||
test "x$1" = "x-" ||
test -d "$1"
217 # otherwise, check the first few lines of the first patch to try
218 # to detect its format
224 "From "* |
"From: "*)
227 '# This series applies on GIT commit'*)
228 patch_format
=stgit-series
230 "# HG changeset patch")
234 # if the second line is empty and the third is
235 # a From, Author or Date entry, this is very
236 # likely an StGIT patch
238 ,"From: "* |
,"Author: "* |
,"Date: "*)
246 } < "$1" || clean_abort
250 case "$patch_format" in
252 git mailsplit
-d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||
258 clean_abort
"Only one StGIT patch series can be applied at once"
260 series_dir
=`dirname "$1"`
267 set "$@" "$series_dir/$filename"
269 # remove the safety x
271 # remove the arg coming from the first-line comment
273 } < "$series_file" || clean_abort
274 # set the patch format appropriately
276 # now handle the actual StGIT patches
283 this
=`expr "$this" + 1`
284 msgnum
=`printf "%0${prec}d" $this`
285 # Perl version of StGIT parse_patch. The first nonemptyline
286 # not starting with Author, From or Date is the
287 # subject, and the body starts with the next nonempty
288 # line not starting with Author, From or Date
289 perl
-ne 'BEGIN { $subject = 0 }
290 if ($subject > 1) { print ; }
291 elsif (/^\s+$/) { next ; }
292 elsif (/^Author:/) { print s/Author/From/ ; }
293 elsif (/^(From|Date)/) { print ; }
299 print "Subject: ", $_ ;
302 ' < "$stgit" > "$dotest/$msgnum" || clean_abort
304 echo "$this" > "$dotest/last"
309 clean_abort
"Patch format $patch_format is not supported."
315 dotest
="$GIT_DIR/rebase-apply"
316 todofile
="$dotest/todo"
317 sign
= utf8
=t keep
= skip
= interactive
= resolved
= rebasing
= abort
=
320 committer_date_is_author_date
=
335 utf8
=t
;; # this is now default
347 rebasing
=t threeway
=t keep
=t
;;
349 die
"-d option is no longer supported. Do not use."
352 shift; resolvemsg
=$1 ;;
353 --whitespace|
--directory)
354 opts
="$opts $1=\"$(escape_double_quotes $2)\""; shift ;;
356 opts
="$opts --context=$2" ; shift ;;
358 opts
="$opts $1$2"; shift ;;
360 shift ; patch_format
="$1" ;;
363 --committer-date-is-author-date)
364 committer_date_is_author_date
=t
;;
380 die
"previous rebase directory $dotest still exists but mbox given."
382 test -f "$dotest/interactive" &&
383 interactive
=_i action
=$
(cat "$dotest/interactive")
385 case "$skip,$abort,$resolved" in
387 die
"Please make up your mind. --skip, --resolved or --abort?"
390 run_sequencer
$interactive --skip
393 run_sequencer
$interactive --abort
396 run_sequencer
$interactive --continue
399 # No file input but without resume parameters; catch
400 # user error to feed us a patch from standard input
401 # when there is already $dotest. This is somewhat
402 # unreliable -- stdin could be /dev/null for example
403 # and the caller did not intend to feed us a patch but
404 # wanted to continue unattended.
409 die
"$dotest still exists. Use git am --abort/--skip/--resolved."
412 # Make sure we are not given --skip, --resolved, nor --abort
413 test -z "$abort$resolved$skip" ||
414 die
'git-am is not in progress. You cannot use --abort/--skip/--resolved then.'
417 git sequencer
--status >/dev
/null
2>&1 &&
418 die
"Sequencer already started. Cannot run git-am."
421 mkdir
-p "$dotest" ||
422 die
"Could not create $dotest directory."
424 if test -n "$prefix" && test $# != 0
429 test -n "$first" && {
437 set "$@" "$prefix$arg" ;;
442 last
=$
(git mailsplit
-d"$prec" -o"$dotest" -b -- "$@") ||
{
448 files
=$
(git diff-index
--cached --name-only HEAD
--) ||
exit
449 if [ "$files" ]; then
450 echo "Dirty index: cannot apply patches (dirty: $files)" >&2
454 test -n "$interactive" && echo 'again' >"$dotest/interactive"
456 # converting our options to git-sequencer file insn options
457 test -n "$utf8" || opts
="$opts -n"
458 test -n "$keep" && opts
="$opts -k"
459 test -n "$sign" && opts
="$opts --signoff"
460 test -n "$threeway" && opts
="$opts -3"
462 # these files are created for tab completion scripts
463 if test -n "$rebasing"
465 : >"$dotest/rebasing"
467 : >"$dotest/applying"
468 git update-ref ORIG_HEAD HEAD
473 die_abort
"Cannot create $todofile"
474 while test "$this" -le "$last"
476 msgnum
=$
(printf "%0${prec}d" $this)
479 # This ignores every mail that does not contain a patch.
480 grep '^diff' "$dotest/$msgnum" >/dev
/null ||
484 test -n "$rebasing" &&
485 commit
=$
(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \
486 -e q
"$dotest/$msgnum") &&
487 test "$(git cat-file -t "$commit")" = commit
&&
490 subject
=$
(sed -n '1,/^Subject:/s/Subject: *\(\[.*\]\)\{0,1\} *//p' \
492 test -n "$GIT_QUIET" -o -n "$interactive" ||
493 printf 'run -- printf "Applying: %%s\\\\n" "%s"\n' \
494 "$(escape_double_quotes "$subject")" >>"$todofile"
495 printf 'patch%s%s "%s" # %s\n' "$opts" "$extra" \
496 "$(escape_double_quotes "$dotest/$msgnum")" \
497 "$subject" >>"$todofile"
498 test -z "$interactive" ||
echo 'pause' >>"$todofile"
501 seqopts
="--no-advice --allow-dirty"
502 run_sequencer
$interactive $GIT_QUIET "$todofile"