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