git-rebase.shon commit Second batch for 2.1 (0953113)
   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
  62cmd=
  63strategy=
  64strategy_opts=
  65do_merge=
  66merge_dir="$GIT_DIR"/rebase-merge
  67apply_dir="$GIT_DIR"/rebase-apply
  68verbose=
  69diffstat=
  70test "$(git config --bool rebase.stat)" = true && diffstat=t
  71autostash="$(git config --bool rebase.autostash || echo false)"
  72fork_point=auto
  73git_am_opt=
  74rebase_root=
  75force_rebase=
  76allow_rerere_autoupdate=
  77# Non-empty if a rebase was in progress when 'git rebase' was invoked
  78in_progress=
  79# One of {am, merge, interactive}
  80type=
  81# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
  82state_dir=
  83# One of {'', continue, skip, abort}, as parsed from command line
  84action=
  85preserve_merges=
  86autosquash=
  87keep_empty=
  88test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
  89gpg_sign_opt=
  90
  91read_basic_state () {
  92        test -f "$state_dir/head-name" &&
  93        test -f "$state_dir/onto" &&
  94        head_name=$(cat "$state_dir"/head-name) &&
  95        onto=$(cat "$state_dir"/onto) &&
  96        # We always write to orig-head, but interactive rebase used to write to
  97        # head. Fall back to reading from head to cover for the case that the
  98        # user upgraded git with an ongoing interactive rebase.
  99        if test -f "$state_dir"/orig-head
 100        then
 101                orig_head=$(cat "$state_dir"/orig-head)
 102        else
 103                orig_head=$(cat "$state_dir"/head)
 104        fi &&
 105        GIT_QUIET=$(cat "$state_dir"/quiet) &&
 106        test -f "$state_dir"/verbose && verbose=t
 107        test -f "$state_dir"/strategy && strategy="$(cat "$state_dir"/strategy)"
 108        test -f "$state_dir"/strategy_opts &&
 109                strategy_opts="$(cat "$state_dir"/strategy_opts)"
 110        test -f "$state_dir"/allow_rerere_autoupdate &&
 111                allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
 112        test -f "$state_dir"/gpg_sign_opt &&
 113                gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
 114}
 115
 116write_basic_state () {
 117        echo "$head_name" > "$state_dir"/head-name &&
 118        echo "$onto" > "$state_dir"/onto &&
 119        echo "$orig_head" > "$state_dir"/orig-head &&
 120        echo "$GIT_QUIET" > "$state_dir"/quiet &&
 121        test t = "$verbose" && : > "$state_dir"/verbose
 122        test -n "$strategy" && echo "$strategy" > "$state_dir"/strategy
 123        test -n "$strategy_opts" && echo "$strategy_opts" > \
 124                "$state_dir"/strategy_opts
 125        test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
 126                "$state_dir"/allow_rerere_autoupdate
 127        test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
 128}
 129
 130output () {
 131        case "$verbose" in
 132        '')
 133                output=$("$@" 2>&1 )
 134                status=$?
 135                test $status != 0 && printf "%s\n" "$output"
 136                return $status
 137                ;;
 138        *)
 139                "$@"
 140                ;;
 141        esac
 142}
 143
 144move_to_original_branch () {
 145        case "$head_name" in
 146        refs/*)
 147                message="rebase finished: $head_name onto $onto"
 148                git update-ref -m "$message" \
 149                        $head_name $(git rev-parse HEAD) $orig_head &&
 150                git symbolic-ref \
 151                        -m "rebase finished: returning to $head_name" \
 152                        HEAD $head_name ||
 153                die "$(gettext "Could not move back to $head_name")"
 154                ;;
 155        esac
 156}
 157
 158finish_rebase () {
 159        if test -f "$state_dir/autostash"
 160        then
 161                stash_sha1=$(cat "$state_dir/autostash")
 162                if git stash apply $stash_sha1 2>&1 >/dev/null
 163                then
 164                        echo "$(gettext 'Applied autostash.')"
 165                else
 166                        git stash store -m "autostash" -q $stash_sha1 ||
 167                        die "$(eval_gettext "Cannot store \$stash_sha1")"
 168                        gettext 'Applying autostash resulted in conflicts.
 169Your changes are safe in the stash.
 170You can run "git stash pop" or "git stash drop" at any time.
 171'
 172                fi
 173        fi
 174        git gc --auto &&
 175        rm -rf "$state_dir"
 176}
 177
 178run_specific_rebase () {
 179        if [ "$interactive_rebase" = implied ]; then
 180                GIT_EDITOR=:
 181                export GIT_EDITOR
 182                autosquash=
 183        fi
 184        . git-rebase--$type
 185        ret=$?
 186        if test $ret -eq 0
 187        then
 188                finish_rebase
 189        fi
 190        exit $ret
 191}
 192
 193run_pre_rebase_hook () {
 194        if test -z "$ok_to_skip_pre_rebase" &&
 195           test -x "$GIT_DIR/hooks/pre-rebase"
 196        then
 197                "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
 198                die "$(gettext "The pre-rebase hook refused to rebase.")"
 199        fi
 200}
 201
 202test -f "$apply_dir"/applying &&
 203        die "$(gettext "It looks like git-am is in progress. Cannot rebase.")"
 204
 205if test -d "$apply_dir"
 206then
 207        type=am
 208        state_dir="$apply_dir"
 209elif test -d "$merge_dir"
 210then
 211        if test -f "$merge_dir"/interactive
 212        then
 213                type=interactive
 214                interactive_rebase=explicit
 215        else
 216                type=merge
 217        fi
 218        state_dir="$merge_dir"
 219fi
 220test -n "$type" && in_progress=t
 221
 222total_argc=$#
 223while test $# != 0
 224do
 225        case "$1" in
 226        --no-verify)
 227                ok_to_skip_pre_rebase=yes
 228                ;;
 229        --verify)
 230                ok_to_skip_pre_rebase=
 231                ;;
 232        --continue|--skip|--abort|--edit-todo)
 233                test $total_argc -eq 2 || usage
 234                action=${1##--}
 235                ;;
 236        --onto=*)
 237                onto="${1#--onto=}"
 238                ;;
 239        --exec=*)
 240                cmd="${cmd}exec ${1#--exec=}${LF}"
 241                ;;
 242        --interactive)
 243                interactive_rebase=explicit
 244                ;;
 245        --keep-empty)
 246                keep_empty=yes
 247                ;;
 248        --preserve-merges)
 249                preserve_merges=t
 250                test -z "$interactive_rebase" && interactive_rebase=implied
 251                ;;
 252        --autosquash)
 253                autosquash=t
 254                ;;
 255        --no-autosquash)
 256                autosquash=
 257                ;;
 258        --fork-point)
 259                fork_point=t
 260                ;;
 261        --no-fork-point)
 262                fork_point=
 263                ;;
 264        --merge)
 265                do_merge=t
 266                ;;
 267        --strategy-option=*)
 268                strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--${1#--strategy-option=}")"
 269                do_merge=t
 270                test -z "$strategy" && strategy=recursive
 271                ;;
 272        --strategy=*)
 273                strategy="${1#--strategy=}"
 274                do_merge=t
 275                ;;
 276        --no-stat)
 277                diffstat=
 278                ;;
 279        --stat)
 280                diffstat=t
 281                ;;
 282        --autostash)
 283                autostash=true
 284                ;;
 285        --verbose)
 286                verbose=t
 287                diffstat=t
 288                GIT_QUIET=
 289                ;;
 290        --quiet)
 291                GIT_QUIET=t
 292                git_am_opt="$git_am_opt -q"
 293                verbose=
 294                diffstat=
 295                ;;
 296        --whitespace=*)
 297                git_am_opt="$git_am_opt --whitespace=${1#--whitespace=}"
 298                case "${1#--whitespace=}" in
 299                fix|strip)
 300                        force_rebase=t
 301                        ;;
 302                esac
 303                ;;
 304        --ignore-whitespace)
 305                git_am_opt="$git_am_opt $1"
 306                ;;
 307        --committer-date-is-author-date|--ignore-date)
 308                git_am_opt="$git_am_opt $1"
 309                force_rebase=t
 310                ;;
 311        -C*)
 312                git_am_opt="$git_am_opt $1"
 313                ;;
 314        --root)
 315                rebase_root=t
 316                ;;
 317        --force-rebase|--no-ff)
 318                force_rebase=t
 319                ;;
 320        --rerere-autoupdate|--no-rerere-autoupdate)
 321                allow_rerere_autoupdate="$1"
 322                ;;
 323        --gpg-sign)
 324                gpg_sign_opt=-S
 325                ;;
 326        --gpg-sign=*)
 327                gpg_sign_opt="-S${1#--gpg-sign=}"
 328                ;;
 329        --)
 330                shift
 331                break
 332                ;;
 333        esac
 334        shift
 335done
 336test $# -gt 2 && usage
 337
 338if test -n "$cmd" &&
 339   test "$interactive_rebase" != explicit
 340then
 341        die "$(gettext "The --exec option must be used with the --interactive option")"
 342fi
 343
 344if test -n "$action"
 345then
 346        test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
 347        # Only interactive rebase uses detailed reflog messages
 348        if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
 349        then
 350                GIT_REFLOG_ACTION="rebase -i ($action)"
 351                export GIT_REFLOG_ACTION
 352        fi
 353fi
 354
 355if test "$action" = "edit-todo" && test "$type" != "interactive"
 356then
 357        die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
 358fi
 359
 360case "$action" in
 361continue)
 362        # Sanity check
 363        git rev-parse --verify HEAD >/dev/null ||
 364                die "$(gettext "Cannot read HEAD")"
 365        git update-index --ignore-submodules --refresh &&
 366        git diff-files --quiet --ignore-submodules || {
 367                echo "$(gettext "You must edit all merge conflicts and then
 368mark them as resolved using git add")"
 369                exit 1
 370        }
 371        read_basic_state
 372        run_specific_rebase
 373        ;;
 374skip)
 375        output git reset --hard HEAD || exit $?
 376        read_basic_state
 377        run_specific_rebase
 378        ;;
 379abort)
 380        git rerere clear
 381        read_basic_state
 382        case "$head_name" in
 383        refs/*)
 384                git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
 385                die "$(eval_gettext "Could not move back to \$head_name")"
 386                ;;
 387        esac
 388        output git reset --hard $orig_head
 389        finish_rebase
 390        exit
 391        ;;
 392edit-todo)
 393        run_specific_rebase
 394        ;;
 395esac
 396
 397# Make sure no rebase is in progress
 398if test -n "$in_progress"
 399then
 400        state_dir_base=${state_dir##*/}
 401        cmd_live_rebase="git rebase (--continue | --abort | --skip)"
 402        cmd_clear_stale_rebase="rm -fr \"$state_dir\""
 403        die "
 404$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
 405I wonder if you are in the middle of another rebase.  If that is the
 406case, please try
 407        $cmd_live_rebase
 408If that is not the case, please
 409        $cmd_clear_stale_rebase
 410and run me again.  I am stopping in case you still have something
 411valuable there.')"
 412fi
 413
 414if test -n "$rebase_root" && test -z "$onto"
 415then
 416        test -z "$interactive_rebase" && interactive_rebase=implied
 417fi
 418
 419if test -n "$interactive_rebase"
 420then
 421        type=interactive
 422        state_dir="$merge_dir"
 423elif test -n "$do_merge"
 424then
 425        type=merge
 426        state_dir="$merge_dir"
 427else
 428        type=am
 429        state_dir="$apply_dir"
 430fi
 431
 432if test -z "$rebase_root"
 433then
 434        case "$#" in
 435        0)
 436                if ! upstream_name=$(git rev-parse --symbolic-full-name \
 437                        --verify -q @{upstream} 2>/dev/null)
 438                then
 439                        . git-parse-remote
 440                        error_on_missing_default_upstream "rebase" "rebase" \
 441                                "against" "git rebase <branch>"
 442                fi
 443
 444                test "$fork_point" = auto && fork_point=t
 445                ;;
 446        *)      upstream_name="$1"
 447                if test "$upstream_name" = "-"
 448                then
 449                        upstream_name="@{-1}"
 450                fi
 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