git-rebase--interactive.shon commit rebase -i: remove an unnecessary 'rerere' invocation (7063693)
   1# This shell script fragment is sourced by git-rebase to implement
   2# its interactive mode.  "git rebase --interactive" makes it easy
   3# to fix up commits in the middle of a series and rearrange commits.
   4#
   5# Copyright (c) 2006 Johannes E. Schindelin
   6#
   7# The original idea comes from Eric W. Biederman, in
   8# http://article.gmane.org/gmane.comp.version-control.git/22407
   9#
  10# The file containing rebase commands, comments, and empty lines.
  11# This file is created by "git rebase -i" then edited by the user.  As
  12# the lines are processed, they are removed from the front of this
  13# file and written to the tail of $done.
  14todo="$state_dir"/git-rebase-todo
  15
  16# The rebase command lines that have already been processed.  A line
  17# is moved here when it is first handled, before any associated user
  18# actions.
  19done="$state_dir"/done
  20
  21# The commit message that is planned to be used for any changes that
  22# need to be committed following a user interaction.
  23msg="$state_dir"/message
  24
  25# The file into which is accumulated the suggested commit message for
  26# squash/fixup commands.  When the first of a series of squash/fixups
  27# is seen, the file is created and the commit message from the
  28# previous commit and from the first squash/fixup commit are written
  29# to it.  The commit message for each subsequent squash/fixup commit
  30# is appended to the file as it is processed.
  31#
  32# The first line of the file is of the form
  33#     # This is a combination of $count commits.
  34# where $count is the number of commits whose messages have been
  35# written to the file so far (including the initial "pick" commit).
  36# Each time that a commit message is processed, this line is read and
  37# updated.  It is deleted just before the combined commit is made.
  38squash_msg="$state_dir"/message-squash
  39
  40# If the current series of squash/fixups has not yet included a squash
  41# command, then this file exists and holds the commit message of the
  42# original "pick" commit.  (If the series ends without a "squash"
  43# command, then this can be used as the commit message of the combined
  44# commit without opening the editor.)
  45fixup_msg="$state_dir"/message-fixup
  46
  47# $rewritten is the name of a directory containing files for each
  48# commit that is reachable by at least one merge base of $head and
  49# $upstream. They are not necessarily rewritten, but their children
  50# might be.  This ensures that commits on merged, but otherwise
  51# unrelated side branches are left alone. (Think "X" in the man page's
  52# example.)
  53rewritten="$state_dir"/rewritten
  54
  55dropped="$state_dir"/dropped
  56
  57end="$state_dir"/end
  58msgnum="$state_dir"/msgnum
  59
  60# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
  61# GIT_AUTHOR_DATE that will be used for the commit that is currently
  62# being rebased.
  63author_script="$state_dir"/author-script
  64
  65# When an "edit" rebase command is being processed, the SHA1 of the
  66# commit to be edited is recorded in this file.  When "git rebase
  67# --continue" is executed, if there are any staged changes then they
  68# will be amended to the HEAD commit, but only provided the HEAD
  69# commit is still the commit to be edited.  When any other rebase
  70# command is processed, this file is deleted.
  71amend="$state_dir"/amend
  72
  73# For the post-rewrite hook, we make a list of rewritten commits and
  74# their new sha1s.  The rewritten-pending list keeps the sha1s of
  75# commits that have been processed, but not committed yet,
  76# e.g. because they are waiting for a 'squash' command.
  77rewritten_list="$state_dir"/rewritten-list
  78rewritten_pending="$state_dir"/rewritten-pending
  79
  80strategy_args=
  81if test -n "$do_merge"
  82then
  83        strategy_args=${strategy:+--strategy=$strategy}
  84        eval '
  85                for strategy_opt in '"$strategy_opts"'
  86                do
  87                        strategy_args="$strategy_args -X$(git rev-parse --sq-quote "${strategy_opt#--}")"
  88                done
  89        '
  90fi
  91
  92GIT_CHERRY_PICK_HELP="$resolvemsg"
  93export GIT_CHERRY_PICK_HELP
  94
  95comment_char=$(git config --get core.commentchar 2>/dev/null | cut -c1)
  96: ${comment_char:=#}
  97
  98warn () {
  99        printf '%s\n' "$*" >&2
 100}
 101
 102# Output the commit message for the specified commit.
 103commit_message () {
 104        git cat-file commit "$1" | sed "1,/^$/d"
 105}
 106
 107orig_reflog_action="$GIT_REFLOG_ACTION"
 108
 109comment_for_reflog () {
 110        case "$orig_reflog_action" in
 111        ''|rebase*)
 112                GIT_REFLOG_ACTION="rebase -i ($1)"
 113                export GIT_REFLOG_ACTION
 114                ;;
 115        esac
 116}
 117
 118last_count=
 119mark_action_done () {
 120        sed -e 1q < "$todo" >> "$done"
 121        sed -e 1d < "$todo" >> "$todo".new
 122        mv -f "$todo".new "$todo"
 123        new_count=$(git stripspace --strip-comments <"$done" | wc -l)
 124        echo $new_count >"$msgnum"
 125        total=$(($new_count + $(git stripspace --strip-comments <"$todo" | wc -l)))
 126        echo $total >"$end"
 127        if test "$last_count" != "$new_count"
 128        then
 129                last_count=$new_count
 130                printf "Rebasing (%d/%d)\r" $new_count $total
 131                test -z "$verbose" || echo
 132        fi
 133}
 134
 135# Put the last action marked done at the beginning of the todo list
 136# again. If there has not been an action marked done yet, leave the list of
 137# items on the todo list unchanged.
 138reschedule_last_action () {
 139        tail -n 1 "$done" | cat - "$todo" >"$todo".new
 140        sed -e \$d <"$done" >"$done".new
 141        mv -f "$todo".new "$todo"
 142        mv -f "$done".new "$done"
 143}
 144
 145append_todo_help () {
 146        git stripspace --comment-lines >>"$todo" <<\EOF
 147
 148Commands:
 149 p, pick = use commit
 150 r, reword = use commit, but edit the commit message
 151 e, edit = use commit, but stop for amending
 152 s, squash = use commit, but meld into previous commit
 153 f, fixup = like "squash", but discard this commit's log message
 154 x, exec = run command (the rest of the line) using shell
 155
 156These lines can be re-ordered; they are executed from top to bottom.
 157
 158If you remove a line here THAT COMMIT WILL BE LOST.
 159EOF
 160}
 161
 162make_patch () {
 163        sha1_and_parents="$(git rev-list --parents -1 "$1")"
 164        case "$sha1_and_parents" in
 165        ?*' '?*' '?*)
 166                git diff --cc $sha1_and_parents
 167                ;;
 168        ?*' '?*)
 169                git diff-tree -p "$1^!"
 170                ;;
 171        *)
 172                echo "Root commit"
 173                ;;
 174        esac > "$state_dir"/patch
 175        test -f "$msg" ||
 176                commit_message "$1" > "$msg"
 177        test -f "$author_script" ||
 178                get_author_ident_from_commit "$1" > "$author_script"
 179}
 180
 181die_with_patch () {
 182        echo "$1" > "$state_dir"/stopped-sha
 183        make_patch "$1"
 184        die "$2"
 185}
 186
 187exit_with_patch () {
 188        echo "$1" > "$state_dir"/stopped-sha
 189        make_patch $1
 190        git rev-parse --verify HEAD > "$amend"
 191        gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
 192        warn "You can amend the commit now, with"
 193        warn
 194        warn "  git commit --amend $gpg_sign_opt_quoted"
 195        warn
 196        warn "Once you are satisfied with your changes, run"
 197        warn
 198        warn "  git rebase --continue"
 199        warn
 200        exit $2
 201}
 202
 203die_abort () {
 204        rm -rf "$state_dir"
 205        die "$1"
 206}
 207
 208has_action () {
 209        test -n "$(git stripspace --strip-comments <"$1")"
 210}
 211
 212is_empty_commit() {
 213        tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null ||
 214                die "$1: not a commit that can be picked")
 215        ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null ||
 216                ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904)
 217        test "$tree" = "$ptree"
 218}
 219
 220is_merge_commit()
 221{
 222        git rev-parse --verify --quiet "$1"^2 >/dev/null 2>&1
 223}
 224
 225# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
 226# GIT_AUTHOR_DATE exported from the current environment.
 227do_with_author () {
 228        (
 229                export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
 230                "$@"
 231        )
 232}
 233
 234git_sequence_editor () {
 235        if test -z "$GIT_SEQUENCE_EDITOR"
 236        then
 237                GIT_SEQUENCE_EDITOR="$(git config sequence.editor)"
 238                if [ -z "$GIT_SEQUENCE_EDITOR" ]
 239                then
 240                        GIT_SEQUENCE_EDITOR="$(git var GIT_EDITOR)" || return $?
 241                fi
 242        fi
 243
 244        eval "$GIT_SEQUENCE_EDITOR" '"$@"'
 245}
 246
 247pick_one () {
 248        ff=--ff
 249
 250        case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
 251        case "$force_rebase" in '') ;; ?*) ff= ;; esac
 252        output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
 253
 254        if is_empty_commit "$sha1"
 255        then
 256                empty_args="--allow-empty"
 257        fi
 258
 259        test -d "$rewritten" &&
 260                pick_one_preserving_merges "$@" && return
 261        output eval git cherry-pick \
 262                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
 263                        "$strategy_args" $empty_args $ff "$@"
 264
 265        # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
 266        # previous task so this commit is not lost.
 267        ret=$?
 268        case "$ret" in [01]) ;; *) reschedule_last_action ;; esac
 269        return $ret
 270}
 271
 272pick_one_preserving_merges () {
 273        fast_forward=t
 274        case "$1" in
 275        -n)
 276                fast_forward=f
 277                sha1=$2
 278                ;;
 279        *)
 280                sha1=$1
 281                ;;
 282        esac
 283        sha1=$(git rev-parse $sha1)
 284
 285        if test -f "$state_dir"/current-commit
 286        then
 287                if test "$fast_forward" = t
 288                then
 289                        while read current_commit
 290                        do
 291                                git rev-parse HEAD > "$rewritten"/$current_commit
 292                        done <"$state_dir"/current-commit
 293                        rm "$state_dir"/current-commit ||
 294                        die "Cannot write current commit's replacement sha1"
 295                fi
 296        fi
 297
 298        echo $sha1 >> "$state_dir"/current-commit
 299
 300        # rewrite parents; if none were rewritten, we can fast-forward.
 301        new_parents=
 302        pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
 303        if test "$pend" = " "
 304        then
 305                pend=" root"
 306        fi
 307        while [ "$pend" != "" ]
 308        do
 309                p=$(expr "$pend" : ' \([^ ]*\)')
 310                pend="${pend# $p}"
 311
 312                if test -f "$rewritten"/$p
 313                then
 314                        new_p=$(cat "$rewritten"/$p)
 315
 316                        # If the todo reordered commits, and our parent is marked for
 317                        # rewriting, but hasn't been gotten to yet, assume the user meant to
 318                        # drop it on top of the current HEAD
 319                        if test -z "$new_p"
 320                        then
 321                                new_p=$(git rev-parse HEAD)
 322                        fi
 323
 324                        test $p != $new_p && fast_forward=f
 325                        case "$new_parents" in
 326                        *$new_p*)
 327                                ;; # do nothing; that parent is already there
 328                        *)
 329                                new_parents="$new_parents $new_p"
 330                                ;;
 331                        esac
 332                else
 333                        if test -f "$dropped"/$p
 334                        then
 335                                fast_forward=f
 336                                replacement="$(cat "$dropped"/$p)"
 337                                test -z "$replacement" && replacement=root
 338                                pend=" $replacement$pend"
 339                        else
 340                                new_parents="$new_parents $p"
 341                        fi
 342                fi
 343        done
 344        case $fast_forward in
 345        t)
 346                output warn "Fast-forward to $sha1"
 347                output git reset --hard $sha1 ||
 348                        die "Cannot fast-forward to $sha1"
 349                ;;
 350        f)
 351                first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
 352
 353                if [ "$1" != "-n" ]
 354                then
 355                        # detach HEAD to current parent
 356                        output git checkout $first_parent 2> /dev/null ||
 357                                die "Cannot move HEAD to $first_parent"
 358                fi
 359
 360                case "$new_parents" in
 361                ' '*' '*)
 362                        test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
 363
 364                        # redo merge
 365                        author_script_content=$(get_author_ident_from_commit $sha1)
 366                        eval "$author_script_content"
 367                        msg_content="$(commit_message $sha1)"
 368                        # No point in merging the first parent, that's HEAD
 369                        new_parents=${new_parents# $first_parent}
 370                        merge_args="--no-log --no-ff"
 371                        if ! do_with_author output eval \
 372                        'git merge ${gpg_sign_opt:+"$gpg_sign_opt"} \
 373                                $merge_args $strategy_args -m "$msg_content" $new_parents'
 374                        then
 375                                printf "%s\n" "$msg_content" > "$GIT_DIR"/MERGE_MSG
 376                                die_with_patch $sha1 "Error redoing merge $sha1"
 377                        fi
 378                        echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
 379                        ;;
 380                *)
 381                        output eval git cherry-pick \
 382                                ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
 383                                "$strategy_args" "$@" ||
 384                                die_with_patch $sha1 "Could not pick $sha1"
 385                        ;;
 386                esac
 387                ;;
 388        esac
 389}
 390
 391nth_string () {
 392        case "$1" in
 393        *1[0-9]|*[04-9]) echo "$1"th;;
 394        *1) echo "$1"st;;
 395        *2) echo "$1"nd;;
 396        *3) echo "$1"rd;;
 397        esac
 398}
 399
 400update_squash_messages () {
 401        if test -f "$squash_msg"; then
 402                mv "$squash_msg" "$squash_msg".bak || exit
 403                count=$(($(sed -n \
 404                        -e "1s/^. This is a combination of \(.*\) commits\./\1/p" \
 405                        -e "q" < "$squash_msg".bak)+1))
 406                {
 407                        printf '%s\n' "$comment_char This is a combination of $count commits."
 408                        sed -e 1d -e '2,/^./{
 409                                /^$/d
 410                        }' <"$squash_msg".bak
 411                } >"$squash_msg"
 412        else
 413                commit_message HEAD > "$fixup_msg" || die "Cannot write $fixup_msg"
 414                count=2
 415                {
 416                        printf '%s\n' "$comment_char This is a combination of 2 commits."
 417                        printf '%s\n' "$comment_char The first commit's message is:"
 418                        echo
 419                        cat "$fixup_msg"
 420                } >"$squash_msg"
 421        fi
 422        case $1 in
 423        squash)
 424                rm -f "$fixup_msg"
 425                echo
 426                printf '%s\n' "$comment_char This is the $(nth_string $count) commit message:"
 427                echo
 428                commit_message $2
 429                ;;
 430        fixup)
 431                echo
 432                printf '%s\n' "$comment_char The $(nth_string $count) commit message will be skipped:"
 433                echo
 434                # Change the space after the comment character to TAB:
 435                commit_message $2 | git stripspace --comment-lines | sed -e 's/ /       /'
 436                ;;
 437        esac >>"$squash_msg"
 438}
 439
 440peek_next_command () {
 441        git stripspace --strip-comments <"$todo" | sed -n -e 's/ .*//p' -e q
 442}
 443
 444# A squash/fixup has failed.  Prepare the long version of the squash
 445# commit message, then die_with_patch.  This code path requires the
 446# user to edit the combined commit message for all commits that have
 447# been squashed/fixedup so far.  So also erase the old squash
 448# messages, effectively causing the combined commit to be used as the
 449# new basis for any further squash/fixups.  Args: sha1 rest
 450die_failed_squash() {
 451        mv "$squash_msg" "$msg" || exit
 452        rm -f "$fixup_msg"
 453        cp "$msg" "$GIT_DIR"/MERGE_MSG || exit
 454        warn
 455        warn "Could not apply $1... $2"
 456        die_with_patch $1 ""
 457}
 458
 459flush_rewritten_pending() {
 460        test -s "$rewritten_pending" || return
 461        newsha1="$(git rev-parse HEAD^0)"
 462        sed "s/$/ $newsha1/" < "$rewritten_pending" >> "$rewritten_list"
 463        rm -f "$rewritten_pending"
 464}
 465
 466record_in_rewritten() {
 467        oldsha1="$(git rev-parse $1)"
 468        echo "$oldsha1" >> "$rewritten_pending"
 469
 470        case "$(peek_next_command)" in
 471        squash|s|fixup|f)
 472                ;;
 473        *)
 474                flush_rewritten_pending
 475                ;;
 476        esac
 477}
 478
 479do_pick () {
 480        if test "$(git rev-parse HEAD)" = "$squash_onto"
 481        then
 482                # Set the correct commit message and author info on the
 483                # sentinel root before cherry-picking the original changes
 484                # without committing (-n).  Finally, update the sentinel again
 485                # to include these changes.  If the cherry-pick results in a
 486                # conflict, this means our behaviour is similar to a standard
 487                # failed cherry-pick during rebase, with a dirty index to
 488                # resolve before manually running git commit --amend then git
 489                # rebase --continue.
 490                git commit --allow-empty --allow-empty-message --amend \
 491                           --no-post-rewrite -n -q -C $1 &&
 492                        pick_one -n $1 &&
 493                        git commit --allow-empty --allow-empty-message \
 494                                   --amend --no-post-rewrite -n -q -C $1 \
 495                                   ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 496                        die_with_patch $1 "Could not apply $1... $2"
 497        else
 498                pick_one $1 ||
 499                        die_with_patch $1 "Could not apply $1... $2"
 500        fi
 501}
 502
 503do_next () {
 504        rm -f "$msg" "$author_script" "$amend" "$state_dir"/stopped-sha || exit
 505        read -r command sha1 rest < "$todo"
 506        case "$command" in
 507        "$comment_char"*|''|noop)
 508                mark_action_done
 509                ;;
 510        pick|p)
 511                comment_for_reflog pick
 512
 513                mark_action_done
 514                do_pick $sha1 "$rest"
 515                record_in_rewritten $sha1
 516                ;;
 517        reword|r)
 518                comment_for_reflog reword
 519
 520                mark_action_done
 521                do_pick $sha1 "$rest"
 522                git commit --amend --no-post-rewrite ${gpg_sign_opt:+"$gpg_sign_opt"} || {
 523                        warn "Could not amend commit after successfully picking $sha1... $rest"
 524                        warn "This is most likely due to an empty commit message, or the pre-commit hook"
 525                        warn "failed. If the pre-commit hook failed, you may need to resolve the issue before"
 526                        warn "you are able to reword the commit."
 527                        exit_with_patch $sha1 1
 528                }
 529                record_in_rewritten $sha1
 530                ;;
 531        edit|e)
 532                comment_for_reflog edit
 533
 534                mark_action_done
 535                do_pick $sha1 "$rest"
 536                warn "Stopped at $sha1... $rest"
 537                exit_with_patch $sha1 0
 538                ;;
 539        squash|s|fixup|f)
 540                case "$command" in
 541                squash|s)
 542                        squash_style=squash
 543                        ;;
 544                fixup|f)
 545                        squash_style=fixup
 546                        ;;
 547                esac
 548                comment_for_reflog $squash_style
 549
 550                test -f "$done" && has_action "$done" ||
 551                        die "Cannot '$squash_style' without a previous commit"
 552
 553                mark_action_done
 554                update_squash_messages $squash_style $sha1
 555                author_script_content=$(get_author_ident_from_commit HEAD)
 556                echo "$author_script_content" > "$author_script"
 557                eval "$author_script_content"
 558                if ! pick_one -n $sha1
 559                then
 560                        git rev-parse --verify HEAD >"$amend"
 561                        die_failed_squash $sha1 "$rest"
 562                fi
 563                case "$(peek_next_command)" in
 564                squash|s|fixup|f)
 565                        # This is an intermediate commit; its message will only be
 566                        # used in case of trouble.  So use the long version:
 567                        do_with_author output git commit --amend --no-verify -F "$squash_msg" \
 568                                ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 569                                die_failed_squash $sha1 "$rest"
 570                        ;;
 571                *)
 572                        # This is the final command of this squash/fixup group
 573                        if test -f "$fixup_msg"
 574                        then
 575                                do_with_author git commit --amend --no-verify -F "$fixup_msg" \
 576                                        ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 577                                        die_failed_squash $sha1 "$rest"
 578                        else
 579                                cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
 580                                rm -f "$GIT_DIR"/MERGE_MSG
 581                                do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e \
 582                                        ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 583                                        die_failed_squash $sha1 "$rest"
 584                        fi
 585                        rm -f "$squash_msg" "$fixup_msg"
 586                        ;;
 587                esac
 588                record_in_rewritten $sha1
 589                ;;
 590        x|"exec")
 591                read -r command rest < "$todo"
 592                mark_action_done
 593                printf 'Executing: %s\n' "$rest"
 594                ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
 595                status=$?
 596                # Run in subshell because require_clean_work_tree can die.
 597                dirty=f
 598                (require_clean_work_tree "rebase" 2>/dev/null) || dirty=t
 599                if test "$status" -ne 0
 600                then
 601                        warn "Execution failed: $rest"
 602                        test "$dirty" = f ||
 603                        warn "and made changes to the index and/or the working tree"
 604
 605                        warn "You can fix the problem, and then run"
 606                        warn
 607                        warn "  git rebase --continue"
 608                        warn
 609                        if test $status -eq 127         # command not found
 610                        then
 611                                status=1
 612                        fi
 613                        exit "$status"
 614                elif test "$dirty" = t
 615                then
 616                        warn "Execution succeeded: $rest"
 617                        warn "but left changes to the index and/or the working tree"
 618                        warn "Commit or stash your changes, and then run"
 619                        warn
 620                        warn "  git rebase --continue"
 621                        warn
 622                        exit 1
 623                fi
 624                ;;
 625        *)
 626                warn "Unknown command: $command $sha1 $rest"
 627                fixtodo="Please fix this using 'git rebase --edit-todo'."
 628                if git rev-parse --verify -q "$sha1" >/dev/null
 629                then
 630                        die_with_patch $sha1 "$fixtodo"
 631                else
 632                        die "$fixtodo"
 633                fi
 634                ;;
 635        esac
 636        test -s "$todo" && return
 637
 638        comment_for_reflog finish &&
 639        newhead=$(git rev-parse HEAD) &&
 640        case $head_name in
 641        refs/*)
 642                message="$GIT_REFLOG_ACTION: $head_name onto $onto" &&
 643                git update-ref -m "$message" $head_name $newhead $orig_head &&
 644                git symbolic-ref \
 645                  -m "$GIT_REFLOG_ACTION: returning to $head_name" \
 646                  HEAD $head_name
 647                ;;
 648        esac && {
 649                test ! -f "$state_dir"/verbose ||
 650                        git diff-tree --stat $orig_head..HEAD
 651        } &&
 652        {
 653                test -s "$rewritten_list" &&
 654                git notes copy --for-rewrite=rebase < "$rewritten_list" ||
 655                true # we don't care if this copying failed
 656        } &&
 657        if test -x "$GIT_DIR"/hooks/post-rewrite &&
 658                test -s "$rewritten_list"; then
 659                "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list"
 660                true # we don't care if this hook failed
 661        fi &&
 662        warn "Successfully rebased and updated $head_name."
 663
 664        return 1 # not failure; just to break the do_rest loop
 665}
 666
 667# can only return 0, when the infinite loop breaks
 668do_rest () {
 669        while :
 670        do
 671                do_next || break
 672        done
 673}
 674
 675# skip picking commits whose parents are unchanged
 676skip_unnecessary_picks () {
 677        fd=3
 678        while read -r command rest
 679        do
 680                # fd=3 means we skip the command
 681                case "$fd,$command" in
 682                3,pick|3,p)
 683                        # pick a commit whose parent is current $onto -> skip
 684                        sha1=${rest%% *}
 685                        case "$(git rev-parse --verify --quiet "$sha1"^)" in
 686                        "$onto"*)
 687                                onto=$sha1
 688                                ;;
 689                        *)
 690                                fd=1
 691                                ;;
 692                        esac
 693                        ;;
 694                3,"$comment_char"*|3,)
 695                        # copy comments
 696                        ;;
 697                *)
 698                        fd=1
 699                        ;;
 700                esac
 701                printf '%s\n' "$command${rest:+ }$rest" >&$fd
 702        done <"$todo" >"$todo.new" 3>>"$done" &&
 703        mv -f "$todo".new "$todo" &&
 704        case "$(peek_next_command)" in
 705        squash|s|fixup|f)
 706                record_in_rewritten "$onto"
 707                ;;
 708        esac ||
 709        die "Could not skip unnecessary pick commands"
 710}
 711
 712transform_todo_ids () {
 713        while read -r command rest
 714        do
 715                case "$command" in
 716                "$comment_char"* | exec)
 717                        # Be careful for oddball commands like 'exec'
 718                        # that do not have a SHA-1 at the beginning of $rest.
 719                        ;;
 720                *)
 721                        sha1=$(git rev-parse --verify --quiet "$@" ${rest%% *}) &&
 722                        rest="$sha1 ${rest#* }"
 723                        ;;
 724                esac
 725                printf '%s\n' "$command${rest:+ }$rest"
 726        done <"$todo" >"$todo.new" &&
 727        mv -f "$todo.new" "$todo"
 728}
 729
 730expand_todo_ids() {
 731        transform_todo_ids
 732}
 733
 734collapse_todo_ids() {
 735        transform_todo_ids --short
 736}
 737
 738# Rearrange the todo list that has both "pick sha1 msg" and
 739# "pick sha1 fixup!/squash! msg" appears in it so that the latter
 740# comes immediately after the former, and change "pick" to
 741# "fixup"/"squash".
 742rearrange_squash () {
 743        # extract fixup!/squash! lines and resolve any referenced sha1's
 744        while read -r pick sha1 message
 745        do
 746                case "$message" in
 747                "squash! "*|"fixup! "*)
 748                        action="${message%%!*}"
 749                        rest=$message
 750                        prefix=
 751                        # skip all squash! or fixup! (but save for later)
 752                        while :
 753                        do
 754                                case "$rest" in
 755                                "squash! "*|"fixup! "*)
 756                                        prefix="$prefix${rest%%!*},"
 757                                        rest="${rest#*! }"
 758                                        ;;
 759                                *)
 760                                        break
 761                                        ;;
 762                                esac
 763                        done
 764                        printf '%s %s %s %s\n' "$sha1" "$action" "$prefix" "$rest"
 765                        # if it's a single word, try to resolve to a full sha1 and
 766                        # emit a second copy. This allows us to match on both message
 767                        # and on sha1 prefix
 768                        if test "${rest#* }" = "$rest"; then
 769                                fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
 770                                if test -n "$fullsha"; then
 771                                        # prefix the action to uniquely identify this line as
 772                                        # intended for full sha1 match
 773                                        echo "$sha1 +$action $prefix $fullsha"
 774                                fi
 775                        fi
 776                esac
 777        done >"$1.sq" <"$1"
 778        test -s "$1.sq" || return
 779
 780        used=
 781        while read -r pick sha1 message
 782        do
 783                case " $used" in
 784                *" $sha1 "*) continue ;;
 785                esac
 786                printf '%s\n' "$pick $sha1 $message"
 787                used="$used$sha1 "
 788                while read -r squash action msg_prefix msg_content
 789                do
 790                        case " $used" in
 791                        *" $squash "*) continue ;;
 792                        esac
 793                        emit=0
 794                        case "$action" in
 795                        +*)
 796                                action="${action#+}"
 797                                # full sha1 prefix test
 798                                case "$msg_content" in "$sha1"*) emit=1;; esac ;;
 799                        *)
 800                                # message prefix test
 801                                case "$message" in "$msg_content"*) emit=1;; esac ;;
 802                        esac
 803                        if test $emit = 1; then
 804                                real_prefix=$(echo "$msg_prefix" | sed "s/,/! /g")
 805                                printf '%s\n' "$action $squash ${real_prefix}$msg_content"
 806                                used="$used$squash "
 807                        fi
 808                done <"$1.sq"
 809        done >"$1.rearranged" <"$1"
 810        cat "$1.rearranged" >"$1"
 811        rm -f "$1.sq" "$1.rearranged"
 812}
 813
 814# Add commands after a pick or after a squash/fixup serie
 815# in the todo list.
 816add_exec_commands () {
 817        {
 818                first=t
 819                while read -r insn rest
 820                do
 821                        case $insn in
 822                        pick)
 823                                test -n "$first" ||
 824                                printf "%s" "$cmd"
 825                                ;;
 826                        esac
 827                        printf "%s %s\n" "$insn" "$rest"
 828                        first=
 829                done
 830                printf "%s" "$cmd"
 831        } <"$1" >"$1.new" &&
 832        mv "$1.new" "$1"
 833}
 834
 835# The whole contents of this file is run by dot-sourcing it from
 836# inside a shell function.  It used to be that "return"s we see
 837# below were not inside any function, and expected to return
 838# to the function that dot-sourced us.
 839#
 840# However, FreeBSD /bin/sh misbehaves on such a construct and
 841# continues to run the statements that follow such a "return".
 842# As a work-around, we introduce an extra layer of a function
 843# here, and immediately call it after defining it.
 844git_rebase__interactive () {
 845
 846case "$action" in
 847continue)
 848        # do we have anything to commit?
 849        if git diff-index --cached --quiet HEAD --
 850        then
 851                # Nothing to commit -- skip this commit
 852
 853                test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
 854                rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
 855                die "Could not remove CHERRY_PICK_HEAD"
 856        else
 857                if ! test -f "$author_script"
 858                then
 859                        gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
 860                        die "You have staged changes in your working tree. If these changes are meant to be
 861squashed into the previous commit, run:
 862
 863  git commit --amend $gpg_sign_opt_quoted
 864
 865If they are meant to go into a new commit, run:
 866
 867  git commit $gpg_sign_opt_quoted
 868
 869In both case, once you're done, continue with:
 870
 871  git rebase --continue
 872"
 873                fi
 874                . "$author_script" ||
 875                        die "Error trying to find the author identity to amend commit"
 876                if test -f "$amend"
 877                then
 878                        current_head=$(git rev-parse --verify HEAD)
 879                        test "$current_head" = $(cat "$amend") ||
 880                        die "\
 881You have uncommitted changes in your working tree. Please, commit them
 882first and then run 'git rebase --continue' again."
 883                        do_with_author git commit --amend --no-verify -F "$msg" -e \
 884                                ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 885                                die "Could not commit staged changes."
 886                else
 887                        do_with_author git commit --no-verify -F "$msg" -e \
 888                                ${gpg_sign_opt:+"$gpg_sign_opt"} ||
 889                                die "Could not commit staged changes."
 890                fi
 891        fi
 892
 893        if test -r "$state_dir"/stopped-sha
 894        then
 895                record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
 896        fi
 897
 898        require_clean_work_tree "rebase"
 899        do_rest
 900        return 0
 901        ;;
 902skip)
 903        git rerere clear
 904
 905        do_rest
 906        return 0
 907        ;;
 908edit-todo)
 909        git stripspace --strip-comments <"$todo" >"$todo".new
 910        mv -f "$todo".new "$todo"
 911        collapse_todo_ids
 912        append_todo_help
 913        git stripspace --comment-lines >>"$todo" <<\EOF
 914
 915You are editing the todo file of an ongoing interactive rebase.
 916To continue rebase after editing, run:
 917    git rebase --continue
 918
 919EOF
 920
 921        git_sequence_editor "$todo" ||
 922                die "Could not execute editor"
 923        expand_todo_ids
 924
 925        exit
 926        ;;
 927esac
 928
 929git var GIT_COMMITTER_IDENT >/dev/null ||
 930        die "You need to set your committer info first"
 931
 932comment_for_reflog start
 933
 934if test ! -z "$switch_to"
 935then
 936        GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
 937        output git checkout "$switch_to" -- ||
 938        die "Could not checkout $switch_to"
 939
 940        comment_for_reflog start
 941fi
 942
 943orig_head=$(git rev-parse --verify HEAD) || die "No HEAD?"
 944mkdir -p "$state_dir" || die "Could not create temporary $state_dir"
 945
 946: > "$state_dir"/interactive || die "Could not mark as interactive"
 947write_basic_state
 948if test t = "$preserve_merges"
 949then
 950        if test -z "$rebase_root"
 951        then
 952                mkdir "$rewritten" &&
 953                for c in $(git merge-base --all $orig_head $upstream)
 954                do
 955                        echo $onto > "$rewritten"/$c ||
 956                                die "Could not init rewritten commits"
 957                done
 958        else
 959                mkdir "$rewritten" &&
 960                echo $onto > "$rewritten"/root ||
 961                        die "Could not init rewritten commits"
 962        fi
 963        # No cherry-pick because our first pass is to determine
 964        # parents to rewrite and skipping dropped commits would
 965        # prematurely end our probe
 966        merges_option=
 967else
 968        merges_option="--no-merges --cherry-pick"
 969fi
 970
 971shorthead=$(git rev-parse --short $orig_head)
 972shortonto=$(git rev-parse --short $onto)
 973if test -z "$rebase_root"
 974        # this is now equivalent to ! -z "$upstream"
 975then
 976        shortupstream=$(git rev-parse --short $upstream)
 977        revisions=$upstream...$orig_head
 978        shortrevisions=$shortupstream..$shorthead
 979else
 980        revisions=$onto...$orig_head
 981        shortrevisions=$shorthead
 982fi
 983git rev-list $merges_option --pretty=oneline --reverse --left-right --topo-order \
 984        $revisions ${restrict_revision+^$restrict_revision} | \
 985        sed -n "s/^>//p" |
 986while read -r sha1 rest
 987do
 988
 989        if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
 990        then
 991                comment_out="$comment_char "
 992        else
 993                comment_out=
 994        fi
 995
 996        if test t != "$preserve_merges"
 997        then
 998                printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
 999        else
1000                if test -z "$rebase_root"
1001                then
1002                        preserve=t
1003                        for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
1004                        do
1005                                if test -f "$rewritten"/$p
1006                                then
1007                                        preserve=f
1008                                fi
1009                        done
1010                else
1011                        preserve=f
1012                fi
1013                if test f = "$preserve"
1014                then
1015                        touch "$rewritten"/$sha1
1016                        printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
1017                fi
1018        fi
1019done
1020
1021# Watch for commits that been dropped by --cherry-pick
1022if test t = "$preserve_merges"
1023then
1024        mkdir "$dropped"
1025        # Save all non-cherry-picked changes
1026        git rev-list $revisions --left-right --cherry-pick | \
1027                sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
1028        # Now all commits and note which ones are missing in
1029        # not-cherry-picks and hence being dropped
1030        git rev-list $revisions |
1031        while read rev
1032        do
1033                if test -f "$rewritten"/$rev && test "$(sane_grep "$rev" "$state_dir"/not-cherry-picks)" = ""
1034                then
1035                        # Use -f2 because if rev-list is telling us this commit is
1036                        # not worthwhile, we don't want to track its multiple heads,
1037                        # just the history of its first-parent for others that will
1038                        # be rebasing on top of it
1039                        git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
1040                        sha1=$(git rev-list -1 $rev)
1041                        sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
1042                        rm "$rewritten"/$rev
1043                fi
1044        done
1045fi
1046
1047test -s "$todo" || echo noop >> "$todo"
1048test -n "$autosquash" && rearrange_squash "$todo"
1049test -n "$cmd" && add_exec_commands "$todo"
1050
1051todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
1052todocount=${todocount##* }
1053
1054cat >>"$todo" <<EOF
1055
1056$comment_char Rebase $shortrevisions onto $shortonto ($todocount command(s))
1057EOF
1058append_todo_help
1059git stripspace --comment-lines >>"$todo" <<\EOF
1060
1061However, if you remove everything, the rebase will be aborted.
1062
1063EOF
1064
1065if test -z "$keep_empty"
1066then
1067        printf '%s\n' "$comment_char Note that empty commits are commented out" >>"$todo"
1068fi
1069
1070
1071has_action "$todo" ||
1072        return 2
1073
1074cp "$todo" "$todo".backup
1075collapse_todo_ids
1076git_sequence_editor "$todo" ||
1077        die_abort "Could not execute editor"
1078
1079has_action "$todo" ||
1080        return 2
1081
1082expand_todo_ids
1083
1084test -d "$rewritten" || test -n "$force_rebase" || skip_unnecessary_picks
1085
1086GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
1087output git checkout $onto || die_abort "could not detach HEAD"
1088git update-ref ORIG_HEAD $orig_head
1089do_rest
1090
1091}
1092# ... and then we call the whole thing.
1093git_rebase__interactive