3b5521108180f196a0118d779e0ed1ee844b3598
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano.
   4#
   5
   6SUBDIRECTORY_OK=Yes
   7OPTIONS_KEEPDASHDASH=
   8OPTIONS_STUCKLONG=
   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="$2"
 242                shift
 243                ;;
 244        -x)
 245                cmd="${cmd}exec $2${LF}"
 246                shift
 247                ;;
 248        -i)
 249                interactive_rebase=explicit
 250                ;;
 251        -k)
 252                keep_empty=yes
 253                ;;
 254        -p)
 255                preserve_merges=t
 256                test -z "$interactive_rebase" && interactive_rebase=implied
 257                ;;
 258        --autosquash)
 259                autosquash=t
 260                ;;
 261        --no-autosquash)
 262                autosquash=
 263                ;;
 264        --fork-point)
 265                fork_point=t
 266                ;;
 267        --no-fork-point)
 268                fork_point=
 269                ;;
 270        -m)
 271                do_merge=t
 272                ;;
 273        -X)
 274                shift
 275                strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
 276                do_merge=t
 277                test -z "$strategy" && strategy=recursive
 278                ;;
 279        -s)
 280                shift
 281                strategy="$1"
 282                do_merge=t
 283                ;;
 284        -n)
 285                diffstat=
 286                ;;
 287        --stat)
 288                diffstat=t
 289                ;;
 290        --autostash)
 291                autostash=true
 292                ;;
 293        -v)
 294                verbose=t
 295                diffstat=t
 296                GIT_QUIET=
 297                ;;
 298        -q)
 299                GIT_QUIET=t
 300                git_am_opt="$git_am_opt -q"
 301                verbose=
 302                diffstat=
 303                ;;
 304        --whitespace)
 305                shift
 306                git_am_opt="$git_am_opt --whitespace=$1"
 307                case "$1" in
 308                fix|strip)
 309                        force_rebase=t
 310                        ;;
 311                esac
 312                ;;
 313        --ignore-whitespace)
 314                git_am_opt="$git_am_opt $1"
 315                ;;
 316        --committer-date-is-author-date|--ignore-date)
 317                git_am_opt="$git_am_opt $1"
 318                force_rebase=t
 319                ;;
 320        -C)
 321                shift
 322                git_am_opt="$git_am_opt -C$1"
 323                ;;
 324        --root)
 325                rebase_root=t
 326                ;;
 327        -f|--no-ff)
 328                force_rebase=t
 329                ;;
 330        --rerere-autoupdate|--no-rerere-autoupdate)
 331                allow_rerere_autoupdate="$1"
 332                ;;
 333        --)
 334                shift
 335                break
 336                ;;
 337        esac
 338        shift
 339done
 340test $# -gt 2 && usage
 341
 342if test -n "$cmd" &&
 343   test "$interactive_rebase" != explicit
 344then
 345        die "$(gettext "The --exec option must be used with the --interactive option")"
 346fi
 347
 348if test -n "$action"
 349then
 350        test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
 351        # Only interactive rebase uses detailed reflog messages
 352        if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
 353        then
 354                GIT_REFLOG_ACTION="rebase -i ($action)"
 355                export GIT_REFLOG_ACTION
 356        fi
 357fi
 358
 359if test "$action" = "edit-todo" && test "$type" != "interactive"
 360then
 361        die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
 362fi
 363
 364case "$action" in
 365continue)
 366        # Sanity check
 367        git rev-parse --verify HEAD >/dev/null ||
 368                die "$(gettext "Cannot read HEAD")"
 369        git update-index --ignore-submodules --refresh &&
 370        git diff-files --quiet --ignore-submodules || {
 371                echo "$(gettext "You must edit all merge conflicts and then
 372mark them as resolved using git add")"
 373                exit 1
 374        }
 375        read_basic_state
 376        run_specific_rebase
 377        ;;
 378skip)
 379        output git reset --hard HEAD || exit $?
 380        read_basic_state
 381        run_specific_rebase
 382        ;;
 383abort)
 384        git rerere clear
 385        read_basic_state
 386        case "$head_name" in
 387        refs/*)
 388                git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
 389                die "$(eval_gettext "Could not move back to \$head_name")"
 390                ;;
 391        esac
 392        output git reset --hard $orig_head
 393        finish_rebase
 394        exit
 395        ;;
 396edit-todo)
 397        run_specific_rebase
 398        ;;
 399esac
 400
 401# Make sure no rebase is in progress
 402if test -n "$in_progress"
 403then
 404        state_dir_base=${state_dir##*/}
 405        cmd_live_rebase="git rebase (--continue | --abort | --skip)"
 406        cmd_clear_stale_rebase="rm -fr \"$state_dir\""
 407        die "
 408$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
 409I wonder if you are in the middle of another rebase.  If that is the
 410case, please try
 411        $cmd_live_rebase
 412If that is not the case, please
 413        $cmd_clear_stale_rebase
 414and run me again.  I am stopping in case you still have something
 415valuable there.')"
 416fi
 417
 418if test -n "$rebase_root" && test -z "$onto"
 419then
 420        test -z "$interactive_rebase" && interactive_rebase=implied
 421fi
 422
 423if test -n "$interactive_rebase"
 424then
 425        type=interactive
 426        state_dir="$merge_dir"
 427elif test -n "$do_merge"
 428then
 429        type=merge
 430        state_dir="$merge_dir"
 431else
 432        type=am
 433        state_dir="$apply_dir"
 434fi
 435
 436if test -z "$rebase_root"
 437then
 438        case "$#" in
 439        0)
 440                if ! upstream_name=$(git rev-parse --symbolic-full-name \
 441                        --verify -q @{upstream} 2>/dev/null)
 442                then
 443                        . git-parse-remote
 444                        error_on_missing_default_upstream "rebase" "rebase" \
 445                                "against" "git rebase <branch>"
 446                fi
 447
 448                test "$fork_point" = auto && fork_point=t
 449                ;;
 450        *)      upstream_name="$1"
 451                shift
 452                ;;
 453        esac
 454        upstream=$(peel_committish "${upstream_name}") ||
 455        die "$(eval_gettext "invalid upstream \$upstream_name")"
 456        upstream_arg="$upstream_name"
 457else
 458        if test -z "$onto"
 459        then
 460                empty_tree=`git hash-object -t tree /dev/null`
 461                onto=`git commit-tree $empty_tree </dev/null`
 462                squash_onto="$onto"
 463        fi
 464        unset upstream_name
 465        unset upstream
 466        test $# -gt 1 && usage
 467        upstream_arg=--root
 468fi
 469
 470# Make sure the branch to rebase onto is valid.
 471onto_name=${onto-"$upstream_name"}
 472case "$onto_name" in
 473*...*)
 474        if      left=${onto_name%...*} right=${onto_name#*...} &&
 475                onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
 476        then
 477                case "$onto" in
 478                ?*"$LF"?*)
 479                        die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
 480                        ;;
 481                '')
 482                        die "$(eval_gettext "\$onto_name: there is no merge base")"
 483                        ;;
 484                esac
 485        else
 486                die "$(eval_gettext "\$onto_name: there is no merge base")"
 487        fi
 488        ;;
 489*)
 490        onto=$(peel_committish "$onto_name") ||
 491        die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
 492        ;;
 493esac
 494
 495# If the branch to rebase is given, that is the branch we will rebase
 496# $branch_name -- branch being rebased, or HEAD (already detached)
 497# $orig_head -- commit object name of tip of the branch before rebasing
 498# $head_name -- refs/heads/<that-branch> or "detached HEAD"
 499switch_to=
 500case "$#" in
 5011)
 502        # Is it "rebase other $branchname" or "rebase other $commit"?
 503        branch_name="$1"
 504        switch_to="$1"
 505
 506        if git show-ref --verify --quiet -- "refs/heads/$1" &&
 507           orig_head=$(git rev-parse -q --verify "refs/heads/$1")
 508        then
 509                head_name="refs/heads/$1"
 510        elif orig_head=$(git rev-parse -q --verify "$1")
 511        then
 512                head_name="detached HEAD"
 513        else
 514                die "$(eval_gettext "fatal: no such branch: \$branch_name")"
 515        fi
 516        ;;
 5170)
 518        # Do not need to switch branches, we are already on it.
 519        if branch_name=`git symbolic-ref -q HEAD`
 520        then
 521                head_name=$branch_name
 522                branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
 523        else
 524                head_name="detached HEAD"
 525                branch_name=HEAD ;# detached
 526        fi
 527        orig_head=$(git rev-parse --verify HEAD) || exit
 528        ;;
 529*)
 530        die "BUG: unexpected number of arguments left to parse"
 531        ;;
 532esac
 533
 534if test "$fork_point" = t
 535then
 536        new_upstream=$(git merge-base --fork-point "$upstream_name" \
 537                        "${switch_to:-HEAD}")
 538        if test -n "$new_upstream"
 539        then
 540                upstream=$new_upstream
 541        fi
 542fi
 543
 544if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
 545then
 546        stash_sha1=$(git stash create "autostash") ||
 547        die "$(gettext 'Cannot autostash')"
 548
 549        mkdir -p "$state_dir" &&
 550        echo $stash_sha1 >"$state_dir/autostash" &&
 551        stash_abbrev=$(git rev-parse --short $stash_sha1) &&
 552        echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
 553        git reset --hard
 554fi
 555
 556require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
 557
 558# Now we are rebasing commits $upstream..$orig_head (or with --root,
 559# everything leading up to $orig_head) on top of $onto
 560
 561# Check if we are already based on $onto with linear history,
 562# but this should be done only when upstream and onto are the same
 563# and if this is not an interactive rebase.
 564mb=$(git merge-base "$onto" "$orig_head")
 565if test "$type" != interactive && test "$upstream" = "$onto" &&
 566        test "$mb" = "$onto" &&
 567        # linear history?
 568        ! (git rev-list --parents "$onto".."$orig_head" | sane_grep " .* ") > /dev/null
 569then
 570        if test -z "$force_rebase"
 571        then
 572                # Lazily switch to the target branch if needed...
 573                test -z "$switch_to" ||
 574                GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \
 575                        git checkout "$switch_to" --
 576                say "$(eval_gettext "Current branch \$branch_name is up to date.")"
 577                finish_rebase
 578                exit 0
 579        else
 580                say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
 581        fi
 582fi
 583
 584# If a hook exists, give it a chance to interrupt
 585run_pre_rebase_hook "$upstream_arg" "$@"
 586
 587if test -n "$diffstat"
 588then
 589        if test -n "$verbose"
 590        then
 591                echo "$(eval_gettext "Changes from \$mb to \$onto:")"
 592        fi
 593        # We want color (if set), but no pager
 594        GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
 595fi
 596
 597test "$type" = interactive && run_specific_rebase
 598
 599# Detach HEAD and reset the tree
 600say "$(gettext "First, rewinding head to replay your work on top of it...")"
 601
 602GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" \
 603        git checkout -q "$onto^0" || die "could not detach HEAD"
 604git update-ref ORIG_HEAD $orig_head
 605
 606# If the $onto is a proper descendant of the tip of the branch, then
 607# we just fast-forwarded.
 608if test "$mb" = "$orig_head"
 609then
 610        say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
 611        move_to_original_branch
 612        finish_rebase
 613        exit 0
 614fi
 615
 616if test -n "$rebase_root"
 617then
 618        revisions="$onto..$orig_head"
 619else
 620        revisions="$upstream..$orig_head"
 621fi
 622
 623run_specific_rebase