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