diff --git a/sequencer.c b/sequencer.c index ffa4334982..894c7538d5 100644 --- a/sequencer.c +++ b/sequencer.c @@ -4700,52 +4700,22 @@ int check_todo_list_from_file(struct repository *r) return res; } -static int rewrite_file(const char *path, const char *buf, size_t len) -{ - int rc = 0; - int fd = open(path, O_WRONLY | O_TRUNC); - if (fd < 0) - return error_errno(_("could not open '%s' for writing"), path); - if (write_in_full(fd, buf, len) < 0) - rc = error_errno(_("could not write to '%s'"), path); - if (close(fd) && !rc) - rc = error_errno(_("could not close '%s'"), path); - return rc; -} - /* skip picking commits whose parents are unchanged */ -static int skip_unnecessary_picks(struct repository *r, struct object_id *output_oid) +static int skip_unnecessary_picks(struct repository *r, + struct todo_list *todo_list, + struct object_id *base_oid) { - const char *todo_file = rebase_path_todo(); - struct strbuf buf = STRBUF_INIT; - struct todo_list todo_list = TODO_LIST_INIT; struct object_id *parent_oid; - int fd, i; + int i; - if (!read_oneliner(&buf, rebase_path_onto(), 0)) - return error(_("could not read 'onto'")); - if (get_oid(buf.buf, output_oid)) { - strbuf_release(&buf); - return error(_("need a HEAD to fixup")); - } - strbuf_release(&buf); - - if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0) - return -1; - if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list) < 0) { - todo_list_release(&todo_list); - return -1; - } - - for (i = 0; i < todo_list.nr; i++) { - struct todo_item *item = todo_list.items + i; + for (i = 0; i < todo_list->nr; i++) { + struct todo_item *item = todo_list->items + i; if (item->command >= TODO_NOOP) continue; if (item->command != TODO_PICK) break; if (parse_commit(item->commit)) { - todo_list_release(&todo_list); return error(_("could not parse commit '%s'"), oid_to_hex(&item->commit->object.oid)); } @@ -4754,42 +4724,26 @@ static int skip_unnecessary_picks(struct repository *r, struct object_id *output if (item->commit->parents->next) break; /* merge commit */ parent_oid = &item->commit->parents->item->object.oid; - if (!oideq(parent_oid, output_oid)) + if (!oideq(parent_oid, base_oid)) break; - oidcpy(output_oid, &item->commit->object.oid); + oidcpy(base_oid, &item->commit->object.oid); } if (i > 0) { - int offset = get_item_line_offset(&todo_list, i); const char *done_path = rebase_path_done(); - fd = open(done_path, O_CREAT | O_WRONLY | O_APPEND, 0666); - if (fd < 0) { - error_errno(_("could not open '%s' for writing"), - done_path); - todo_list_release(&todo_list); - return -1; - } - if (write_in_full(fd, todo_list.buf.buf, offset) < 0) { + if (todo_list_write_to_file(r, todo_list, done_path, NULL, NULL, i, 0)) { error_errno(_("could not write to '%s'"), done_path); - todo_list_release(&todo_list); - close(fd); - return -1; - } - close(fd); - - if (rewrite_file(rebase_path_todo(), todo_list.buf.buf + offset, - todo_list.buf.len - offset) < 0) { - todo_list_release(&todo_list); return -1; } - todo_list.current = i; - if (is_fixup(peek_command(&todo_list, 0))) - record_in_rewritten(output_oid, peek_command(&todo_list, 0)); + MOVE_ARRAY(todo_list->items, todo_list->items + i, todo_list->nr - i); + todo_list->nr -= i; + todo_list->current = 0; + + if (is_fixup(peek_command(todo_list, 0))) + record_in_rewritten(base_oid, peek_command(todo_list, 0)); } - todo_list_release(&todo_list); - return 0; } @@ -4860,6 +4814,11 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla return -1; } + if (opts->allow_ff && skip_unnecessary_picks(r, &new_todo, &oid)) { + todo_list_release(&new_todo); + return error(_("could not skip unnecessary pick commands")); + } + if (todo_list_write_to_file(r, &new_todo, todo_file, NULL, NULL, -1, flags & ~(TODO_LIST_SHORTEN_IDS))) { todo_list_release(&new_todo); @@ -4868,9 +4827,6 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla todo_list_release(&new_todo); - if (opts->allow_ff && skip_unnecessary_picks(r, &oid)) - return error(_("could not skip unnecessary pick commands")); - if (checkout_onto(opts, onto_name, oid_to_hex(&oid), orig_head)) return -1;