@@ -537,6 +537,34 @@ do_next () {
537537 esac
538538 record_in_rewritten $sha1
539539 ;;
540+ x|" exec" )
541+ read -r command rest < " $TODO "
542+ mark_action_done
543+ printf ' Executing: %s\n' " $rest "
544+ # "exec" command doesn't take a sha1 in the todo-list.
545+ # => can't just use $sha1 here.
546+ git rev-parse --verify HEAD > " $DOTEST " /stopped-sha
547+ ${SHELL:-@ SHELL_PATH@ } -c " $rest " # Actual execution
548+ status=$?
549+ if test " $status " -ne 0
550+ then
551+ warn " Execution failed: $rest "
552+ warn " You can fix the problem, and then run"
553+ warn
554+ warn " git rebase --continue"
555+ warn
556+ exit " $status "
557+ fi
558+ # Run in subshell because require_clean_work_tree can die.
559+ if ! (require_clean_work_tree)
560+ then
561+ warn " Commit or stash your changes, and then run"
562+ warn
563+ warn " git rebase --continue"
564+ warn
565+ exit 1
566+ fi
567+ ;;
540568 * )
541569 warn " Unknown command: $command $sha1 $rest "
542570 if git rev-parse --verify -q " $sha1 " > /dev/null
@@ -591,22 +619,30 @@ do_rest () {
591619# skip picking commits whose parents are unchanged
592620skip_unnecessary_picks () {
593621 fd=3
594- while read -r command sha1 rest
622+ while read -r command rest
595623 do
596624 # fd=3 means we skip the command
597- case " $fd ,$command , $( git rev-parse --verify --quiet $sha1 ^ ) " in
598- 3,pick, " $ONTO " * |3,p, " $ONTO " * )
625+ case " $fd ,$command " in
626+ 3,pick|3,p)
599627 # pick a commit whose parent is current $ONTO -> skip
600- ONTO=$sha1
628+ sha1=$( printf ' %s' " $rest " | cut -d ' ' -f 1)
629+ case " $( git rev-parse --verify --quiet " $sha1 " ^) " in
630+ " $ONTO " * )
631+ ONTO=$sha1
632+ ;;
633+ * )
634+ fd=1
635+ ;;
636+ esac
601637 ;;
602- 3,#* |3,, * )
638+ 3,#* |3,)
603639 # copy comments
604640 ;;
605641 * )
606642 fd=1
607643 ;;
608644 esac
609- printf ' %s\n' " $command ${sha1 : + } $sha1 ${ rest: + }$rest " >& $fd
645+ printf ' %s\n' " $command ${rest: + } $rest " >& $fd
610646 done < " $TODO " > " $TODO .new" 3>> " $DONE " &&
611647 mv -f " $TODO " .new " $TODO " &&
612648 case " $( peek_next_command) " in
@@ -957,6 +993,7 @@ first and then run 'git rebase --continue' again."
957993# e, edit = use commit, but stop for amending
958994# s, squash = use commit, but meld into previous commit
959995# f, fixup = like "squash", but discard this commit's log message
996+ # x <cmd>, exec <cmd> = Run a shell command <cmd>, and stop if it fails
960997#
961998# If you remove a line here THAT COMMIT WILL BE LOST.
962999# However, if you remove everything, the rebase will be aborted.
0 commit comments