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