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