Hi Phillip, I’ve just reread this message and have a couple of additionnal comments. Le 01/02/2019 à 12:03, Phillip Wood a écrit : > Hi Alban > > This looks good apart from some missing error handling. > > On 29/01/2019 15:01, Alban Gruin wrote: >> edit_todo_list() is changed to work on a todo_list, and to handle the >> initial edition of the todo list (ie. making a backup of the todo >> list). >> >> It does not check for dropped commits yet, as todo_list_check() does not >> take the commits that have already been processed by the rebase (ie. the >> todo list is edited in the middle of a rebase session). >> >> Signed-off-by: Alban Gruin <alban.gruin@xxxxxxxxx> >> --- >> builtin/rebase--interactive.c | 24 +++++++++++++++++- >> rebase-interactive.c | 48 ++++++++++++++++++----------------- >> rebase-interactive.h | 4 ++- >> sequencer.c | 3 +-- >> sequencer.h | 1 + >> 5 files changed, 53 insertions(+), 27 deletions(-) >> >> diff --git a/builtin/rebase--interactive.c >> b/builtin/rebase--interactive.c >> index 2dbf8fc08b..645ac587f7 100644 >> --- a/builtin/rebase--interactive.c >> +++ b/builtin/rebase--interactive.c >> @@ -13,6 +13,28 @@ static GIT_PATH_FUNC(path_state_dir, "rebase-merge/") >> static GIT_PATH_FUNC(path_squash_onto, "rebase-merge/squash-onto") >> static GIT_PATH_FUNC(path_interactive, "rebase-merge/interactive") >> +static int edit_todo_file(unsigned flags) >> +{ >> + const char *todo_file = rebase_path_todo(); >> + struct todo_list todo_list = TODO_LIST_INIT, >> + new_todo = TODO_LIST_INIT; >> + >> + if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0) >> + return error_errno(_("could not read '%s'."), todo_file); >> + >> + strbuf_stripspace(&todo_list.buf, 1); >> + if (!edit_todo_list(the_repository, &todo_list, >> + &new_todo, NULL, NULL, flags) && >> + todo_list_write_to_file(the_repository, &new_todo, todo_file, >> NULL, NULL, >> + -1, flags & ~(TODO_LIST_SHORTEN_IDS)) < 0) >> + return error_errno(_("could not write '%s'"), todo_file); > > If edit_todo_list() fails then the function returns 0. I think you need > to do > > if (edit_todo_list() || todo_list_write_file()) > return error... > > todo_list_write_file() forwards the return value of write_message() > which is 0/-1 so there is no need for the '< 0' > With your proposed condition, if edit_todo_list() fails, the error "could not write '%s'" will be shown, if I’m not mistaken. But in my version, if edit_todo_list() fails, the return value is 0. Perhaps I should write something like this instead: int res = 0; … res = edit_todo_list(); if (!res && todo_list_write_to_file()) return error; … return res; >> + >> + todo_list_release(&todo_list); >> + todo_list_release(&new_todo); >> + >> + return 0; >> +} >> + >> static int get_revision_ranges(const char *upstream, const char *onto, >> const char **head_hash, >> char **revisions, char **shortrevisions) >> @@ -242,7 +264,7 @@ int cmd_rebase__interactive(int argc, const char >> **argv, const char *prefix) >> break; >> } >> case EDIT_TODO: >> - ret = edit_todo_list(the_repository, flags); >> + ret = edit_todo_file(flags); >> break; >> case SHOW_CURRENT_PATCH: { >> struct child_process cmd = CHILD_PROCESS_INIT; >> diff --git a/rebase-interactive.c b/rebase-interactive.c >> index 807f8370db..3301efbe52 100644 >> --- a/rebase-interactive.c >> +++ b/rebase-interactive.c >> @@ -87,35 +87,37 @@ void append_todo_help(unsigned keep_empty, int >> command_count, >> } >> } >> -int edit_todo_list(struct repository *r, unsigned flags) >> +int edit_todo_list(struct repository *r, struct todo_list *todo_list, >> + struct todo_list *new_todo, const char *shortrevisions, >> + const char *shortonto, unsigned flags) >> { >> const char *todo_file = rebase_path_todo(); >> - struct todo_list todo_list = TODO_LIST_INIT; >> - int res = 0; >> - >> - if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0) >> - return error_errno(_("could not read '%s'."), todo_file); >> - >> - strbuf_stripspace(&todo_list.buf, 1); >> - todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list); >> - if (todo_list_write_to_file(r, &todo_list, todo_file, NULL, NULL, >> -1, >> - flags | TODO_LIST_SHORTEN_IDS | >> TODO_LIST_APPEND_TODO_HELP)) { >> - todo_list_release(&todo_list); >> - return -1; >> + unsigned initial = shortrevisions && shortonto; >> + >> + if (initial) { >> + todo_list_write_to_file(r, todo_list, todo_file, >> shortrevisions, shortonto, >> + -1, flags | TODO_LIST_SHORTEN_IDS | >> TODO_LIST_APPEND_TODO_HELP); > > This has lost the error handling when we cannot write the file > >> + >> + if (copy_file(rebase_path_todo_backup(), todo_file, 0666)) >> + return error(_("could not copy '%s' to '%s'."), todo_file, >> + rebase_path_todo_backup()); >> + } else { >> + todo_list_parse_insn_buffer(r, todo_list->buf.buf, todo_list); >> + todo_list_write_to_file(r, todo_list, todo_file, NULL, NULL, -1, >> + flags | TODO_LIST_SHORTEN_IDS | >> TODO_LIST_APPEND_TODO_HELP); > > error handling again > I agree for todo_list_write_to_file(), but todo_list_parse_insn_buffer() already shows an error, and here it should not return -- we want to edit the todo list to remove an error, but git would fail because the todo list has an error. -- Alban