t4150: am.messageid really adds the message id
[gitweb.git] / git-rebase--interactive.sh
index f7deeb096e24f4de69bdfe08f0aa35ebf170577a..dc3133f681227e66dd54f7bed4be68277e4240b3 100644 (file)
@@ -132,6 +132,16 @@ mark_action_done () {
        fi
 }
 
+# Put the last action marked done at the beginning of the todo list
+# again. If there has not been an action marked done yet, leave the list of
+# items on the todo list unchanged.
+reschedule_last_action () {
+       tail -n 1 "$done" | cat - "$todo" >"$todo".new
+       sed -e \$d <"$done" >"$done".new
+       mv -f "$todo".new "$todo"
+       mv -f "$done".new "$done"
+}
+
 append_todo_help () {
        git stripspace --comment-lines >>"$todo" <<\EOF
 
@@ -252,6 +262,12 @@ pick_one () {
        output eval git cherry-pick \
                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
                        "$strategy_args" $empty_args $ff "$@"
+
+       # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
+       # previous task so this commit is not lost.
+       ret=$?
+       case "$ret" in [01]) ;; *) reschedule_last_action ;; esac
+       return $ret
 }
 
 pick_one_preserving_merges () {
@@ -486,7 +502,7 @@ do_pick () {
 }
 
 do_next () {
-       rm -f "$msg" "$author_script" "$amend" || exit
+       rm -f "$msg" "$author_script" "$amend" "$state_dir"/stopped-sha || exit
        read -r command sha1 rest < "$todo"
        case "$command" in
        "$comment_char"*|''|noop)
@@ -576,9 +592,6 @@ do_next () {
                read -r command rest < "$todo"
                mark_action_done
                printf 'Executing: %s\n' "$rest"
-               # "exec" command doesn't take a sha1 in the todo-list.
-               # => can't just use $sha1 here.
-               git rev-parse --verify HEAD > "$state_dir"/stopped-sha
                ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
                status=$?
                # Run in subshell because require_clean_work_tree can die.
@@ -642,9 +655,9 @@ do_next () {
                git notes copy --for-rewrite=rebase < "$rewritten_list" ||
                true # we don't care if this copying failed
        } &&
-       if test -x "$GIT_DIR"/hooks/post-rewrite &&
-               test -s "$rewritten_list"; then
-               "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list"
+       hook="$(git rev-parse --git-path hooks/post-rewrite)"
+       if test -x "$hook" && test -s "$rewritten_list"; then
+               "$hook" rebase < "$rewritten_list"
                true # we don't care if this hook failed
        fi &&
        warn "Successfully rebased and updated $head_name."
@@ -874,7 +887,10 @@ first and then run 'git rebase --continue' again."
                fi
        fi
 
-       record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+       if test -r "$state_dir"/stopped-sha
+       then
+               record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+       fi
 
        require_clean_work_tree "rebase"
        do_rest