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