git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/6] rebase -i: impove handling of failed commands

From
PGPhillip Wood via GitGitGadget <gitgitgadget@gmail.com>
Date
Apr 21, 2023, 14:57 UTC
Message-ID
<pull.1492.v2.git.1682089074.gitgitgadget@gmail.com>
In-Reply-To
<pull.1492.git.1679237337683.gitgitgadget@gmail.com>

This series fixes several bugs in the way we handle a commit cannot be picked because it would overwrite an untracked file.

 * after a failed pick "git rebase --continue" will happily commit any
   staged changes even though no commit was picked.
 * the commit of the failed pick is recorded as rewritten even though no
   commit was picked.
 * the "done" file used by "git status" to show the recently executed
   commands contains an incorrect entry.

Thanks for the comments on V1, this series has now grown somewhat. Previously I was worried that refactoring would change the behavior, but having thought about it the current behavior is wrong and should be changed.

Changes since V1:

Rebased onto master to avoid a conflict with ab/remove-implicit-use-of-the-repository

 * Patches 1-3 are new preparatory changes
 * Patches 4 & 5 are new and fix the first two issues listed above.
 * Patch 6 is the old patch 1 which has been rebased and the commit message
   reworded. It fixes the last issues listed above.
Phillip Wood (6):
  rebase -i: move unlink() calls
  rebase -i: remove patch file after conflict resolution
  sequencer: factor out part of pick_commits()
  rebase --continue: refuse to commit after failed command
  rebase: fix rewritten list for failed pick
  rebase -i: fix adding failed command to the todo list
 sequencer.c                   | 170 ++++++++++++++++++----------------
 t/t3404-rebase-interactive.sh |  49 +++++++---
 t/t3430-rebase-merges.sh      |  35 +++++--
 t/t5407-post-rewrite-hook.sh  |  11 +++
 4 files changed, 165 insertions(+), 100 deletions(-)
base-commit: 9c6990cca24301ae8f82bf6291049667a0aef14b
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1492%2Fphillipwood%2Frebase-dont-write-done-when-rescheduling-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1492/phillipwood/rebase-dont-write-done-when-rescheduling-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1492
Range-diff vs v1:
 -:  ----------- > 1:  3dfb2c6903b rebase -i: move unlink() calls
 -:  ----------- > 2:  227aea031b5 rebase -i: remove patch file after conflict resolution
 -:  ----------- > 3:  31bb644e769 sequencer: factor out part of pick_commits()
 -:  ----------- > 4:  9356d14b09a rebase --continue: refuse to commit after failed command
 -:  ----------- > 5:  f8e64c1b631 rebase: fix rewritten list for failed pick
 1:  dc51a7499bc ! 6:  a836b049b90 rebase -i: do not update "done" when rescheduling command
     @@ Metadata
      Author: Phillip Wood <phillip.wood@dunelm.org.uk>
      
       ## Commit message ##
     -    rebase -i: do not update "done" when rescheduling command
     +    rebase -i: fix adding failed command to the todo list
      
     -    As the sequencer executes todo commands it appends them to
     -    .git/rebase-merge/done. This file is used by "git status" to show the
     -    recently executed commands. Unfortunately when a command is rescheduled
     +    When rebasing commands are moved from the todo list in "git-rebase-todo"
     +    to the "done" file (which is used by "git status" to show the recently
     +    executed commands) just before they are executed. This means that if a
     +    command fails because it would overwrite an untracked file it has to be
     +    added back into the todo list before the rebase stops for the user to
     +    fix the problem.
     +
     +    Unfortunately when a failed command is added back into the todo list
          the command preceding it is erroneously appended to the "done" file.
     -    This means that when rebase stops after rescheduling "pick B" the "done"
     +    This means that when rebase stops after "pick B" fails the "done"
          file contains
      
                  pick A
     @@ Commit message
                  pick A
                  pick B
      
     -    Fix this by not updating the "done" file when adding a rescheduled
     -    command back into the "todo" file. A couple of the existing tests are
     +    Fix this by not updating the "done" file when adding a failed command
     +    back into the "git-rebase-todo" file. A couple of the existing tests are
          modified to improve their coverage as none of them trigger this bug or
          check the "done" file.
      
     -    Note that the rescheduled command will still be appended to the "done"
     -    file again when it is successfully executed. Arguably it would be better
     -    not to do that but fixing it would be more involved.
     -
          Reported-by: Stefan Haller <lists@haller-berlin.de>
          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
      
     @@ sequencer.c: static int pick_commits(struct repository *r,
       		int check_todo = 0;
       
      -		if (save_todo(todo_list, opts))
     -+		if (save_todo(todo_list, opts, 0))
     ++		if (save_todo(todo_list, opts, reschedule))
       			return -1;
       		if (is_rebase_i(opts)) {
       			if (item->command != TODO_COMMENT) {
     -@@ sequencer.c: static int pick_commits(struct repository *r,
     - 							    todo_list->current),
     - 				       get_item_line(todo_list,
     - 						     todo_list->current));
     --				todo_list->current--;
     --				if (save_todo(todo_list, opts))
     -+				if (save_todo(todo_list, opts, 1))
     - 					return -1;
     - 			}
     - 			if (item->command == TODO_EDIT) {
      @@ sequencer.c: static int pick_commits(struct repository *r,
       			       get_item_line_length(todo_list,
       						    todo_list->current),
       			       get_item_line(todo_list, todo_list->current));
      -			todo_list->current--;
      -			if (save_todo(todo_list, opts))
     -+			if (save_todo(todo_list, opts, 1))
     ++			if (save_todo(todo_list, opts, reschedule))
       				return -1;
       			if (item->commit)
     - 				return error_with_patch(r,
     + 				write_rebase_head(&item->commit->object.oid);
      
       ## t/t3404-rebase-interactive.sh ##
      @@ t/t3404-rebase-interactive.sh: test_expect_success 'todo count' '
     @@ t/t3404-rebase-interactive.sh: test_expect_success 'todo count' '
      +	head -n3 todo >expect &&
      +	test_cmp expect .git/rebase-merge/done &&
      +	rm file2 &&
     + 	test_path_is_missing .git/rebase-merge/author-script &&
     + 	test_path_is_missing .git/rebase-merge/patch &&
     + 	test_path_is_missing .git/MERGE_MSG &&
     +@@ t/t3404-rebase-interactive.sh: test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '
     + 	grep "error: you have staged changes in your working tree" err &&
     + 	git reset --hard HEAD &&
       	git rebase --continue &&
      -	test_cmp_rev HEAD I
      +	test_cmp_rev HEAD D &&
-- 
gitgitgadget
Previous: Johannes SchindelinNext: Phillip Wood via GitGitGadget
Message 10 of 80 in “rebase -i: do not update "done" when rescheduling command”
  1. rebase -i: do not update "done" when rescheduling commandPhillip Wood via GitGitGadget, Mar 19, 2023
  2. Stefan HallerMar 20, 2023
  3. Junio C HamanoMar 20, 2023
  4. Phillip WoodMar 24, 2023
  5. Junio C HamanoMar 24, 2023
  6. Phillip WoodMar 24, 2023
  7. Johannes SchindelinMar 27, 2023
  8. Phillip WoodAug 3, 2023
  9. Johannes SchindelinAug 23, 2023
  10. 0/6 rebase -i: impove handling of failed commandsPhillip Wood via GitGitGadget, Apr 21, 2023
  11. 1/6 rebase -i: move unlink() callsPhillip Wood via GitGitGadget, Apr 21, 2023
  12. Junio C HamanoApr 21, 2023
  13. Phillip WoodApr 27, 2023
  14. 2/6 rebase -i: remove patch file after conflict resolutionPhillip Wood via GitGitGadget, Apr 21, 2023
  15. Junio C HamanoApr 21, 2023
  16. Phillip WoodApr 27, 2023
  17. Glen ChooJun 21, 2023
  18. Phillip WoodJul 14, 2023
  19. Junio C HamanoJul 14, 2023
  20. Phillip WoodJul 17, 2023
  21. 3/6 sequencer: factor out part of pick_commits()Phillip Wood via GitGitGadget, Apr 21, 2023
  22. Eric SunshineApr 21, 2023
  23. Junio C HamanoApr 21, 2023
  24. Phillip WoodApr 21, 2023
  25. Junio C HamanoApr 21, 2023
  26. 4/6 rebase --continue: refuse to commit after failed commandPhillip Wood via GitGitGadget, Apr 21, 2023
  27. Eric SunshineApr 21, 2023
  28. Junio C HamanoApr 21, 2023
  29. Glen ChooJun 21, 2023
  30. 5/6 rebase: fix rewritten list for failed pickPhillip Wood via GitGitGadget, Apr 21, 2023
  31. Glen ChooJun 21, 2023
  32. Phillip WoodJul 25, 2023
  33. Glen ChooJul 25, 2023
  34. Phillip WoodJul 26, 2023
  35. Glen ChooJul 26, 2023
  36. Phillip WoodJul 28, 2023
  37. 6/6 rebase -i: fix adding failed command to the todo listPhillip Wood via GitGitGadget, Apr 21, 2023
  38. Glen ChooJun 21, 2023
  39. Junio C HamanoApr 21, 2023
  40. Glen ChooJun 21, 2023
  41. 0/7 rebase -i: impove handling of failed commandsPhillip Wood via GitGitGadget, Aug 1, 2023
  42. 2/7 rebase -i: remove patch file after conflict resolutionPhillip Wood via GitGitGadget, Aug 1, 2023
  43. Junio C HamanoAug 1, 2023
  44. Phillip WoodAug 1, 2023
  45. 1/7 rebase -i: move unlink() callsPhillip Wood via GitGitGadget, Aug 1, 2023
  46. Junio C HamanoAug 1, 2023
  47. Phillip WoodAug 1, 2023
  48. Junio C HamanoAug 1, 2023
  49. 3/7 sequencer: use rebase_path_message()Phillip Wood via GitGitGadget, Aug 1, 2023
  50. Junio C HamanoAug 1, 2023
  51. Phillip WoodAug 1, 2023
  52. Junio C HamanoAug 2, 2023
  53. 4/7 sequencer: factor out part of pick_commits()Phillip Wood via GitGitGadget, Aug 1, 2023
  54. Johannes SchindelinAug 23, 2023
  55. 5/7 rebase: fix rewritten list for failed pickPhillip Wood via GitGitGadget, Aug 1, 2023
  56. Johannes SchindelinAug 23, 2023
  57. Phillip WoodSep 4, 2023
  58. 6/7 rebase --continue: refuse to commit after failed commandPhillip Wood via GitGitGadget, Aug 1, 2023
  59. Johannes SchindelinAug 23, 2023
  60. Phillip WoodSep 4, 2023
  61. Johannes SchindelinSep 5, 2023
  62. Junio C HamanoSep 5, 2023
  63. Phillip WoodSep 5, 2023
  64. 7/7 rebase -i: fix adding failed command to the todo listPhillip Wood via GitGitGadget, Aug 1, 2023
  65. Junio C HamanoAug 2, 2023
  66. Phillip WoodAug 3, 2023
  67. Phillip WoodAug 9, 2023
  68. Glen ChooAug 7, 2023
  69. Phillip WoodAug 9, 2023
  70. 0/7 rebase -i: impove handling of failed commandsPhillip Wood via GitGitGadget, Sep 6, 2023
  71. 3/7 sequencer: use rebase_path_message()Phillip Wood via GitGitGadget, Sep 6, 2023
  72. 2/7 rebase -i: remove patch file after conflict resolutionPhillip Wood via GitGitGadget, Sep 6, 2023
  73. 1/7 rebase -i: move unlink() callsPhillip Wood via GitGitGadget, Sep 6, 2023
  74. 4/7 sequencer: factor out part of pick_commits()Phillip Wood via GitGitGadget, Sep 6, 2023
  75. 5/7 rebase: fix rewritten list for failed pickPhillip Wood via GitGitGadget, Sep 6, 2023
  76. 6/7 rebase --continue: refuse to commit after failed commandPhillip Wood via GitGitGadget, Sep 6, 2023
  77. 7/7 rebase -i: fix adding failed command to the todo listPhillip Wood via GitGitGadget, Sep 6, 2023
  78. Junio C HamanoSep 6, 2023
  79. Johannes SchindelinSep 7, 2023
  80. Junio C HamanoSep 7, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.