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