X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=inline;f=git-am.sh;h=d3390755fc687a611e89320a7bbfb4ead512c863;hb=c511549e0c6848f00bd19f152b8ab42261ff5d0c;hp=b48096ec2037e3f14d4bdf89a0afe4623aff090e;hpb=92798702cf6d201f80e257a07d0a0c40565c79fe;p=git.git diff --git a/git-am.sh b/git-am.sh index b48096ec2..d3390755f 100755 --- a/git-am.sh +++ b/git-am.sh @@ -5,24 +5,27 @@ SUBDIRECTORY_OK=Yes OPTIONS_KEEPDASHDASH= OPTIONS_SPEC="\ -git-am [options] |... -git-am [options] --resolved -git-am [options] --skip +git am [options] [|...] +git am [options] (--resolved | --skip | --abort) -- -d,dotest= (removed -- do not use) i,interactive run interactively -b,binary pass --allow-binary-replacement to git-apply +b,binary* (historical option -- no-op) 3,3way allow fall back on 3way merging if needed 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 whitespace= pass it through git-apply +directory= pass it through git-apply C= pass it through git-apply p= pass it through git-apply +reject pass it through git-apply resolvemsg= override error message when patch failure occurs r,resolved to be used after a patch failure skip skip the current patch -rebasing (internal use for git-rebase)" +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 +rebasing* (internal use for git-rebase)" . git-sh-setup prefix=$(git rev-parse --show-prefix) @@ -30,7 +33,16 @@ set_reflog_action am require_work_tree cd_to_toplevel -git var GIT_COMMITTER_IDENT >/dev/null || exit +git var GIT_COMMITTER_IDENT >/dev/null || + die "You need to set your committer info first" + +sq () { + for sqarg + do + printf "%s" "$sqarg" | + sed -e 's/'\''/'\''\\'\'''\''/g' -e 's/.*/ '\''&'\''/' + done +} stop_here () { echo "$1" >"$dotest/next" @@ -42,7 +54,7 @@ stop_here_user_resolve () { printf '%s\n' "$resolvemsg" stop_here $1 fi - cmdline=$(basename $0) + cmdline="git am" if test '' != "$interactive" then cmdline="$cmdline -i" @@ -53,6 +65,7 @@ stop_here_user_resolve () { fi echo "When you have resolved this problem run \"$cmdline --resolved\"." echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"." + echo "To restore the original branch and stop patching run \"$cmdline --abort\"." stop_here $1 } @@ -85,7 +98,7 @@ fall_back_3way () { echo Using index info to reconstruct a base tree... if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git apply $binary --cached <"$dotest/patch" + git apply --cached <"$dotest/patch" then mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" @@ -118,10 +131,12 @@ It does not apply to blobs recorded in its index." } prec=4 -dotest=".dotest" -sign= utf8=t keep= skip= interactive= resolved= binary= rebasing= +dotest="$GIT_DIR/rebase-apply" +sign= utf8=t keep= skip= interactive= resolved= rebasing= abort= resolvemsg= resume= git_apply_opt= +committer_date_is_author_date= +ignore_date= while test $# != 0 do @@ -129,7 +144,7 @@ do -i|--interactive) interactive=t ;; -b|--binary) - binary=t ;; + : ;; -3|--3way) threeway=t ;; -s|--signoff) @@ -144,17 +159,25 @@ do resolved=t ;; --skip) skip=t ;; + --abort) + abort=t ;; --rebasing) - rebasing=t threeway=t keep=t binary=t ;; + rebasing=t threeway=t keep=t ;; -d|--dotest) die "-d option is no longer supported. Do not use." ;; --resolvemsg) shift; resolvemsg=$1 ;; - --whitespace) - git_apply_opt="$git_apply_opt $1=$2"; shift ;; + --whitespace|--directory) + git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;; -C|-p) - git_apply_opt="$git_apply_opt $1$2"; shift ;; + git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;; + --reject) + git_apply_opt="$git_apply_opt $1" ;; + --committer-date-is-author-date) + committer_date_is_author_date=t ;; + --ignore-date) + ignore_date=t ;; --) shift; break ;; *) @@ -176,7 +199,7 @@ fi if test -d "$dotest" then - case "$#,$skip$resolved" in + case "$#,$skip$resolved$abort" in 0,*t*) # Explicit resume command and we do not have file, so # we are happy. @@ -188,17 +211,43 @@ then # unreliable -- stdin could be /dev/null for example # and the caller did not intend to feed us a patch but # wanted to continue unattended. - tty -s + test -t 0 ;; *) false ;; esac || - die "previous dotest directory $dotest still exists but mbox given." + die "previous rebase directory $dotest still exists but mbox given." resume=yes + + case "$skip,$abort" in + t,t) + die "Please make up your mind. --skip or --abort?" + ;; + t,) + git rerere clear + git read-tree --reset -u HEAD HEAD + orig_head=$(cat "$GIT_DIR/ORIG_HEAD") + git reset HEAD + git update-ref ORIG_HEAD $orig_head + ;; + ,t) + if test -f "$dotest/rebasing" + then + exec git rebase --abort + fi + git rerere clear + test -f "$dotest/dirtyindex" || { + git read-tree --reset -u HEAD ORIG_HEAD + git reset ORIG_HEAD + } + rm -fr "$dotest" + exit ;; + esac + rm -f "$dotest/dirtyindex" else - # Make sure we are not given --skip nor --resolved - test ",$skip,$resolved," = ,,, || + # Make sure we are not given --skip, --resolved, nor --abort + test "$skip$resolved$abort" = "" || die "Resolve operation not in progress, we are not resuming." # Start afresh. @@ -227,11 +276,11 @@ else exit 1 } - # -b, -s, -u, -k and --whitespace flags are kept for the - # resuming session after a patch failure. - # -3 and -i can and must be given when resuming. - echo "$binary" >"$dotest/binary" - echo " $ws" >"$dotest/whitespace" + # -s, -u, -k, --whitespace, -3, -C and -p flags are kept + # for the resuming session after a patch failure. + # -i can and must be given when resuming. + echo " $git_apply_opt" >"$dotest/apply-opt" + echo "$threeway" >"$dotest/threeway" echo "$sign" >"$dotest/sign" echo "$utf8" >"$dotest/utf8" echo "$keep" >"$dotest/keep" @@ -241,22 +290,20 @@ else : >"$dotest/rebasing" else : >"$dotest/applying" + git update-ref ORIG_HEAD HEAD 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 + if test "$files" + then + : >"$dotest/dirtyindex" + die "Dirty index: cannot apply patches (dirty: $files)" fi esac -if test "$(cat "$dotest/binary")" = t -then - binary=--allow-binary-replacement -fi if test "$(cat "$dotest/utf8")" = t then utf8=-u @@ -267,10 +314,14 @@ if test "$(cat "$dotest/keep")" = t then keep=-k fi -ws=`cat "$dotest/whitespace"` +if test "$(cat "$dotest/threeway")" = t +then + threeway=t +fi +git_apply_opt=$(cat "$dotest/apply-opt") if test "$(cat "$dotest/sign")" = t then - SIGNOFF=`git-var GIT_COMMITTER_IDENT | sed -e ' + SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e ' s/>.*/>/ s/^/Signed-off-by: /' ` @@ -282,7 +333,6 @@ last=`cat "$dotest/last"` this=`cat "$dotest/next"` if test "$skip" = t then - git rerere clear this=`expr "$this" + 1` resume= fi @@ -323,7 +373,7 @@ do <"$dotest"/info >/dev/null && go_next && continue - test -s $dotest/patch || { + test -s "$dotest/patch" || { echo "Patch is empty. Was it split wrong?" stop_here $this } @@ -421,7 +471,7 @@ do else action=yes fi - FIRSTLINE=$(head -1 "$dotest/final-commit") + FIRSTLINE=$(sed 1q "$dotest/final-commit") if test $action = skip then @@ -435,11 +485,11 @@ do stop_here $this fi - printf 'Applying %s\n' "$FIRSTLINE" + printf 'Applying: %s\n' "$FIRSTLINE" case "$resolved" in '') - git apply $git_apply_opt $binary --index "$dotest/patch" + eval 'git apply '"$git_apply_opt"' --index "$dotest/patch"' apply_status=$? ;; t) @@ -481,7 +531,7 @@ do fi if test $apply_status != 0 then - echo Patch failed at $msgnum. + printf 'Patch failed at %s %s\n' "$msgnum" "$FIRSTLINE" stop_here_user_resolve $this fi @@ -492,7 +542,18 @@ do tree=$(git write-tree) && parent=$(git rev-parse --verify HEAD) && - commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") && + commit=$( + if test -n "$ignore_date" + then + GIT_AUTHOR_DATE= + fi + if test -n "$committer_date_is_author_date" + then + GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" + export GIT_COMMITTER_DATE + fi && + git commit-tree $tree -p $parent <"$dotest/final-commit" + ) && git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent || stop_here $this