#!/bin/sh # # Copyright (c) 2005, 2006 Junio C Hamano setglobal SUBDIRECTORY_OK = 'Yes' setglobal OPTIONS_KEEPDASHDASH = '' setglobal OPTIONS_STUCKLONG = 't' setglobal 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 setglobal 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 { setglobal HAS_HEAD = 'yes' } else { setglobal HAS_HEAD = '' } setglobal cmdline = '"git am'" if test '' != $interactive { setglobal cmdline = ""$cmdline -i"" } if test '' != $threeway { setglobal cmdline = ""$cmdline -3"" } setglobal 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 } setglobal 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" setglobal this = $next } proc cannot_fallback { echo $1 gettextln "Cannot fall back to three-way merge." exit 1 } proc fall_back_3way { setglobal 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. setglobal cmd = ""git apply $git_apply_opt --build-fake-ancestor"" && setglobal cmd = ""$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch""' && eval $cmd && env 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...] setglobal 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" } setglobal 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" && setglobal his_tree = $[env GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree] && setglobal 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 { setglobal GIT_MERGE_VERBOSITY = '0' && export GIT_MERGE_VERBOSITY } setglobal 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 } setglobal 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 { setglobal 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 setglobal l1 = '' while test -z "$l1" { read l1 || break } read l2 read l3 match $l1 { with "From "* | "From: "* setglobal patch_format = 'mbox' with '# This series applies on GIT commit'* setglobal patch_format = 'stgit-series' with "# HG changeset patch" setglobal patch_format = 'hg' with * # if the second line is empty and the third is # a From, Author or Date entry, this is very # likely an StGIT patch match "$l2,$l3" { with ,"From: "* | ,"Author: "* | ,"Date: "* setglobal patch_format = 'stgit' with * } } 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 || setglobal patch_format = 'mbox' } } < "$1" || clean_abort } proc split_patches { match $patch_format { with mbox if test t = $keepcr { setglobal keep_cr = '--keep-cr' } else { setglobal keep_cr = '' } git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- @Argv > "$dotest/last" || clean_abort with stgit-series if test $Argc -ne 1 { clean_abort $[gettext "Only one StGIT patch series can be applied at once] } setglobal series_dir = $[dirname $1] setglobal 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 setglobal patch_format = 'stgit' # now handle the actual StGIT patches split_patches @Argv with stgit setglobal this = '0' test 0 -eq "$Argc" && set -- - for stgit in [@Argv] { setglobal this = $[expr $this + 1] setglobal 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" setglobal this = '' setglobal msgnum = '' with hg setglobal this = '0' test 0 -eq "$Argc" && set -- - for hg in [@Argv] { setglobal this = $shExpr(' $this + 1 ') setglobal 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 env 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" setglobal this = '' setglobal msgnum = '' with * if test -n $patch_format { clean_abort $[eval_gettext "Patch format \$patch_format is not supported.] } else { clean_abort $[gettext "Patch format detection failed.] } } } setglobal prec = '4' setglobal dotest = ""$GIT_DIR/rebase-apply"" setglobal sign = '', utf8 = 't', keep = '', keepcr = '', skip = '', interactive = '', resolved = '', rebasing = '', abort = '' setglobal messageid = '', resolvemsg = '', resume = '', scissors = '', no_inbody_headers = '' setglobal git_apply_opt = '' setglobal committer_date_is_author_date = '' setglobal ignore_date = '' setglobal allow_rerere_autoupdate = '' setglobal gpg_sign_opt = '' setglobal threeway = '' if test $[git config --bool --get am.messageid] = true { setglobal messageid = 't' } if test $[git config --bool --get am.keepcr] = true { setglobal keepcr = 't' } while test $# != 0 { match $1 { with -i|--interactive setglobal interactive = 't' with -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." with -3|--3way setglobal threeway = 't' with -s|--signoff setglobal sign = 't' with -u|--utf8 setglobal utf8 = 't' # this is now default with --no-utf8 setglobal utf8 = '' with -m|--message-id setglobal messageid = 't' with --no-message-id setglobal messageid = 'f' with -k|--keep setglobal keep = 't' with --keep-non-patch setglobal keep = 'b' with -c|--scissors setglobal scissors = 't' with --no-scissors setglobal scissors = 'f' with -r|--resolved|--continue setglobal resolved = 't' with --skip setglobal skip = 't' with --abort setglobal abort = 't' with --rebasing setglobal rebasing = 't', threeway = 't' with --resolvemsg=* setglobal resolvemsg = $(1#--resolvemsg=) with --whitespace=*|--directory=*|--exclude=*|--include=* setglobal git_apply_opt = ""$git_apply_opt $[sq $1]"" with -C*|-p* setglobal git_apply_opt = ""$git_apply_opt $[sq $1]"" with --patch-format=* setglobal patch_format = $(1#--patch-format=) with --reject|--ignore-whitespace|--ignore-space-change setglobal git_apply_opt = ""$git_apply_opt $1"" with --committer-date-is-author-date setglobal committer_date_is_author_date = 't' with --ignore-date setglobal ignore_date = 't' with --rerere-autoupdate|--no-rerere-autoupdate setglobal allow_rerere_autoupdate = $1 with -q|--quiet setglobal GIT_QUIET = 't' with --keep-cr setglobal keepcr = 't' with --no-keep-cr setglobal keepcr = 'f' with --gpg-sign setglobal gpg_sign_opt = '-S' with --gpg-sign=* setglobal gpg_sign_opt = ""-S$(1#--gpg-sign=)"" with -- shift; break with * 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" && setglobal last = $[cat "$dotest/last] && setglobal 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" { match "$Argc,$skip$resolved$abort" { with 0,*t* # Explicit resume command and we do not have file, so # we are happy. : with 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 with * false } || die $[eval_gettext "previous rebase directory \$dotest still exists but mbox given.] setglobal resume = 'yes' match "$skip,$abort" { with t,t die $[gettext "Please make up your mind. --skip or --abort?] with t, git rerere clear setglobal head_tree = $[git rev-parse --verify -q HEAD || echo $empty_tree] && git read-tree --reset -u $head_tree $head_tree && setglobal index_tree = $[git write-tree] && git read-tree -m -u $index_tree $head_tree git read-tree -m $head_tree with ,t if test -f "$dotest/rebasing" { exec git rebase --abort } git rerere clear if safe_to_abort { setglobal head_tree = $[git rev-parse --verify -q HEAD || echo $empty_tree] && git read-tree --reset -u $head_tree $head_tree && setglobal index_tree = $[git write-tree] && setglobal 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 setglobal 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 { match "$skip,$resolved,$abort" { with ,,t rm -fr $dotest exit 0 with * 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 { setglobal first = 't'for arg in @Argv { test -n $first && do { set x setglobal 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 match $resolved { with '' match $HAS_HEAD { with '' setglobal files = $[git ls-files] with ?* setglobal 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 { setglobal utf8 = '-u' } else { setglobal utf8 = '-n' } setglobal keep = $[cat "$dotest/keep] match $keep { with t setglobal keep = '-k' with b setglobal keep = '-b' with * setglobal keep = '' } match $[cat "$dotest/messageid] { with t setglobal messageid = '-m' with f setglobal messageid = '' } match $[cat "$dotest/scissors] { with t setglobal scissors = '--scissors' with f setglobal scissors = '--no-scissors' } if test $[cat "$dotest/no_inbody_headers] = t { setglobal no_inbody_headers = '--no-inbody-headers' } else { setglobal no_inbody_headers = '' } if test $[cat "$dotest/quiet] = t { setglobal GIT_QUIET = 't' } if test $[cat "$dotest/threeway] = t { setglobal threeway = 't' } setglobal git_apply_opt = $[cat "$dotest/apply-opt] if test $[cat "$dotest/sign] = t { setglobal SIGNOFF = $[git var GIT_COMMITTER_IDENT | sed -e ' s/>.*/>/ s/^/Signed-off-by: /] } else { setglobal SIGNOFF = '' } setglobal last = $[cat "$dotest/last] setglobal this = $[cat "$dotest/next] if test $skip = t { setglobal this = $[expr $this + 1] setglobal resume = '' } while test "$this" -le "$last" { setglobal msgnum = $[printf "%0$(prec)d" $this] setglobal next = $[expr $this + 1] test -f "$dotest/$msgnum" || do { setglobal 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. match $resume { with '' if test -f "$dotest/rebasing" { setglobal 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 { setglobal GIT_AUTHOR_NAME = $[sed -n '/^Author/ s/Author: //p' "$dotest/info] setglobal GIT_AUTHOR_EMAIL = $[sed -n '/^Email/ s/Email: //p' "$dotest/info] setglobal 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 match $resume { with '' if test '' != $SIGNOFF { setglobal LAST_SIGNED_OFF_BY = $[ sed -ne '/^Signed-off-by: /p' \ "$dotest/msg-clean" | sed -ne '$p] setglobal ADD_SIGNOFF = $[ test $LAST_SIGNED_OFF_BY = $SIGNOFF || do { test '' = $LAST_SIGNED_OFF_BY && echo echo $SIGNOFF] } else { setglobal ADD_SIGNOFF = '' } do { if test -s "$dotest/msg-clean" { cat "$dotest/msg-clean" } if test '' != $ADD_SIGNOFF { echo $ADD_SIGNOFF } } >"$dotest/final-commit" with * match "$resolved$interactive" { with tt # This is used only for interactive view option. git diff-index -p --cached HEAD -- >"$dotest/patch" } } setglobal resume = '' if test $interactive = t { test -t 0 || die $[gettext "cannot be interactive without stdin connected to a terminal.] setglobal 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 match $reply { with [yY]* setglobal action = 'yes' with [aA]* setglobal action = 'yes', interactive = '' with [nN]* setglobal action = 'skip' with [eE]* git_editor "$dotest/final-commit" setglobal action = 'again' with [vV]* setglobal action = 'again' git_pager "$dotest/patch" with * setglobal action = 'again' } } } else { setglobal action = 'yes' } if test $action = skip { go_next continue } setglobal 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" { setglobal FIRSTLINE = $[sed 1q "$dotest/final-commit] } else { setglobal FIRSTLINE = ''"" } say $[eval_gettext "Applying: \$FIRSTLINE] match $resolved { with '' # When we are allowed to fall back to 3-way later, don't give # false errors during the initial attempt. setglobal squelch = '' if test $threeway = t { setglobal squelch = ''>/dev/null 2>&1 '' } eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"' setglobal apply_status = $Status with 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. setglobal 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 } setglobal 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 } setglobal 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. setglobal 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 } setglobal hook = $[git rev-parse --git-path hooks/pre-applypatch] if test -x $hook { $hook || stop_here $this } setglobal tree = $[git write-tree] && setglobal commit = $[ if test -n $ignore_date { setglobal GIT_AUTHOR_DATE = '' } setglobal parent = $[git rev-parse --verify -q HEAD] || say >&2 $[gettext "applying to an empty history]> !2 "$(gettext "applying to an empty history")" if test -n $committer_date_is_author_date { setglobal GIT_COMMITTER_DATE = $GIT_AUTHOR_DATE export GIT_COMMITTER_DATE } && 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" } setglobal 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 setglobal 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 }