sequencer: change complete_action() to use the refactored functions
authorAlban Gruin <alban.gruin@gmail.com>
Tue, 5 Mar 2019 19:17:57 +0000 (20:17 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Mar 2019 00:17:57 +0000 (09:17 +0900)
complete_action() used functions that read the todo-list file, made some
changes to it, and wrote it back to the disk.

The previous commits were dedicated to separate the part that deals with
the file from the actual logic of these functions. Now that this is
done, we can call directly the "logic" functions to avoid useless file
access.

The parsing of the list has to be done by the caller. If the buffer of
the todo list provided by the caller is empty, a `noop' command is
directly added to the todo list, without touching the buffer.

Signed-off-by: Alban Gruin <alban.gruin@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rebase--interactive.c
sequencer.c
sequencer.h
index b4190e58e1c5bb367bdef6fa3162a7cdab85433f..ffbe14cef5039e47ac1dee6f22d0a021eb2faa10 100644 (file)
@@ -71,7 +71,6 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
        const char *head_hash = NULL;
        char *revisions = NULL, *shortrevisions = NULL;
        struct argv_array make_script_args = ARGV_ARRAY_INIT;
-       FILE *todo_list_file;
        struct todo_list todo_list = TODO_LIST_INIT;
 
        if (prepare_branch_to_be_rebased(opts, switch_to))
@@ -94,14 +93,6 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
        if (!upstream && squash_onto)
                write_file(path_squash_onto(), "%s\n", squash_onto);
 
-       todo_list_file = fopen(rebase_path_todo(), "w");
-       if (!todo_list_file) {
-               free(revisions);
-               free(shortrevisions);
-
-               return error_errno(_("could not open %s"), rebase_path_todo());
-       }
-
        argv_array_pushl(&make_script_args, "", revisions, NULL);
        if (restrict_revision)
                argv_array_push(&make_script_args, restrict_revision);
@@ -109,16 +100,17 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
        ret = sequencer_make_script(the_repository, &todo_list.buf,
                                    make_script_args.argc, make_script_args.argv,
                                    flags);
-       fputs(todo_list.buf.buf, todo_list_file);
-       fclose(todo_list_file);
 
        if (ret)
                error(_("could not generate todo list"));
        else {
                discard_cache();
-               ret = complete_action(the_repository, opts, flags,
-                                     shortrevisions, onto_name, onto,
-                                     head_hash, commands, autosquash);
+               if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
+                                               &todo_list))
+                       BUG("unusable todo list");
+
+               ret = complete_action(the_repository, opts, flags, shortrevisions, onto_name,
+                                     onto, head_hash, commands, autosquash, &todo_list);
        }
 
        free(revisions);
index cf716fa5b842141ccd34837f73b4bf305482baeb..1d5cd2fc27cfc405798ddbd0297ce6987648c180 100644 (file)
@@ -4817,93 +4817,82 @@ static int skip_unnecessary_picks(struct repository *r, struct object_id *output
        return 0;
 }
 
+static int todo_list_rearrange_squash(struct todo_list *todo_list);
+
 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
                    const char *shortrevisions, const char *onto_name,
                    const char *onto, const char *orig_head, struct string_list *commands,
-                   unsigned autosquash)
+                   unsigned autosquash, struct todo_list *todo_list)
 {
        const char *shortonto, *todo_file = rebase_path_todo();
-       struct todo_list todo_list = TODO_LIST_INIT;
-       struct strbuf *buf = &(todo_list.buf);
+       struct todo_list new_todo = TODO_LIST_INIT;
+       struct strbuf *buf = &todo_list->buf;
        struct object_id oid;
-       struct stat st;
 
        get_oid(onto, &oid);
        shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV);
 
-       if (!lstat(todo_file, &st) && st.st_size == 0 &&
-           write_message("noop\n", 5, todo_file, 0))
-               return -1;
+       if (buf->len == 0) {
+               struct todo_item *item = append_new_todo(todo_list);
+               item->command = TODO_NOOP;
+               item->commit = NULL;
+               item->arg_len = item->arg_offset = item->flags = item->offset_in_buf = 0;
+       }
 
-       if (autosquash && rearrange_squash_in_todo_file(r))
+       if (autosquash && todo_list_rearrange_squash(todo_list))
                return -1;
 
        if (commands->nr)
-               sequencer_add_exec_commands(r, commands);
+               todo_list_add_exec_commands(todo_list, commands);
 
-       if (strbuf_read_file(buf, todo_file, 0) < 0)
-               return error_errno(_("could not read '%s'."), todo_file);
-
-       if (todo_list_parse_insn_buffer(r, buf->buf, &todo_list)) {
-               todo_list_release(&todo_list);
-               return error(_("unusable todo list: '%s'"), todo_file);
-       }
-
-       if (count_commands(&todo_list) == 0) {
+       if (count_commands(todo_list) == 0) {
                apply_autostash(opts);
                sequencer_remove_state(opts);
-               todo_list_release(&todo_list);
 
                return error(_("nothing to do"));
        }
 
-       strbuf_addch(buf, '\n');
-       strbuf_commented_addf(buf, Q_("Rebase %s onto %s (%d command)",
-                                     "Rebase %s onto %s (%d commands)",
-                                     count_commands(&todo_list)),
-                             shortrevisions, shortonto, count_commands(&todo_list));
-       append_todo_help(0, flags & TODO_LIST_KEEP_EMPTY, buf);
-
-       if (write_message(buf->buf, buf->len, todo_file, 0)) {
-               todo_list_release(&todo_list);
-               return -1;
-       }
+       if (todo_list_write_to_file(r, todo_list, todo_file,
+                                   shortrevisions, shortonto, -1,
+                                   flags | TODO_LIST_SHORTEN_IDS | TODO_LIST_APPEND_TODO_HELP))
+               return error_errno(_("could not write '%s'"), todo_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());
 
-       if (transform_todo_file(r, flags | TODO_LIST_SHORTEN_IDS))
-               return error(_("could not transform the todo list"));
-
-       strbuf_reset(buf);
-
-       if (launch_sequence_editor(todo_file, buf, NULL)) {
+       if (launch_sequence_editor(todo_file, &new_todo.buf, NULL)) {
                apply_autostash(opts);
                sequencer_remove_state(opts);
-               todo_list_release(&todo_list);
 
                return -1;
        }
 
-       strbuf_stripspace(buf, 1);
-       if (buf->len == 0) {
+       strbuf_stripspace(&new_todo.buf, 1);
+       if (new_todo.buf.len == 0) {
                apply_autostash(opts);
                sequencer_remove_state(opts);
-               todo_list_release(&todo_list);
+               todo_list_release(&new_todo);
 
                return error(_("nothing to do"));
        }
 
-       todo_list_release(&todo_list);
-
-       if (check_todo_list_from_file(r)) {
+       if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) ||
+           todo_list_check(todo_list, &new_todo)) {
+               fprintf(stderr, _(edit_todo_list_advice));
                checkout_onto(opts, onto_name, onto, orig_head);
+               todo_list_release(&new_todo);
+
                return -1;
        }
 
-       if (transform_todo_file(r, flags & ~(TODO_LIST_SHORTEN_IDS)))
-               return error(_("could not transform the todo list"));
+       if (todo_list_write_to_file(r, &new_todo, todo_file, NULL, NULL, -1,
+                                   flags & ~(TODO_LIST_SHORTEN_IDS))) {
+               todo_list_release(&new_todo);
+               return error_errno(_("could not write '%s'"), todo_file);
+       }
+
+       todo_list_release(&new_todo);
 
        if (opts->allow_ff && skip_unnecessary_picks(r, &oid))
                return error(_("could not skip unnecessary pick commands"));
index e25f5151d37fab6a8c1753f929f4435b1478781d..7029b39cd690fdd58f06bc842106851aa4e9166b 100644 (file)
@@ -152,7 +152,7 @@ int check_todo_list_from_file(struct repository *r);
 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
                    const char *shortrevisions, const char *onto_name,
                    const char *onto, const char *orig_head, struct string_list *commands,
-                   unsigned autosquash);
+                   unsigned autosquash, struct todo_list *todo_list);
 int rearrange_squash_in_todo_file(struct repository *r);
 
 extern const char sign_off_header[];