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