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