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