git-rebase.shon commit rebase: add --quit to cleanup rebase, leave everything else untouched (9512177)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano.
   4#
   5
   6SUBDIRECTORY_OK=Yes
   7OPTIONS_KEEPDASHDASH=
   8OPTIONS_STUCKLONG=t
   9OPTIONS_SPEC="\
  10git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
  11git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
  12git-rebase --continue | --abort | --skip | --edit-todo
  13--
  14 Available options are
  15v,verbose!         display a diffstat of what changed upstream
  16q,quiet!           be quiet. implies --no-stat
  17autostash          automatically stash/stash pop before and after
  18fork-point         use 'merge-base --fork-point' to refine upstream
  19onto=!             rebase onto given branch instead of upstream
  20p,preserve-merges! try to recreate merges instead of ignoring them
  21s,strategy=!       use the given merge strategy
  22no-ff!             cherry-pick all commits, even if unchanged
  23m,merge!           use merging strategies to rebase
  24i,interactive!     let the user edit the list of commits to rebase
  25x,exec=!           add exec lines after each commit of the editable list
  26k,keep-empty       preserve empty commits during rebase
  27f,force-rebase!    force rebase even if branch is up to date
  28X,strategy-option=! pass the argument through to the merge strategy
  29stat!              display a diffstat of what changed upstream
  30n,no-stat!         do not show diffstat of what changed upstream
  31verify             allow pre-rebase hook to run
  32rerere-autoupdate  allow rerere to update index with resolved conflicts
  33root!              rebase all reachable commits up to the root(s)
  34autosquash         move commits that begin with squash!/fixup! under -i
  35committer-date-is-author-date! passed to 'git am'
  36ignore-date!       passed to 'git am'
  37whitespace=!       passed to 'git apply'
  38ignore-whitespace! passed to 'git apply'
  39C=!                passed to 'git apply'
  40S,gpg-sign?        GPG-sign commits
  41 Actions:
  42continue!          continue
  43abort!             abort and check out the original branch
  44skip!              skip current patch and continue
  45edit-todo!         edit the todo list during an interactive rebase
  46quit!              abort but keep HEAD where it is
  47"
  48. git-sh-setup
  49. git-sh-i18n
  50set_reflog_action rebase
  51require_work_tree_exists
  52cd_to_toplevel
  53
  54LF='
  55'
  56ok_to_skip_pre_rebase=
  57resolvemsg="
  58$(gettext 'When you have resolved this problem, run "git rebase --continue".
  59If you prefer to skip this patch, run "git rebase --skip" instead.
  60To check out the original branch and stop rebasing, run "git rebase --abort".')
  61"
  62unset onto
  63unset restrict_revision
  64cmd=
  65strategy=
  66strategy_opts=
  67do_merge=
  68merge_dir="$GIT_DIR"/rebase-merge
  69apply_dir="$GIT_DIR"/rebase-apply
  70verbose=
  71diffstat=
  72test "$(git config --bool rebase.stat)" = true && diffstat=t
  73autostash="$(git config --bool rebase.autostash || echo false)"
  74fork_point=auto
  75git_am_opt=
  76rebase_root=
  77force_rebase=
  78allow_rerere_autoupdate=
  79# Non-empty if a rebase was in progress when 'git rebase' was invoked
  80in_progress=
  81# One of {am, merge, interactive}
  82type=
  83# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
  84state_dir=
  85# One of {'', continue, skip, abort}, as parsed from command line
  86action=
  87preserve_merges=
  88autosquash=
  89keep_empty=
  90test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
  91gpg_sign_opt=
  92
  93read_basic_state () {
  94        test -f "$state_dir/head-name" &&
  95        test -f "$state_dir/onto" &&
  96        head_name=$(cat "$state_dir"/head-name) &&
  97        onto=$(cat "$state_dir"/onto) &&
  98        # We always write to orig-head, but interactive rebase used to write to
  99        # head. Fall back to reading from head to cover for the case that the
 100        # user upgraded git with an ongoing interactive rebase.
 101        if test -f "$state_dir"/orig-head
 102        then
 103                orig_head=$(cat "$state_dir"/orig-head)
 104        else
 105                orig_head=$(cat "$state_dir"/head)
 106        fi &&
 107        GIT_QUIET=$(cat "$state_dir"/quiet) &&
 108        test -f "$state_dir"/verbose && verbose=t
 109        test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
 110        test -f "$state_dir"/strategy_opts &&
 111                strategy_opts="$(cat "$state_dir"/strategy_opts)"
 112        test -f "$state_dir"/allow_rerere_autoupdate &&
 113                allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
 114        test -f "$state_dir"/gpg_sign_opt &&
 115                gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
 116}
 117
 118write_basic_state () {
 119        echo "$head_name" > "$state_dir"/head-name &&
 120        echo "$onto" > "$state_dir"/onto &&
 121        echo "$orig_head" > "$state_dir"/orig-head &&
 122        echo "$GIT_QUIET" > "$state_dir"/quiet &&
 123        test t = "$verbose" && : > "$state_dir"/verbose
 124        test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
 125        test -n "$strategy_opts" && echo "$strategy_opts" > \
 126                "$state_dir"/strategy_opts
 127        test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
 128                "$state_dir"/allow_rerere_autoupdate
 129        test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
 130}
 131
 132output () {
 133        case "$verbose" in
 134        '')
 135                output=$("$@" 2>&1 )
 136                status=$?
 137                test $status != 0 && printf "%s\n" "$output"
 138                return $status
 139                ;;
 140        *)
 141                "$@"
 142                ;;
 143        esac
 144}
 145
 146move_to_original_branch () {
 147        case "$head_name" in
 148        refs/*)
 149                message="rebase finished: $head_name onto $onto"
 150                git update-ref -m "$message" \
 151                        $head_name $(git rev-parse HEAD) $orig_head &&
 152                git symbolic-ref \
 153                        -m "rebase finished: returning to $head_name" \
 154                        HEAD $head_name ||
 155                die "$(gettext "Could not move back to $head_name")"
 156                ;;
 157        esac
 158}
 159
 160apply_autostash () {
 161        if test -f "$state_dir/autostash"
 162        then
 163                stash_sha1=$(cat "$state_dir/autostash")
 164                if git stash apply $stash_sha1 2>&1 >/dev/null
 165                then
 166                        echo "$(gettext 'Applied autostash.')"
 167                else
 168                        git stash store -m "autostash" -q $stash_sha1 ||
 169                        die "$(eval_gettext "Cannot store \$stash_sha1")"
 170                        gettext 'Applying autostash resulted in conflicts.
 171Your changes are safe in the stash.
 172You can run "git stash pop" or "git stash drop" at any time.
 173'
 174                fi
 175        fi
 176}
 177
 178finish_rebase () {
 179        apply_autostash &&
 180        { git gc --auto || true; } &&
 181        rm -rf "$state_dir"
 182}
 183
 184run_specific_rebase () {
 185        if [ "$interactive_rebase" = implied ]; then
 186                GIT_EDITOR=:
 187                export GIT_EDITOR
 188                autosquash=
 189        fi
 190        . git-rebase--$type
 191        ret=$?
 192        if test $ret -eq 0
 193        then
 194                finish_rebase
 195        elif test $ret -eq 2 # special exit status for rebase -i
 196        then
 197                apply_autostash &&
 198                rm -rf "$state_dir" &&
 199                die "Nothing to do"
 200        fi
 201        exit $ret
 202}
 203
 204run_pre_rebase_hook () {
 205        if test -z "$ok_to_skip_pre_rebase" &&
 206           test -x "$(git rev-parse --git-path hooks/pre-rebase)"
 207        then
 208                "$(git rev-parse --git-path hooks/pre-rebase)" ${1+"$@"} ||
 209                die "$(gettext "The pre-rebase hook refused to rebase.")"
 210        fi
 211}
 212
 213test -f "$apply_dir"/applying &&
 214        die "$(gettext "It looks like git-am is in progress. Cannot rebase.")"
 215
 216if test -d "$apply_dir"
 217then
 218        type=am
 219        state_dir="$apply_dir"
 220elif test -d "$merge_dir"
 221then
 222        if test -f "$merge_dir"/interactive
 223        then
 224                type=interactive
 225                interactive_rebase=explicit
 226        else
 227                type=merge
 228        fi
 229        state_dir="$merge_dir"
 230fi
 231test -n "$type" && in_progress=t
 232
 233total_argc=$#
 234while test $# != 0
 235do
 236        case "$1" in
 237        --no-verify)
 238                ok_to_skip_pre_rebase=yes
 239                ;;
 240        --verify)
 241                ok_to_skip_pre_rebase=
 242                ;;
 243        --continue|--skip|--abort|--quit|--edit-todo)
 244                test $total_argc -eq 2 || usage
 245                action=${1##--}
 246                ;;
 247        --onto=*)
 248                onto="${1#--onto=}"
 249                ;;
 250        --exec=*)
 251                cmd="${cmd}exec ${1#--exec=}${LF}"
 252                ;;
 253        --interactive)
 254                interactive_rebase=explicit
 255                ;;
 256        --keep-empty)
 257                keep_empty=yes
 258                ;;
 259        --preserve-merges)
 260                preserve_merges=t
 261                test -z "$interactive_rebase" && interactive_rebase=implied
 262                ;;
 263        --autosquash)
 264                autosquash=t
 265                ;;
 266        --no-autosquash)
 267                autosquash=
 268                ;;
 269        --fork-point)
 270                fork_point=t
 271                ;;
 272        --no-fork-point)
 273                fork_point=
 274                ;;
 275        --merge)
 276                do_merge=t
 277                ;;
 278        --strategy-option=*)
 279                strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}")"
 280                do_merge=t
 281                test -z "$strategy" && strategy=recursive
 282                ;;
 283        --strategy=*)
 284                strategy="${1#--strategy=}"
 285                do_merge=t
 286                ;;
 287        --no-stat)
 288                diffstat=
 289                ;;
 290        --stat)
 291                diffstat=t
 292                ;;
 293        --autostash)
 294                autostash=true
 295                ;;
 296        --no-autostash)
 297                autostash=false
 298                ;;
 299        --verbose)
 300                verbose=t
 301                diffstat=t
 302                GIT_QUIET=
 303                ;;
 304        --quiet)
 305                GIT_QUIET=t
 306                git_am_opt="$git_am_opt -q"
 307                verbose=
 308                diffstat=
 309                ;;
 310        --whitespace=*)
 311                git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}"
 312                case "${1#--whitespace=}" in
 313                fix|strip)
 314                        force_rebase=t
 315                        ;;
 316                esac
 317                ;;
 318        --ignore-whitespace)
 319                git_am_opt="$git_am_opt $1"
 320                ;;
 321        --committer-date-is-author-date|--ignore-date)
 322                git_am_opt="$git_am_opt $1"
 323                force_rebase=t
 324                ;;
 325        -C*)
 326                git_am_opt="$git_am_opt $1"
 327                ;;
 328        --root)
 329                rebase_root=t
 330                ;;
 331        --force-rebase|--no-ff)
 332                force_rebase=t
 333                ;;
 334        --rerere-autoupdate|--no-rerere-autoupdate)
 335                allow_rerere_autoupdate="$1"
 336                ;;
 337        --gpg-sign)
 338                gpg_sign_opt=-S
 339                ;;
 340        --gpg-sign=*)
 341                gpg_sign_opt="-S${1#--gpg-sign=}"
 342                ;;
 343        --)
 344                shift
 345                break
 346                ;;
 347        esac
 348        shift
 349done
 350test $# -gt 2 && usage
 351
 352if test -n "$cmd" &&
 353   test "$interactive_rebase" != explicit
 354then
 355        die "$(gettext "The --exec option must be used with the --interactive option")"
 356fi
 357
 358if test -n "$action"
 359then
 360        test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
 361        # Only interactive rebase uses detailed reflog messages
 362        if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
 363        then
 364                GIT_REFLOG_ACTION="rebase -i ($action)"
 365                export GIT_REFLOG_ACTION
 366        fi
 367fi
 368
 369if test "$action" = "edit-todo" && test "$type" != "interactive"
 370then
 371        die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
 372fi
 373
 374case "$action" in
 375continue)
 376        # Sanity check
 377        git rev-parse --verify HEAD >/dev/null ||
 378                die "$(gettext "Cannot read HEAD")"
 379        git update-index --ignore-submodules --refresh &&
 380        git diff-files --quiet --ignore-submodules || {
 381                echo "$(gettext "You must edit all merge conflicts and then
 382mark them as resolved using git add")"
 383                exit 1
 384        }
 385        read_basic_state
 386        run_specific_rebase
 387        ;;
 388skip)
 389        output git reset --hard HEAD || exit $?
 390        read_basic_state
 391        run_specific_rebase
 392        ;;
 393abort)
 394        git rerere clear
 395        read_basic_state
 396        case "$head_name" in
 397        refs/*)
 398                git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
 399                die "$(eval_gettext "Could not move back to \$head_name")"
 400                ;;
 401        esac
 402        output git reset --hard $orig_head
 403        finish_rebase
 404        exit
 405        ;;
 406quit)
 407        exec rm -rf "$state_dir"
 408        ;;
 409edit-todo)
 410        run_specific_rebase
 411        ;;
 412esac
 413
 414# Make sure no rebase is in progress
 415if test -n "$in_progress"
 416then
 417        state_dir_base=${state_dir##*/}
 418        cmd_live_rebase="git rebase (--continue | --abort | --skip)"
 419        cmd_clear_stale_rebase="rm -fr \"$state_dir\""
 420        die "
 421$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
 422I wonder if you are in the middle of another rebase.  If that is the
 423case, please try
 424        $cmd_live_rebase
 425If that is not the case, please
 426        $cmd_clear_stale_rebase
 427and run me again.  I am stopping in case you still have something
 428valuable there.')"
 429fi
 430
 431if test -n "$rebase_root" && test -z "$onto"
 432then
 433        test -z "$interactive_rebase" && interactive_rebase=implied
 434fi
 435
 436if test -n "$interactive_rebase"
 437then
 438        type=interactive
 439        state_dir="$merge_dir"
 440elif test -n "$do_merge"
 441then
 442        type=merge
 443        state_dir="$merge_dir"
 444else
 445        type=am
 446        state_dir="$apply_dir"
 447fi
 448
 449if test -z "$rebase_root"
 450then
 451        case "$#" in
 452        0)
 453                if ! upstream_name=$(git rev-parse --symbolic-full-name \
 454                        --verify -q @{upstream} 2>/dev/null)
 455                then
 456                        . git-parse-remote
 457                        error_on_missing_default_upstream "rebase" "rebase" \
 458                                "against" "git rebase <branch>"
 459                fi
 460
 461                test "$fork_point" = auto && fork_point=t
 462                ;;
 463        *)      upstream_name="$1"
 464                if test "$upstream_name" = "-"
 465                then
 466                        upstream_name="@{-1}"
 467                fi
 468                shift
 469                ;;
 470        esac
 471        upstream=$(peel_committish "${upstream_name}") ||
 472        die "$(eval_gettext "invalid upstream \$upstream_name")"
 473        upstream_arg="$upstream_name"
 474else
 475        if test -z "$onto"
 476        then
 477                empty_tree=$(git hash-object -t tree /dev/null)
 478                onto=$(git commit-tree $empty_tree </dev/null)
 479                squash_onto="$onto"
 480        fi
 481        unset upstream_name
 482        unset upstream
 483        test $# -gt 1 && usage
 484        upstream_arg=--root
 485fi
 486
 487# Make sure the branch to rebase onto is valid.
 488onto_name=${onto-"$upstream_name"}
 489case "$onto_name" in
 490*...*)
 491        if      left=${onto_name%...*} right=${onto_name#*...} &&
 492                onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
 493        then
 494                case "$onto" in
 495                ?*"$LF"?*)
 496                        die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
 497                        ;;
 498                '')
 499                        die "$(eval_gettext "\$onto_name: there is no merge base")"
 500                        ;;
 501                esac
 502        else
 503                die "$(eval_gettext "\$onto_name: there is no merge base")"
 504        fi
 505        ;;
 506*)
 507        onto=$(peel_committish "$onto_name") ||
 508        die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
 509        ;;
 510esac
 511
 512# If the branch to rebase is given, that is the branch we will rebase
 513# $branch_name -- branch being rebased, or HEAD (already detached)
 514# $orig_head -- commit object name of tip of the branch before rebasing
 515# $head_name -- refs/heads/<that-branch> or "detached HEAD"
 516switch_to=
 517case "$#" in
 5181)
 519        # Is it "rebase other $branchname" or "rebase other $commit"?
 520        branch_name="$1"
 521        switch_to="$1"
 522
 523        if git show-ref --verify --quiet -- "refs/heads/$1" &&
 524           orig_head=$(git rev-parse -q --verify "refs/heads/$1")
 525        then
 526                head_name="refs/heads/$1"
 527        elif orig_head=$(git rev-parse -q --verify "$1")
 528        then
 529                head_name="detached HEAD"
 530        else
 531                die "$(eval_gettext "fatal: no such branch: \$branch_name")"
 532        fi
 533        ;;
 5340)
 535        # Do not need to switch branches, we are already on it.
 536        if branch_name=$(git symbolic-ref -q HEAD)
 537        then
 538                head_name=$branch_name
 539                branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)')
 540        else
 541                head_name="detached HEAD"
 542                branch_name=HEAD ;# detached
 543        fi
 544        orig_head=$(git rev-parse --verify HEAD) || exit
 545        ;;
 546*)
 547        die "BUG: unexpected number of arguments left to parse"
 548        ;;
 549esac
 550
 551if test "$fork_point" = t
 552then
 553        new_upstream=$(git merge-base --fork-point "$upstream_name" \
 554                        "${switch_to:-HEAD}")
 555        if test -n "$new_upstream"
 556        then
 557                restrict_revision=$new_upstream
 558        fi
 559fi
 560
 561if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
 562then
 563        stash_sha1=$(git stash create "autostash") ||
 564        die "$(gettext 'Cannot autostash')"
 565
 566        mkdir -p "$state_dir" &&
 567        echo $stash_sha1 >"$state_dir/autostash" &&
 568        stash_abbrev=$(git rev-parse --short $stash_sha1) &&
 569        echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
 570        git reset --hard
 571fi
 572
 573require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
 574
 575# Now we are rebasing commits $upstream..$orig_head (or with --root,
 576# everything leading up to $orig_head) on top of $onto
 577
 578# Check if we are already based on $onto with linear history,
 579# but this should be done only when upstream and onto are the same
 580# and if this is not an interactive rebase.
 581mb=$(git merge-base "$onto" "$orig_head")
 582if test "$type" != interactive && test "$upstream" = "$onto" &&
 583        test "$mb" = "$onto" && test -z "$restrict_revision" &&
 584        # linear history?
 585        ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
 586then
 587        if test -z "$force_rebase"
 588        then
 589                # Lazily switch to the target branch if needed...
 590                test -z "$switch_to" ||
 591                GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \
 592                        git checkout -q "$switch_to" --
 593                say "$(eval_gettext "Current branch \$branch_name is up to date.")"
 594                finish_rebase
 595                exit 0
 596        else
 597                say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
 598        fi
 599fi
 600
 601# If a hook exists, give it a chance to interrupt
 602run_pre_rebase_hook "$upstream_arg" "$@"
 603
 604if test -n "$diffstat"
 605then
 606        if test -n "$verbose"
 607        then
 608                echo "$(eval_gettext "Changes from \$mb to \$onto:")"
 609        fi
 610        # We want color (if set), but no pager
 611        GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
 612fi
 613
 614test "$type" = interactive && run_specific_rebase
 615
 616# Detach HEAD and reset the tree
 617say "$(gettext "First, rewinding head to replay your work on top of it...")"
 618
 619GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
 620        git checkout -q "$onto^0" || die "could not detach HEAD"
 621git update-ref ORIG_HEAD $orig_head
 622
 623# If the $onto is a proper descendant of the tip of the branch, then
 624# we just fast-forwarded.
 625if test "$mb" = "$orig_head"
 626then
 627        say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
 628        move_to_original_branch
 629        finish_rebase
 630        exit 0
 631fi
 632
 633if test -n "$rebase_root"
 634then
 635        revisions="$onto..$orig_head"
 636else
 637        revisions="${restrict_revision-$upstream}..$orig_head"
 638fi
 639
 640run_specific_rebase