git-compat-util.h: don't define _XOPEN_SOURCE on cygwin
[gitweb.git] / git-rebase.sh
index 07e2bd48dc60811db7ee5e44c127aa0480c0ec1d..55da9db818665f39ed205d3c77352987e3ca9963 100755 (executable)
@@ -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>]
@@ -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
@@ -57,6 +59,7 @@ If you prefer to skip this patch, run "git rebase --skip" instead.
 To check out the original branch and stop rebasing, run "git rebase --abort".')
 "
 unset onto
+unset restrict_revision
 cmd=
 strategy=
 strategy_opts=
@@ -84,6 +87,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" &&
@@ -106,6 +110,8 @@ read_basic_state () {
                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 () {
@@ -119,6 +125,7 @@ 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 () {
@@ -149,7 +156,7 @@ move_to_original_branch () {
        esac
 }
 
-finish_rebase () {
+apply_autostash () {
        if test -f "$state_dir/autostash"
        then
                stash_sha1=$(cat "$state_dir/autostash")
@@ -165,6 +172,10 @@ You can run "git stash pop" or "git stash drop" at any time.
 '
                fi
        fi
+}
+
+finish_rebase () {
+       apply_autostash &&
        git gc --auto &&
        rm -rf "$state_dir"
 }
@@ -180,6 +191,11 @@ run_specific_rebase () {
        if test $ret -eq 0
        then
                finish_rebase
+       elif test $ret -eq 2 # special exit status for rebase -i
+       then
+               apply_autostash &&
+               rm -rf "$state_dir" &&
+               die "Nothing to do"
        fi
        exit $ret
 }
@@ -227,23 +243,19 @@ do
                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
                ;;
@@ -259,21 +271,19 @@ do
        --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)
@@ -282,21 +292,20 @@ do
        --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
                        ;;
@@ -309,19 +318,24 @@ do
                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
@@ -440,6 +454,10 @@ then
                test "$fork_point" = auto && fork_point=t
                ;;
        *)      upstream_name="$1"
+               if test "$upstream_name" = "-"
+               then
+                       upstream_name="@{-1}"
+               fi
                shift
                ;;
        esac
@@ -449,8 +467,8 @@ then
 else
        if test -z "$onto"
        then
-               empty_tree=`git hash-object -t tree /dev/null`
-               onto=`git commit-tree $empty_tree </dev/null`
+               empty_tree=$(git hash-object -t tree /dev/null)
+               onto=$(git commit-tree $empty_tree </dev/null)
                squash_onto="$onto"
        fi
        unset upstream_name
@@ -508,10 +526,10 @@ case "$#" in
        ;;
 0)
        # Do not need to switch branches, we are already on it.
-       if branch_name=`git symbolic-ref -q HEAD`
+       if branch_name=$(git symbolic-ref -q HEAD)
        then
                head_name=$branch_name
-               branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
+               branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)')
        else
                head_name="detached HEAD"
                branch_name=HEAD ;# detached
@@ -529,7 +547,7 @@ then
                        "${switch_to:-HEAD}")
        if test -n "$new_upstream"
        then
-               upstream=$new_upstream
+               restrict_revision=$new_upstream
        fi
 fi
 
@@ -555,7 +573,7 @@ require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
 # and if this is not an interactive rebase.
 mb=$(git merge-base "$onto" "$orig_head")
 if test "$type" != interactive && test "$upstream" = "$onto" &&
-       test "$mb" = "$onto" &&
+       test "$mb" = "$onto" && test -z "$restrict_revision" &&
        # linear history?
        ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
 then
@@ -609,7 +627,7 @@ if test -n "$rebase_root"
 then
        revisions="$onto..$orig_head"
 else
-       revisions="$upstream..$orig_head"
+       revisions="${restrict_revision-$upstream}..$orig_head"
 fi
 
 run_specific_rebase