rebase --continue: refuse to commit after failed command

If a commit cannot be picked because it would overwrite an untracked file then "git rebase --continue" should refuse to commit any staged changes as the commit was not picked. This is implemented by refusing to commit if the message file is missing. The message file is chosen for this check because it is only written when "git rebase" stops for the user to resolve merge conflicts. Existing commands that refuse to commit staged changes when continuing such as a failed "exec" rely on checking for the absence of the author script in run_git_commit(). This prevents the staged changes from being committed but prints error: could not open '.git/rebase-merge/author-script' for reading before the message about not being able to commit. This is confusing to users and so checking for the message file instead improves the user experience. The existing test for refusing to commit after a failed exec is updated to check that we do not print the error message about a missing author script anymore. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Sep 6, 2023 at 15:22 UTC 405509cbd66b2149fcce6e71c0eb0704c241a826
3 files changed +26 -1
sequencer.c
+5
@@ -4963,6 +4963,11 @@ static int commit_staged_changes(struct repository *r,
4963
4964 is_clean = !has_uncommitted_changes(r, 0);
4965
4966 + if (!is_clean && !file_exists(rebase_path_message())) {
4967 + const char *gpg_opt = gpg_sign_opt_quoted(opts);
4968 +
4969 + return error(_(staged_changes_advice), gpg_opt, gpg_opt);
4970 + }
4971 if (file_exists(rebase_path_amend())) {
4972 struct strbuf rev = STRBUF_INIT;
4973 struct object_id head, to_amend;
t/t3404-rebase-interactive.sh
+17 -1
@@ -604,7 +604,8 @@ test_expect_success 'clean error after failed "exec"' '
604 echo "edited again" > file7 &&
605 git add file7 &&
606 test_must_fail git rebase --continue 2>error &&
607 - test_i18ngrep "you have staged changes in your working tree" error
607 + test_i18ngrep "you have staged changes in your working tree" error &&
608 + test_i18ngrep ! "could not open.*for reading" error
609 '
610
611 test_expect_success 'rebase a detached HEAD' '
@@ -1290,6 +1291,11 @@ test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '
1291 test_cmp_rev REBASE_HEAD I &&
1292 rm file6 &&
1293 test_path_is_missing .git/rebase-merge/patch &&
1294 + echo changed >file1 &&
1295 + git add file1 &&
1296 + test_must_fail git rebase --continue 2>err &&
1297 + grep "error: you have staged changes in your working tree" err &&
1298 + git reset --hard HEAD &&
1299 git rebase --continue &&
1300 test_cmp_rev HEAD I
1301 '
@@ -1310,6 +1316,11 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'
1316 test_cmp_rev REBASE_HEAD I &&
1317 rm file6 &&
1318 test_path_is_missing .git/rebase-merge/patch &&
1319 + echo changed >file1 &&
1320 + git add file1 &&
1321 + test_must_fail git rebase --continue 2>err &&
1322 + grep "error: you have staged changes in your working tree" err &&
1323 + git reset --hard HEAD &&
1324 git rebase --continue &&
1325 test $(git cat-file commit HEAD | sed -ne \$p) = I &&
1326 git reset --hard original-branch2
@@ -1330,6 +1341,11 @@ test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '
1341 test_cmp_rev REBASE_HEAD I &&
1342 rm file6 &&
1343 test_path_is_missing .git/rebase-merge/patch &&
1344 + echo changed >file1 &&
1345 + git add file1 &&
1346 + test_must_fail git rebase --continue 2>err &&
1347 + grep "error: you have staged changes in your working tree" err &&
1348 + git reset --hard HEAD &&
1349 git rebase --continue &&
1350 test $(git cat-file commit HEAD | sed -ne \$p) = I
1351 '
t/t3430-rebase-merges.sh
+4
@@ -169,6 +169,10 @@ test_expect_success 'failed `merge -C` writes patch (may be rescheduled, too)' '
169 grep "^merge -C .* G$" .git/rebase-merge/done &&
170 grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo &&
171 test_path_is_missing .git/rebase-merge/patch &&
172 + echo changed >file1 &&
173 + git add file1 &&
174 + test_must_fail git rebase --continue 2>err &&
175 + grep "error: you have staged changes in your working tree" err &&
176
177 : fail because of merge conflict &&
178 git reset --hard conflicting-G &&