X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-am.sh;h=afe322b20fb0b40dfeb1cb17dc3cad09096e943a;hb=d5f6a01af0658bc0ec5f068d81ba321be94526d5;hp=872145b92dc7000eb1c87d548a46fa0d9522870d;hpb=dd097fcd4d3d6692ec19c0caf4686aa8849301a2;p=git.git diff --git a/git-am.sh b/git-am.sh index 872145b92..afe322b20 100755 --- a/git-am.sh +++ b/git-am.sh @@ -14,6 +14,30 @@ stop_here () { exit 1 } +stop_here_user_resolve () { + if [ -n "$resolvemsg" ]; then + echo "$resolvemsg" + stop_here $1 + fi + cmdline=$(basename $0) + if test '' != "$interactive" + then + cmdline="$cmdline -i" + fi + if test '' != "$threeway" + then + cmdline="$cmdline -3" + fi + if test '.dotest' != "$dotest" + then + cmdline="$cmdline -d=$dotest" + fi + echo "When you have resolved this problem run \"$cmdline --resolved\"." + echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"." + + stop_here $1 +} + go_next () { rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \ "$dotest/patch" "$dotest/info" @@ -21,6 +45,12 @@ go_next () { this=$next } +cannot_fallback () { + echo "$1" + echo "Cannot fall back to three-way merge." + exit 1 +} + fall_back_3way () { O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd` @@ -28,53 +58,23 @@ fall_back_3way () { mkdir "$dotest/patch-merge-tmp-dir" # First see if the patch records the index info that we can use. - if git-apply -z --index-info "$dotest/patch" \ - >"$dotest/patch-merge-index-info" 2>/dev/null && - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-update-index -z --index-info <"$dotest/patch-merge-index-info" && - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-write-tree >"$dotest/patch-merge-base+" && - # index has the base tree now. - ( - cd "$dotest/patch-merge-tmp-dir" && - GIT_INDEX_FILE="../patch-merge-tmp-index" \ - GIT_OBJECT_DIRECTORY="$O_OBJECT" \ - git-apply $binary --index <../patch - ) + git-apply -z --index-info "$dotest/patch" \ + >"$dotest/patch-merge-index-info" && + GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-update-index -z --index-info <"$dotest/patch-merge-index-info" && + GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-write-tree >"$dotest/patch-merge-base+" || + cannot_fallback "Patch does not record usable index information." + + echo Using index info to reconstruct a base tree... + if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-apply $binary --cached <"$dotest/patch" then - echo Using index info to reconstruct a base tree... mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" else - # Otherwise, try nearby trees that can be used to apply the - # patch. - ( - N=10 - - # Hoping the patch is against our recent commits... - git-rev-list --max-count=$N HEAD - - # or hoping the patch is against known tags... - git-ls-remote --tags . - ) | - while read base junk - do - # See if we have it as a tree... - git-cat-file tree "$base" >/dev/null 2>&1 || continue - - rm -fr "$dotest"/patch-merge-* && - mkdir "$dotest/patch-merge-tmp-dir" || break - ( - cd "$dotest/patch-merge-tmp-dir" && - GIT_INDEX_FILE=../patch-merge-tmp-index && - GIT_OBJECT_DIRECTORY="$O_OBJECT" && - export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY && - git-read-tree "$base" && - git-apply $binary --index && - mv ../patch-merge-tmp-index ../patch-merge-index && - echo "$base" >../patch-merge-base - ) <"$dotest/patch" 2>/dev/null && break - done + cannot_fallback "Did you hand edit your patch? +It does not apply to blobs recorded in its index." fi test -f "$dotest/patch-merge-index" && @@ -87,7 +87,7 @@ fall_back_3way () { # 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 resolve ends up cancelling them, + # patch did not touch, so resolve ends up canceling them, # saying that we reverted all those changes. git-merge-resolve $orig_tree -- HEAD $his_tree || { @@ -101,13 +101,14 @@ fall_back_3way () { } prec=4 -dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= +rloga=am +dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= resolvemsg= while case "$#" in 0) break;; esac do case "$1" in -d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*) - dotest=`expr "$1" : '-[^=]*=\(.*\)'`; shift ;; + dotest=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;; -d|--d|--do|--dot|--dote|--dotes|--dotest) case "$#" in 1) usage ;; esac; shift dotest="$1"; shift;; @@ -137,6 +138,12 @@ do --whitespace=*) ws=$1; shift ;; + --resolvemsg=*) + resolvemsg=$(echo "$1" | sed -e "s/^--resolvemsg=//"); shift ;; + + --reflog-action=*) + rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;; + --) shift; break ;; -*) @@ -159,13 +166,30 @@ fi if test -d "$dotest" then - test ",$#," = ",0," || + case "$#,$skip$resolved" in + 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. + tty -s + ;; + *) + false + ;; + esac || die "previous dotest directory $dotest still exists but mbox given." resume=yes else # Make sure we are not given --skip nor --resolved test ",$skip,$resolved," = ,,, || - die "we are not resuming." + die "Resolve operation not in progress, we are not resuming." # Start afresh. mkdir -p "$dotest" || exit @@ -374,14 +398,14 @@ do if test '' = "$changed" then echo "No changes - did you forget update-index?" - stop_here $this + stop_here_user_resolve $this fi unmerged=$(git-ls-files -u) if test -n "$unmerged" then echo "You still have unmerged paths in your index" echo "did you forget update-index?" - stop_here $this + stop_here_user_resolve $this fi apply_status=0 ;; @@ -407,7 +431,7 @@ do if test $apply_status != 0 then echo Patch failed at $msgnum. - stop_here $this + stop_here_user_resolve $this fi if test -x "$GIT_DIR"/hooks/pre-applypatch @@ -420,7 +444,7 @@ do parent=$(git-rev-parse --verify HEAD) && commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") && echo Committed: $commit && - git-update-ref HEAD $commit $parent || + git-update-ref -m "$rloga: $SUBJECT" HEAD $commit $parent || stop_here $this if test -x "$GIT_DIR"/hooks/post-applypatch