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