OSDN Git Service

Merge branch 'km/avoid-non-function-return-in-rebase'
authorJunio C Hamano <gitster@pobox.com>
Mon, 21 Apr 2014 17:42:45 +0000 (10:42 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 21 Apr 2014 17:42:46 +0000 (10:42 -0700)
Work around /bin/sh that does not like "return" at the top-level
of a file that is dot-sourced from inside a function definition.

* km/avoid-non-function-return-in-rebase:
  Revert "rebase: fix run_specific_rebase's use of "return" on FreeBSD"
  rebase: avoid non-function use of "return" on FreeBSD

1  2 
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-rebase.sh

diff --combined git-rebase--am.sh
@@@ -4,10 -4,20 +4,21 @@@
  # Copyright (c) 2010 Junio C Hamano.
  #
  
+ # The whole contents of this file is run by dot-sourcing it from
+ # inside a shell function.  It used to be that "return"s we see
+ # below were not inside any function, and expected to return
+ # to the function that dot-sourced us.
+ #
+ # However, FreeBSD /bin/sh misbehaves on such a construct and
+ # continues to run the statements that follow such a "return".
+ # As a work-around, we introduce an extra layer of a function
+ # here, and immediately call it after defining it.
+ git_rebase__am () {
  case "$action" in
  continue)
 -      git am --resolved --resolvemsg="$resolvemsg" &&
 +      git am --resolved --resolvemsg="$resolvemsg" \
 +              ${gpg_sign_opt:+"$gpg_sign_opt"} &&
        move_to_original_branch
        return
        ;;
@@@ -27,7 -37,7 +38,7 @@@ the
        # empty commits and even if it didn't the format doesn't really lend
        # itself well to recording empty patches.  fortunately, cherry-pick
        # makes this easy
 -      git cherry-pick --allow-empty "$revisions"
 +      git cherry-pick ${gpg_sign_opt:+"$gpg_sign_opt"} --allow-empty "$revisions"
        ret=$?
  else
        rm -f "$GIT_DIR/rebased-patches"
@@@ -61,8 -71,7 +72,8 @@@
                return $?
        fi
  
 -      git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" <"$GIT_DIR/rebased-patches"
 +      git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
 +              ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
        ret=$?
  
        rm -f "$GIT_DIR/rebased-patches"
@@@ -75,3 -84,7 +86,7 @@@ the
  fi
  
  move_to_original_branch
+ }
+ # ... and then we call the whole thing.
+ git_rebase__am
@@@ -179,10 -179,9 +179,10 @@@ exit_with_patch () 
        echo "$1" > "$state_dir"/stopped-sha
        make_patch $1
        git rev-parse --verify HEAD > "$amend"
 +      gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
        warn "You can amend the commit now, with"
        warn
 -      warn "  git commit --amend"
 +      warn "  git commit --amend $gpg_sign_opt_quoted"
        warn
        warn "Once you are satisfied with your changes, run"
        warn
@@@ -249,9 -248,7 +249,9 @@@ pick_one () 
  
        test -d "$rewritten" &&
                pick_one_preserving_merges "$@" && return
 -      output eval git cherry-pick "$strategy_args" $empty_args $ff "$@"
 +      output eval git cherry-pick \
 +                      ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
 +                      "$strategy_args" $empty_args $ff "$@"
  }
  
  pick_one_preserving_merges () {
                        new_parents=${new_parents# $first_parent}
                        merge_args="--no-log --no-ff"
                        if ! do_with_author output eval \
 -                      'git merge $merge_args $strategy_args -m "$msg_content" $new_parents'
 +                      'git merge ${gpg_sign_opt:+"$gpg_sign_opt"} \
 +                              $merge_args $strategy_args -m "$msg_content" $new_parents'
                        then
                                printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
                                die_with_patch $sha1 "Error redoing merge $sha1"
                        echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
                        ;;
                *)
 -                      output eval git cherry-pick "$strategy_args" "$@" ||
 +                      output eval git cherry-pick \
 +                              ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
 +                              "$strategy_args" "$@" ||
                                die_with_patch $sha1 "Could not pick $sha1"
                        ;;
                esac
@@@ -476,8 -470,7 +476,8 @@@ do_pick () 
                           --no-post-rewrite -n -q -C $1 &&
                        pick_one -n $1 &&
                        git commit --allow-empty --allow-empty-message \
 -                                 --amend --no-post-rewrite -n -q -C $1 ||
 +                                 --amend --no-post-rewrite -n -q -C $1 \
 +                                 ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                        die_with_patch $1 "Could not apply $1... $2"
        else
                pick_one $1 ||
@@@ -504,7 -497,7 +504,7 @@@ do_next () 
  
                mark_action_done
                do_pick $sha1 "$rest"
 -              git commit --amend --no-post-rewrite || {
 +              git commit --amend --no-post-rewrite ${gpg_sign_opt:+"$gpg_sign_opt"} || {
                        warn "Could not amend commit after successfully picking $sha1... $rest"
                        warn "This is most likely due to an empty commit message, or the pre-commit hook"
                        warn "failed. If the pre-commit hook failed, you may need to resolve the issue before"
                squash|s|fixup|f)
                        # This is an intermediate commit; its message will only be
                        # used in case of trouble.  So use the long version:
 -                      do_with_author output git commit --amend --no-verify -F "$squash_msg" ||
 +                      do_with_author output git commit --amend --no-verify -F "$squash_msg" \
 +                              ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                die_failed_squash $sha1 "$rest"
                        ;;
                *)
                        # This is the final command of this squash/fixup group
                        if test -f "$fixup_msg"
                        then
 -                              do_with_author git commit --amend --no-verify -F "$fixup_msg" ||
 +                              do_with_author git commit --amend --no-verify -F "$fixup_msg" \
 +                                      ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                        die_failed_squash $sha1 "$rest"
                        else
                                cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
                                rm -f "$GIT_DIR"/MERGE_MSG
 -                              do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e ||
 +                              do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e \
 +                                      ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                        die_failed_squash $sha1 "$rest"
                        fi
                        rm -f "$squash_msg" "$fixup_msg"
@@@ -820,6 -810,17 +820,17 @@@ add_exec_commands () 
        mv "$1.new" "$1"
  }
  
+ # The whole contents of this file is run by dot-sourcing it from
+ # inside a shell function.  It used to be that "return"s we see
+ # below were not inside any function, and expected to return
+ # to the function that dot-sourced us.
+ #
+ # However, FreeBSD /bin/sh misbehaves on such a construct and
+ # continues to run the statements that follow such a "return".
+ # As a work-around, we introduce an extra layer of a function
+ # here, and immediately call it after defining it.
+ git_rebase__interactive () {
  case "$action" in
  continue)
        # do we have anything to commit?
        else
                if ! test -f "$author_script"
                then
 +                      gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
                        die "You have staged changes in your working tree. If these changes are meant to be
  squashed into the previous commit, run:
  
 -  git commit --amend
 +  git commit --amend $gpg_sign_opt_quoted
  
  If they are meant to go into a new commit, run:
  
 -  git commit
 +  git commit $gpg_sign_opt_quoted
  
  In both case, once you're done, continue with:
  
                        die "\
  You have uncommitted changes in your working tree. Please, commit them
  first and then run 'git rebase --continue' again."
 -                      do_with_author git commit --amend --no-verify -F "$msg" -e ||
 +                      do_with_author git commit --amend --no-verify -F "$msg" -e \
 +                              ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                die "Could not commit staged changes."
                else
 -                      do_with_author git commit --no-verify -F "$msg" -e ||
 +                      do_with_author git commit --no-verify -F "$msg" -e \
 +                              ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                die "Could not commit staged changes."
                fi
        fi
@@@ -1055,3 -1053,7 +1066,7 @@@ GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: 
  output git checkout $onto || die_abort "could not detach HEAD"
  git update-ref ORIG_HEAD $orig_head
  do_rest
+ }
+ # ... and then we call the whole thing.
+ git_rebase__interactive
diff --combined git-rebase--merge.sh
@@@ -27,7 -27,7 +27,7 @@@ continue_merge () 
        cmt=`cat "$state_dir/current"`
        if ! git diff-index --quiet --ignore-submodules HEAD --
        then
 -              if ! git commit --no-verify -C "$cmt"
 +              if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} --no-verify -C "$cmt"
                then
                        echo "Commit failed, please do not call \"git commit\""
                        echo "directly, but instead do one of the following: "
@@@ -101,6 -101,17 +101,17 @@@ finish_rb_merge () 
        say All done.
  }
  
+ # The whole contents of this file is run by dot-sourcing it from
+ # inside a shell function.  It used to be that "return"s we see
+ # below were not inside any function, and expected to return
+ # to the function that dot-sourced us.
+ #
+ # However, FreeBSD /bin/sh misbehaves on such a construct and
+ # continues to run the statements that follow such a "return".
+ # As a work-around, we introduce an extra layer of a function
+ # here, and immediately call it after defining it.
+ git_rebase__merge () {
  case "$action" in
  continue)
        read_state
@@@ -151,3 -162,7 +162,7 @@@ d
  done
  
  finish_rb_merge
+ }
+ # ... and then we call the whole thing.
+ git_rebase__merge
diff --combined git-rebase.sh
@@@ -5,7 -5,6 +5,7 @@@
  
  SUBDIRECTORY_OK=Yes
  OPTIONS_KEEPDASHDASH=
 +OPTIONS_STUCKLONG=t
  OPTIONS_SPEC="\
  git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
  git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
@@@ -37,7 -36,6 +37,7 @@@ ignore-date!       passed to 'git am
  whitespace=!       passed to 'git apply'
  ignore-whitespace! passed to 'git apply'
  C=!                passed to 'git apply'
 +S,gpg-sign?        GPG-sign commits
   Actions:
  continue!          continue
  abort!             abort and check out the original branch
@@@ -86,7 -84,6 +86,7 @@@ preserve_merges
  autosquash=
  keep_empty=
  test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 +gpg_sign_opt=
  
  read_basic_state () {
        test -f "$state_dir/head-name" &&
                strategy_opts="$(cat "$state_dir"/strategy_opts)"
        test -f "$state_dir"/allow_rerere_autoupdate &&
                allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
 +      test -f "$state_dir"/gpg_sign_opt &&
 +              gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
  }
  
  write_basic_state () {
                "$state_dir"/strategy_opts
        test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
                "$state_dir"/allow_rerere_autoupdate
 +      test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
  }
  
  output () {
@@@ -175,22 -169,13 +175,13 @@@ You can run "git stash pop" or "git sta
        rm -rf "$state_dir"
  }
  
- run_specific_rebase_internal () {
+ run_specific_rebase () {
        if [ "$interactive_rebase" = implied ]; then
                GIT_EDITOR=:
                export GIT_EDITOR
                autosquash=
        fi
-       # On FreeBSD, the shell's "return" returns from the current
-       # function, not from the current file inclusion.
-       # run_specific_rebase_internal has the file inclusion as a
-       # last statement, so POSIX and FreeBSD's return will do the
-       # same thing.
        . git-rebase--$type
- }
- run_specific_rebase () {
-       run_specific_rebase_internal
        ret=$?
        if test $ret -eq 0
        then
                test $total_argc -eq 2 || usage
                action=${1##--}
                ;;
 -      --onto)
 -              test 2 -le "$#" || usage
 -              onto="$2"
 -              shift
 +      --onto=*)
 +              onto="${1#--onto=}"
                ;;
 -      -x)
 -              test 2 -le "$#" || usage
 -              cmd="${cmd}exec $2${LF}"
 -              shift
 +      --exec=*)
 +              cmd="${cmd}exec ${1#--exec=}${LF}"
                ;;
 -      -i)
 +      --interactive)
                interactive_rebase=explicit
                ;;
 -      -k)
 +      --keep-empty)
                keep_empty=yes
                ;;
 -      -p)
 +      --preserve-merges)
                preserve_merges=t
                test -z "$interactive_rebase" && interactive_rebase=implied
                ;;
        --no-fork-point)
                fork_point=
                ;;
 -      -M|-m)
 +      --merge)
                do_merge=t
                ;;
 -      -X)
 -              shift
 -              strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
 +      --strategy-option=*)
 +              strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}")"
                do_merge=t
                test -z "$strategy" && strategy=recursive
                ;;
 -      -s)
 -              shift
 -              strategy="$1"
 +      --strategy=*)
 +              strategy="${1#--strategy=}"
                do_merge=t
                ;;
 -      -n)
 +      --no-stat)
                diffstat=
                ;;
        --stat)
        --autostash)
                autostash=true
                ;;
 -      -v)
 +      --verbose)
                verbose=t
                diffstat=t
                GIT_QUIET=
                ;;
 -      -q)
 +      --quiet)
                GIT_QUIET=t
                git_am_opt="$git_am_opt -q"
                verbose=
                diffstat=
                ;;
 -      --whitespace)
 -              shift
 -              git_am_opt="$git_am_opt --whitespace=$1"
 -              case "$1" in
 +      --whitespace=*)
 +              git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}"
 +              case "${1#--whitespace=}" in
                fix|strip)
                        force_rebase=t
                        ;;
                git_am_opt="$git_am_opt $1"
                force_rebase=t
                ;;
 -      -C)
 -              shift
 -              git_am_opt="$git_am_opt -C$1"
 +      -C*)
 +              git_am_opt="$git_am_opt $1"
                ;;
        --root)
                rebase_root=t
                ;;
 -      -f|--no-ff)
 +      --force-rebase|--no-ff)
                force_rebase=t
                ;;
        --rerere-autoupdate|--no-rerere-autoupdate)
                allow_rerere_autoupdate="$1"
                ;;
 +      --gpg-sign)
 +              gpg_sign_opt=-S
 +              ;;
 +      --gpg-sign=*)
 +              gpg_sign_opt="-S${1#--gpg-sign=}"
 +              ;;
        --)
                shift
                break
@@@ -453,10 -440,6 +444,10 @@@ the
                test "$fork_point" = auto && fork_point=t
                ;;
        *)      upstream_name="$1"
 +              if test "$upstream_name" = "-"
 +              then
 +                      upstream_name="@{-1}"
 +              fi
                shift
                ;;
        esac