From: Junio C Hamano Date: Tue, 19 May 2015 20:17:56 +0000 (-0700) Subject: Merge branch 'ph/rebase-i-redo' X-Git-Tag: v2.5.0-rc0~108 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/eae0216646039b203cd60c4294ef79f805fbd696?ds=inline;hp=-c Merge branch 'ph/rebase-i-redo' "git rebase -i" moved the "current" command from "todo" to "done" a bit too prematurely, losing a step when a "pick" did not even start. * ph/rebase-i-redo: rebase -i: redo tasks that die during cherry-pick --- eae0216646039b203cd60c4294ef79f805fbd696 diff --combined git-rebase--interactive.sh index 08e5d86fe5,0008057252..bab0dccc04 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@@ -132,6 -132,16 +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 +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 () { @@@ -642,9 -658,9 +658,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." diff --combined t/t3404-rebase-interactive.sh index eed76cca55,96be93c624..ac429a0bbb --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@@ -950,7 -950,7 +950,7 @@@ test_expect_success 'rebase --edit-tod set_fake_editor && FAKE_LINES="edit 1 2 3" git rebase -i HEAD~3 && FAKE_LINES="2 1" git rebase --edit-todo && - git rebase --continue + git rebase --continue && test M = $(git cat-file commit HEAD^ | sed -ne \$p) && test L = $(git cat-file commit HEAD | sed -ne \$p) ' @@@ -1007,7 -1007,7 +1007,7 @@@ test_expect_success 'rebase -i with --s ' test_expect_success 'rebase -i error on commits with \ in message' ' - current_head=$(git rev-parse HEAD) + current_head=$(git rev-parse HEAD) && test_when_finished "git rebase --abort; git reset --hard $current_head; rm -f error" && test_commit TO-REMOVE will-conflict old-content && test_commit "\temp" will-conflict new-content dummy && @@@ -1055,4 -1055,51 +1055,51 @@@ test_expect_success 'todo count' grep "^# Rebase ..* onto ..* ([0-9]" actual ' + test_expect_success 'rebase -i commits that overwrite untracked files (pick)' ' + git checkout --force branch2 && + git clean -f && + set_fake_editor && + FAKE_LINES="edit 1 2" git rebase -i A && + test_cmp_rev HEAD F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test_cmp_rev HEAD F && + rm file6 && + git rebase --continue && + test_cmp_rev HEAD I + ' + + test_expect_success 'rebase -i commits that overwrite untracked files (squash)' ' + git checkout --force branch2 && + git clean -f && + git tag original-branch2 && + set_fake_editor && + FAKE_LINES="edit 1 squash 2" git rebase -i A && + test_cmp_rev HEAD F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test_cmp_rev HEAD F && + rm file6 && + git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = I && + git reset --hard original-branch2 + ' + + test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' ' + git checkout --force branch2 && + git clean -f && + set_fake_editor && + FAKE_LINES="edit 1 2" git rebase -i --no-ff A && + test $(git cat-file commit HEAD | sed -ne \$p) = F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = F && + rm file6 && + git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = I + ' + test_done