#!/bin/sh # # Copyright (c) 2005, 2006 Junio C Hamano setvar SUBDIRECTORY_OK = 'Yes' setvar OPTIONS_KEEPDASHDASH = '' setvar OPTIONS_STUCKLONG = 't' setvar OPTIONS_SPEC = ""\ git am [options] [(|)...] git am [options] (--continue | --skip | --abort) -- i,interactive run interactively b,binary* (historical option -- no-op) 3,3way allow fall back on 3way merging if needed q,quiet be quiet 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 keep-non-patch pass -b flag to git-mailinfo m,message-id pass -m flag to git-mailinfo keep-cr pass --keep-cr flag to git-mailsplit for mbox format no-keep-cr do not pass --keep-cr flag to git-mailsplit independent of am.keepcr c,scissors strip everything before a scissors line whitespace= pass it through git-apply ignore-space-change pass it through git-apply ignore-whitespace pass it through git-apply directory= pass it through git-apply exclude= pass it through git-apply include= pass it through git-apply C= pass it through git-apply p= pass it through git-apply patch-format= format the patch(es) are in reject pass it through git-apply resolvemsg= override error message when patch failure occurs continue continue applying patches after resolving a conflict r,resolved synonyms for --continue skip skip the current patch abort restore the original branch and abort the patching operation. committer-date-is-author-date lie about committer date ignore-date use current timestamp for author date rerere-autoupdate update the index with reused conflict resolution if possible S,gpg-sign? GPG-sign commits rebasing* (internal use for git-rebase)"" source git-sh-setup source git-sh-i18n setvar prefix = $(git rev-parse --show-prefix) set_reflog_action am require_work_tree cd_to_toplevel git var GIT_COMMITTER_IDENT >/dev/null || die $(gettext "You need to set your committer info first") if git rev-parse --verify -q HEAD >/dev/null { setvar HAS_HEAD = 'yes' } else { setvar HAS_HEAD = '' } setvar cmdline = ""git am"" if test '' != $interactive { setvar cmdline = ""$cmdline -i"" } if test '' != $threeway { setvar cmdline = ""$cmdline -3"" } setvar empty_tree = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' proc sq { git rev-parse --sq-quote @ARGV } proc stop_here { echo $1 >"$dotest/next" git rev-parse --verify -q HEAD >"$dotest/abort-safety" exit 1 } proc safe_to_abort { if test -f "$dotest/dirtyindex" { return 1 } if ! test -f "$dotest/abort-safety" { return 0 } setvar abort_safety = $(cat "$dotest/abort-safety") if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety" { return 0 } gettextln "You seem to have moved HEAD since the last 'am' failure. Not rewinding to ORIG_HEAD" >&2 return 1 } proc stop_here_user_resolve { if test -n $resolvemsg { printf '%s\n' $resolvemsg stop_here $1 } eval_gettextln "When you have resolved this problem, run \"\$cmdline --continue\". If you prefer to skip this patch, run \"\$cmdline --skip\" instead. To restore the original branch and stop patching, run \"\$cmdline --abort\"." stop_here $1 } proc go_next { rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \ "$dotest/patch" "$dotest/info" echo $next >"$dotest/next" setvar this = "$next" } proc cannot_fallback { echo $1 gettextln "Cannot fall back to three-way merge." exit 1 } proc fall_back_3way { setvar O_OBJECT = $(cd "$GIT_OBJECT_DIRECTORY" && pwd) rm -fr "$dotest"/patch-merge-* mkdir "$dotest/patch-merge-tmp-dir" # First see if the patch records the index info that we can use. setvar cmd = ""git apply $git_apply_opt --build-fake-ancestor"" && setvar cmd = ""$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch""' && eval $cmd" && GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"" \ git write-tree >"$dotest/patch-merge-base+" || cannot_fallback $(gettext "Repository lacks necessary blobs to fall back on 3-way merge.") say $(gettext "Using index info to reconstruct a base tree...") setvar cmd = ''GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"'' if test -z $GIT_QUIET { eval "$cmd git diff-index --cached --diff-filter=AM --name-status HEAD" } setvar cmd = ""$cmd git apply --cached $git_apply_opt"' <"$dotest/patch""' if eval $cmd { mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" } else { cannot_fallback $(gettext "Did you hand edit your patch? It does not apply to blobs recorded in its index.") } test -f "$dotest/patch-merge-index" && setvar his_tree = $(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) && setvar orig_tree = $(cat "$dotest/patch-merge-base") && rm -fr "$dotest"/patch-merge-* || exit 1 say $(gettext "Falling back to patching base and 3-way merge...") # This is not so wrong. Depending on which base we picked, # orig_tree may be wildly different from ours, but his_tree # has the same set of wildly different changes in parts the # patch did not touch, so recursive ends up canceling them, # saying that we reverted all those changes. eval GITHEAD_$his_tree='"$FIRSTLINE"' export GITHEAD_$his_tree if test -n $GIT_QUIET { setvar GIT_MERGE_VERBOSITY = '0' && export GIT_MERGE_VERBOSITY } setvar our_tree = $(git rev-parse --verify -q HEAD || echo $empty_tree) git-merge-recursive $orig_tree -- $our_tree $his_tree || do { git rerere $allow_rerere_autoupdate die $(gettext "Failed to merge in the changes.") } unset GITHEAD_$his_tree } proc clean_abort { test $Argc = 0 || echo >&2 @ARGV>&2 "$@" rm -fr $dotest exit 1 } setvar patch_format = '' proc check_patch_format { # early return if patch_format was set from the command line if test -n $patch_format { return 0 } # we default to mbox format if input is from stdin and for # directories if test $Argc = 0 || test "x$1" = "x-" || test -d $1 { setvar patch_format = 'mbox' return 0 } # otherwise, check the first few non-blank lines of the first # patch to try to detect its format do { # Start from first line containing non-whitespace setvar l1 = '' while test -z "$l1" { read l1 || break } read l2 read l3 case (l1) { "From "* | "From: "* { setvar patch_format = 'mbox' } '# This series applies on GIT commit'* { setvar patch_format = 'stgit-series' } "# HG changeset patch" { setvar patch_format = 'hg' } * { # if the second line is empty and the third is # a From, Author or Date entry, this is very # likely an StGIT patch case{ ,"From: "* | ,"Author: "* | ,"Date: "* { setvar patch_format = 'stgit' } * { } } } } if test -z $patch_format && test -n $l1 && test -n $l2 && test -n $l3 { # This begins with three non-empty lines. Is this a # piece of e-mail a-la RFC2822? Grab all the headers, # discarding the indented remainder of folded lines, # and see if it looks like that they all begin with the # header field names... tr -d '\015' <"$1" | sed -n -e '/^$/q' -e '/^[ ]/d' -e p | sane_egrep -v '^[!-9;-~]+:' >/dev/null || setvar patch_format = 'mbox' } } < "$1" || clean_abort } proc split_patches { case (patch_format) { mbox { if test t = $keepcr { setvar keep_cr = '--keep-cr' } else { setvar keep_cr = '' } git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- @ARGV > "$dotest/last" || clean_abort } stgit-series { if test $Argc -ne 1 { clean_abort $(gettext "Only one StGIT patch series can be applied at once") } setvar series_dir = $(dirname "$1") setvar series_file = "$1" shift do { set x while read filename { set @ARGV "$series_dir/$filename" } # remove the safety x shift # remove the arg coming from the first-line comment shift } < "$series_file" || clean_abort # set the patch format appropriately setvar patch_format = 'stgit' # now handle the actual StGIT patches split_patches @ARGV } stgit { setvar this = '0' test 0 -eq "$Argc" && set -- - for stgit in "$@" { setvar this = $(expr "$this" + 1) setvar msgnum = $(printf "%0${prec}d" $this) # Perl version of StGIT parse_patch. The first nonemptyline # not starting with Author, From or Date is the # subject, and the body starts with the next nonempty # line not starting with Author, From or Date @@PERL@@ -ne 'BEGIN { $subject = 0 } if ($subject > 1) { print ; } elsif (/^\s+$/) { next ; } elsif (/^Author:/) { s/Author/From/ ; print ;} elsif (/^(From|Date)/) { print ; } elsif ($subject) { $subject = 2 ; print "\n" ; print ; } else { print "Subject: ", $_ ; $subject = 1; } ' -- $stgit >"$dotest/$msgnum" || clean_abort } echo $this > "$dotest/last" setvar this = '' setvar msgnum = '' } hg { setvar this = '0' test 0 -eq "$Argc" && set -- - for hg in "$@" { setvar this = $(( $this + 1 )) setvar msgnum = $(printf "%0${prec}d" $this)' # hg stores changeset metadata in #-commented lines preceding # the commit message and diff(s). The only metadata we care about # are the User and Date (Node ID and Parent are hashes which are # only relevant to the hg repository and thus not useful to us) # Since we cannot guarantee that the commit message is in # git-friendly format, we put no Subject: line and just consume # all of the message as the body LANG=C'' LC_ALL=C' @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 } if ($subject) { print ; } elsif (/^\# User /) { s/\# User/From:/ ; print ; } elsif (/^\# Date /) { my ($hashsign, $str, $time, $tz) = split ; $tz_str = sprintf "%+05d", (0-$tz)/36; print "Date: " . strftime("%a, %d %b %Y %H:%M:%S ", gmtime($time-$tz)) . "$tz_str\n"; } elsif (/^\# /) { next ; } else { print "\n", $_ ; $subject = 1; } ' -- $hg >"$dotest/$msgnum" || clean_abort } echo $this >"$dotest/last" setvar this = '' setvar msgnum = '' } * { if test -n $patch_format { clean_abort $(eval_gettext "Patch format \$patch_format is not supported.") } else { clean_abort $(gettext "Patch format detection failed.") } } } } setvar prec = '4' setvar dotest = ""$GIT_DIR/rebase-apply"" setvar sign = '', utf8 = 't', keep = '', keepcr = '', skip = '', interactive = '', resolved = '', rebasing = '', abort = '' setvar messageid = '', resolvemsg = '', resume = '', scissors = '', no_inbody_headers = '' setvar git_apply_opt = '' setvar committer_date_is_author_date = '' setvar ignore_date = '' setvar allow_rerere_autoupdate = '' setvar gpg_sign_opt = '' setvar threeway = '' if test $(git config --bool --get am.messageid) = true { setvar messageid = 't' } if test $(git config --bool --get am.keepcr) = true { setvar keepcr = 't' } while test $# != 0 { case (1) { -i|--interactive { setvar interactive = 't' } -b|--binary { gettextln >&2 "The -b/--binary option has been a no-op for long time, and it will be removed. Please do not use it anymore.>&2 "The -b/--binary option has been a no-op for long time, and it will be removed. Please do not use it anymore." } -3|--3way { setvar threeway = 't' } -s|--signoff { setvar sign = 't' } -u|--utf8 { setvar utf8 = 't' } # this is now default --no-utf8 { setvar utf8 = '' } -m|--message-id { setvar messageid = 't' } --no-message-id { setvar messageid = 'f' } -k|--keep { setvar keep = 't' } --keep-non-patch { setvar keep = 'b' } -c|--scissors { setvar scissors = 't' } --no-scissors { setvar scissors = 'f' } -r|--resolved|--continue { setvar resolved = 't' } --skip { setvar skip = 't' } --abort { setvar abort = 't' } --rebasing { setvar rebasing = 't', threeway = 't' } --resolvemsg=* { setvar resolvemsg = "${1#--resolvemsg=}" } --whitespace=*|--directory=*|--exclude=*|--include=* { setvar git_apply_opt = ""$git_apply_opt $(sq "$1")"" } -C*|-p* { setvar git_apply_opt = ""$git_apply_opt $(sq "$1")"" } --patch-format=* { setvar patch_format = "${1#--patch-format=}" } --reject|--ignore-whitespace|--ignore-space-change { setvar git_apply_opt = ""$git_apply_opt $1"" } --committer-date-is-author-date { setvar committer_date_is_author_date = 't' } --ignore-date { setvar ignore_date = 't' } --rerere-autoupdate|--no-rerere-autoupdate { setvar allow_rerere_autoupdate = "$1" } -q|--quiet { setvar GIT_QUIET = 't' } --keep-cr { setvar keepcr = 't' } --no-keep-cr { setvar keepcr = 'f' } --gpg-sign { setvar gpg_sign_opt = '-S' } --gpg-sign=* { setvar gpg_sign_opt = ""-S${1#--gpg-sign=}"" } -- { shift; break } * { usage } } shift } # If the dotest directory exists, but we have finished applying all the # patches in them, clear it out. if test -d $dotest && test -f "$dotest/last" && test -f "$dotest/next" && setvar last = $(cat "$dotest/last") && setvar next = $(cat "$dotest/next") && test $Argc != 0 && test $next -gt $last { rm -fr $dotest } if test -d $dotest && test -f "$dotest/last" && test -f "$dotest/next" { case{ 0,*t* { # Explicit resume command and we do not have file, so # we are happy. : } 0, { # No file input but without resume parameters; catch # user error to feed us a patch from standard input # when there is already $dotest. This is somewhat # unreliable -- stdin could be /dev/null for example # and the caller did not intend to feed us a patch but # wanted to continue unattended. test -t 0 } * { false } } || die $(eval_gettext "previous rebase directory \$dotest still exists but mbox given.") setvar resume = 'yes' case{ t,t { die $(gettext "Please make up your mind. --skip or --abort?") } t, { git rerere clear setvar head_tree = $(git rev-parse --verify -q HEAD || echo $empty_tree) && git read-tree --reset -u $head_tree $head_tree && setvar index_tree = $(git write-tree) && git read-tree -m -u $index_tree $head_tree git read-tree -m $head_tree } ,t { if test -f "$dotest/rebasing" { exec git rebase --abort } git rerere clear if safe_to_abort { setvar head_tree = $(git rev-parse --verify -q HEAD || echo $empty_tree) && git read-tree --reset -u $head_tree $head_tree && setvar index_tree = $(git write-tree) && setvar orig_head = $(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) && git read-tree -m -u $index_tree $orig_head if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1 { git reset ORIG_HEAD } else { git read-tree $empty_tree setvar curr_branch = $(git symbolic-ref HEAD 2>/dev/null) && git update-ref -d $curr_branch } } rm -fr $dotest exit } } rm -f "$dotest/dirtyindex" } else { # Possible stray $dotest directory in the independent-run # case; in the --rebasing case, it is upto the caller # (git-rebase--am) to take care of stray directories. if test -d $dotest && test -z $rebasing { case{ ,,t { rm -fr $dotest exit 0 } * { die $(eval_gettext "Stray \$dotest directory found. Use \"git am --abort\" to remove it.") } } } # Make sure we are not given --skip, --continue, or --abort test "$skip$resolved$abort" = "" || die $(gettext "Resolve operation not in progress, we are not resuming.") # Start afresh. mkdir -p $dotest || exit if test -n $prefix && test $Argc != 0 { setvar first = 't'for arg in @ARGV { test -n $first && do { set x setvar first = '' } if is_absolute_path $arg { set @ARGV $arg } else { set @ARGV "$prefix$arg" } } shift } check_patch_format @ARGV split_patches @ARGV # -i can and must be given when resuming; everything # else is kept echo " $git_apply_opt" >"$dotest/apply-opt" echo $threeway >"$dotest/threeway" echo $sign >"$dotest/sign" echo $utf8 >"$dotest/utf8" echo $keep >"$dotest/keep" echo $messageid >"$dotest/messageid" echo $scissors >"$dotest/scissors" echo $no_inbody_headers >"$dotest/no_inbody_headers" echo $GIT_QUIET >"$dotest/quiet" echo 1 >"$dotest/next" if test -n $rebasing { : >"$dotest/rebasing" } else { : >"$dotest/applying" if test -n $HAS_HEAD { git update-ref ORIG_HEAD HEAD } else { git update-ref -d ORIG_HEAD >/dev/null 2>&1 } } } git update-index -q --refresh case (resolved) { '' { case (HAS_HEAD) { '' { setvar files = $(git ls-files) } ?* { setvar files = $(git diff-index --cached --name-only HEAD --) } } || exit if test $files { test -n $HAS_HEAD && : >"$dotest/dirtyindex" die $(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)") } } } # Now, decide what command line options we will give to the git # commands we invoke, based on the result of parsing command line # options and previous invocation state stored in $dotest/ files. if test $(cat "$dotest/utf8") = t { setvar utf8 = '-u' } else { setvar utf8 = '-n' } setvar keep = $(cat "$dotest/keep") case (keep) { t { setvar keep = '-k' } b { setvar keep = '-b' } * { setvar keep = '' } } case{ t { setvar messageid = '-m' } f { setvar messageid = '' } } case{ t { setvar scissors = '--scissors' } f { setvar scissors = '--no-scissors' } } if test $(cat "$dotest/no_inbody_headers") = t { setvar no_inbody_headers = '--no-inbody-headers' } else { setvar no_inbody_headers = '' } if test $(cat "$dotest/quiet") = t { setvar GIT_QUIET = 't' } if test $(cat "$dotest/threeway") = t { setvar threeway = 't' } setvar git_apply_opt = $(cat "$dotest/apply-opt") if test $(cat "$dotest/sign") = t { setvar SIGNOFF = $(git var GIT_COMMITTER_IDENT | sed -e ' s/>.*/>/ s/^/Signed-off-by: /' ) } else { setvar SIGNOFF = '' } setvar last = $(cat "$dotest/last") setvar this = $(cat "$dotest/next") if test $skip = t { setvar this = $(expr "$this" + 1) setvar resume = '' } while test "$this" -le "$last" { setvar msgnum = $(printf "%0${prec}d" $this) setvar next = $(expr "$this" + 1) test -f "$dotest/$msgnum" || do { setvar resume = '' 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 --continue flag. case (resume) { '' { if test -f "$dotest/rebasing" { setvar commit = $(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \ -e q "$dotest/$msgnum") && test $(git cat-file -t "$commit") = commit || stop_here $this git cat-file commit $commit | sed -e '1,/^$/d' >"$dotest/msg-clean" echo $commit >"$dotest/original-commit" get_author_ident_from_commit $commit >"$dotest/author-script" git diff-tree --root --binary --full-index $commit >"$dotest/patch" } else { git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \ <"$dotest/$msgnum" >"$dotest/info" || stop_here $this # skip pine's internal folder data sane_grep '^Author: Mail System Internal Data$' \ <"$dotest"/info >/dev/null && go_next && continue test -s "$dotest/patch" || do { eval_gettextln "Patch is empty. Was it split wrong? If you would prefer to skip this patch, instead run \"\$cmdline --skip\". To restore the original branch and stop patching run \"\$cmdline --abort\"." stop_here $this } rm -f "$dotest/original-commit" "$dotest/author-script" do { sed -n '/^Subject/ s/Subject: //p' "$dotest/info" echo cat "$dotest/msg" } | git stripspace > "$dotest/msg-clean" } } } if test -f "$dotest/author-script" { eval $(cat "$dotest/author-script") } else { setvar GIT_AUTHOR_NAME = "$(sed -n '/^Author/ s/Author: //p' "$dotest/info")" setvar GIT_AUTHOR_EMAIL = "$(sed -n '/^Email/ s/Email: //p' "$dotest/info")" setvar GIT_AUTHOR_DATE = "$(sed -n '/^Date/ s/Date: //p' "$dotest/info")" } if test -z $GIT_AUTHOR_EMAIL { gettextln "Patch does not have a valid e-mail address." stop_here $this } export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE case (resume) { '' { if test '' != $SIGNOFF { setvar LAST_SIGNED_OFF_BY = $( sed -ne '/^Signed-off-by: /p' \ "$dotest/msg-clean" | sed -ne '$p' ) setvar ADD_SIGNOFF = $( test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || { test '' = "$LAST_SIGNED_OFF_BY" && echo echo "$SIGNOFF" }) } else { setvar ADD_SIGNOFF = '' } do { if test -s "$dotest/msg-clean" { cat "$dotest/msg-clean" } if test '' != $ADD_SIGNOFF { echo $ADD_SIGNOFF } } >"$dotest/final-commit" } * { case{ tt { # This is used only for interactive view option. git diff-index -p --cached HEAD -- >"$dotest/patch" } } } } setvar resume = '' if test $interactive = t { test -t 0 || die $(gettext "cannot be interactive without stdin connected to a terminal.") setvar action = 'again' while test "$action" = again { gettextln "Commit Body is:" echo "--------------------------" cat "$dotest/final-commit" echo "--------------------------" # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a] # in your translation. The program will only accept English # input at this point. gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all " read reply case (reply) { [yY]* { setvar action = 'yes' } [aA]* { setvar action = 'yes', interactive = '' } [nN]* { setvar action = 'skip' } [eE]* { git_editor "$dotest/final-commit" setvar action = 'again' } [vV]* { setvar action = 'again' git_pager "$dotest/patch" } * { setvar action = 'again' } } } } else { setvar action = 'yes' } if test $action = skip { go_next continue } setvar hook = "$(git rev-parse --git-path hooks/applypatch-msg)" if test -x $hook { $hook "$dotest/final-commit" || stop_here $this } if test -f "$dotest/final-commit" { setvar FIRSTLINE = $(sed 1q "$dotest/final-commit") } else { setvar FIRSTLINE = """" } say $(eval_gettext "Applying: \$FIRSTLINE") case (resolved) { '' { # When we are allowed to fall back to 3-way later, don't give # false errors during the initial attempt. setvar squelch = '' if test $threeway = t { setvar squelch = ''>/dev/null 2>&1 '' } eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"' setvar 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. setvar resolved = '' git diff-index --quiet --cached HEAD -- && do { gettextln "No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch." stop_here_user_resolve $this } setvar unmerged = $(git ls-files -u) if test -n $unmerged { gettextln "You still have unmerged paths in your index did you forget to use 'git add'?" stop_here_user_resolve $this } setvar apply_status = '0' git rerere } } if test $apply_status != 0 && test $threeway = t { if shell {fall_back_3way} { # Applying the patch to an earlier tree and merging the # result may have produced the same tree as ours. git diff-index --quiet --cached HEAD -- && do { say $(gettext "No changes -- Patch already applied.") go_next continue } # clear apply_status -- we have successfully merged. setvar apply_status = '0' } } if test $apply_status != 0 { eval_gettextln 'Patch failed at $msgnum $FIRSTLINE' if test $(git config --bool advice.amworkdir) != false { eval_gettextln 'The copy of the patch that failed is found in: $dotest/patch' } stop_here_user_resolve $this } setvar hook = "$(git rev-parse --git-path hooks/pre-applypatch)" if test -x $hook { $hook || stop_here $this } setvar tree = $(git write-tree) && setvar commit = $( if test -n "$ignore_date" then GIT_AUTHOR_DATE= fi parent=$(git rev-parse --verify -q HEAD) || say >&2 "$(gettext "applying to an empty history")" if test -n "$committer_date_is_author_date" then GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" export GIT_COMMITTER_DATE fi && git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree \ <"$dotest/final-commit" ) && git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent || stop_here $this if test -f "$dotest/original-commit" { echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten" } setvar hook = "$(git rev-parse --git-path hooks/post-applypatch)" test -x $hook && $hook go_next } if test -s "$dotest"/rewritten { git notes copy --for-rewrite=rebase < "$dotest"/rewritten setvar hook = "$(git rev-parse --git-path hooks/post-rewrite)" if test -x $hook { $hook rebase < "$dotest"/rewritten } } # If am was called with --rebasing (from git-rebase--am), it's up to # the caller to take care of housekeeping. if ! test -f "$dotest/rebasing" { rm -fr $dotest git gc --auto }