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