bash prompt: return early from __git_ps1() when not in a git repository
[gitweb.git] / git-rebase.sh
index d6c52e6f9041bed6bbd575f51e604cada7dfb842..2d5c2bd0fcf773367b892fbb993704e5f2089c64 100755 (executable)
@@ -8,11 +8,12 @@ OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
 git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
 git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
-git-rebase [-i] --continue | --abort | --skip
+git-rebase --continue | --abort | --skip | --edit-todo
 --
  Available options are
 v,verbose!         display a diffstat of what changed upstream
 q,quiet!           be quiet. implies --no-stat
+autostash!         automatically stash/stash pop before and after
 onto=!             rebase onto given branch instead of upstream
 p,preserve-merges! try to recreate merges instead of ignoring them
 s,strategy=!       use the given merge strategy
@@ -38,6 +39,7 @@ C=!                passed to 'git apply'
 continue!          continue
 abort!             abort and check out the original branch
 skip!              skip current patch and continue
+edit-todo!         edit the todo list during an interactive rebase
 "
 . git-sh-setup
 . git-sh-i18n
@@ -63,6 +65,7 @@ apply_dir="$GIT_DIR"/rebase-apply
 verbose=
 diffstat=
 test "$(git config --bool rebase.stat)" = true && diffstat=t
+autostash="$(git config --bool rebase.autostash || echo false)"
 git_am_opt=
 rebase_root=
 force_rebase=
@@ -81,6 +84,8 @@ keep_empty=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 
 read_basic_state () {
+       test -f "$state_dir/head-name" &&
+       test -f "$state_dir/onto" &&
        head_name=$(cat "$state_dir"/head-name) &&
        onto=$(cat "$state_dir"/onto) &&
        # We always write to orig-head, but interactive rebase used to write to
@@ -142,6 +147,29 @@ move_to_original_branch () {
        esac
 }
 
+finish_rebase () {
+       if test -f "$state_dir/autostash"
+       then
+               stash_sha1=$(cat "$state_dir/autostash")
+               if git stash apply $stash_sha1 2>&1 >/dev/null
+               then
+                       echo "$(gettext 'Applied autostash.')"
+               else
+                       ref_stash=refs/stash &&
+                       >>"$GIT_DIR/logs/$ref_stash" &&
+                       git update-ref -m "autostash" $ref_stash $stash_sha1 ||
+                       die "$(eval_gettext 'Cannot store $stash_sha1')"
+
+                       gettext 'Applying autostash resulted in conflicts.
+Your changes are safe in the stash.
+You can run "git stash pop" or "git stash drop" it at any time.
+'
+               fi
+       fi
+       git gc --auto &&
+       rm -rf "$state_dir"
+}
+
 run_specific_rebase () {
        if [ "$interactive_rebase" = implied ]; then
                GIT_EDITOR=:
@@ -149,6 +177,12 @@ run_specific_rebase () {
                autosquash=
        fi
        . git-rebase--$type
+       ret=$?
+       if test $ret -eq 0
+       then
+               finish_rebase
+       fi
+       exit $ret
 }
 
 run_pre_rebase_hook () {
@@ -190,7 +224,7 @@ do
        --verify)
                ok_to_skip_pre_rebase=
                ;;
-       --continue|--skip|--abort)
+       --continue|--skip|--abort|--edit-todo)
                test $total_argc -eq 2 || usage
                action=${1##--}
                ;;
@@ -240,6 +274,9 @@ do
        --stat)
                diffstat=t
                ;;
+       --autostash)
+               autostash=true
+               ;;
        -v)
                verbose=t
                diffstat=t
@@ -306,6 +343,11 @@ then
        fi
 fi
 
+if test "$action" = "edit-todo" && test "$type" != "interactive"
+then
+       die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
+fi
+
 case "$action" in
 continue)
        # Sanity check
@@ -335,9 +377,12 @@ abort)
                ;;
        esac
        output git reset --hard $orig_head
-       rm -r "$state_dir"
+       finish_rebase
        exit
        ;;
+edit-todo)
+       run_specific_rebase
+       ;;
 esac
 
 # Make sure no rebase is in progress
@@ -471,6 +516,18 @@ case "$#" in
        ;;
 esac
 
+if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
+then
+       stash_sha1=$(git stash create "autostash") ||
+       die "$(gettext 'Cannot autostash')"
+
+       mkdir -p "$state_dir" &&
+       echo $stash_sha1 >"$state_dir/autostash" &&
+       stash_abbrev=$(git rev-parse --short $stash_sha1) &&
+       echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
+       git reset --hard
+fi
+
 require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
 
 # Now we are rebasing commits $upstream..$orig_head (or with --root,
@@ -490,6 +547,7 @@ then
                # Lazily switch to the target branch if needed...
                test -z "$switch_to" || git checkout "$switch_to" --
                say "$(eval_gettext "Current branch \$branch_name is up to date.")"
+               finish_rebase
                exit 0
        else
                say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
@@ -522,6 +580,7 @@ if test "$mb" = "$orig_head"
 then
        say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
        move_to_original_branch
+       finish_rebase
        exit 0
 fi