sequencer: change complete_action() to use the refactored functions

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>

Alban Gruin committed Mar 5, 2019 at 20:17 UTC 94bcad797966b6a3490bc6806d3ee3eed54da9d9
3 files changed +41 -60
builtin/rebase--interactive.c
+6 -14
@@ -71,7 +71,6 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
71 const char *head_hash = NULL;
72 char *revisions = NULL, *shortrevisions = NULL;
73 struct argv_array make_script_args = ARGV_ARRAY_INIT;
74 - FILE *todo_list_file;
74 struct todo_list todo_list = TODO_LIST_INIT;
75
76 if (prepare_branch_to_be_rebased(opts, switch_to))
@@ -94,14 +93,6 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
93 if (!upstream && squash_onto)
94 write_file(path_squash_onto(), "%s\n", squash_onto);
95
97 - todo_list_file = fopen(rebase_path_todo(), "w");
98 - if (!todo_list_file) {
99 - free(revisions);
100 - free(shortrevisions);
101 -
102 - return error_errno(_("could not open %s"), rebase_path_todo());
103 - }
104 -
96 argv_array_pushl(&make_script_args, "", revisions, NULL);
97 if (restrict_revision)
98 argv_array_push(&make_script_args, restrict_revision);
@@ -109,16 +100,17 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
100 ret = sequencer_make_script(the_repository, &todo_list.buf,
101 make_script_args.argc, make_script_args.argv,
102 flags);
112 - fputs(todo_list.buf.buf, todo_list_file);
113 - fclose(todo_list_file);
103
104 if (ret)
105 error(_("could not generate todo list"));
106 else {
107 discard_cache();
119 - ret = complete_action(the_repository, opts, flags,
120 - shortrevisions, onto_name, onto,
121 - head_hash, commands, autosquash);
108 + if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
109 + &todo_list))
110 + BUG("unusable todo list");
111 +
112 + ret = complete_action(the_repository, opts, flags, shortrevisions, onto_name,
113 + onto, head_hash, commands, autosquash, &todo_list);
114 }
115
116 free(revisions);
sequencer.c
+34 -45
@@ -4817,93 +4817,82 @@ static int skip_unnecessary_picks(struct repository *r, struct object_id *output
4817 return 0;
4818 }
4819
4820 +static int todo_list_rearrange_squash(struct todo_list *todo_list);
4821 +
4822 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
4823 const char *shortrevisions, const char *onto_name,
4824 const char *onto, const char *orig_head, struct string_list *commands,
4823 - unsigned autosquash)
4825 + unsigned autosquash, struct todo_list *todo_list)
4826 {
4827 const char *shortonto, *todo_file = rebase_path_todo();
4826 - struct todo_list todo_list = TODO_LIST_INIT;
4827 - struct strbuf *buf = &(todo_list.buf);
4828 + struct todo_list new_todo = TODO_LIST_INIT;
4829 + struct strbuf *buf = &todo_list->buf;
4830 struct object_id oid;
4829 - struct stat st;
4831
4832 get_oid(onto, &oid);
4833 shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV);
4834
4834 - if (!lstat(todo_file, &st) && st.st_size == 0 &&
4835 - write_message("noop\n", 5, todo_file, 0))
4836 - return -1;
4835 + if (buf->len == 0) {
4836 + struct todo_item *item = append_new_todo(todo_list);
4837 + item->command = TODO_NOOP;
4838 + item->commit = NULL;
4839 + item->arg_len = item->arg_offset = item->flags = item->offset_in_buf = 0;
4840 + }
4841
4838 - if (autosquash && rearrange_squash_in_todo_file(r))
4842 + if (autosquash && todo_list_rearrange_squash(todo_list))
4843 return -1;
4844
4845 if (commands->nr)
4842 - sequencer_add_exec_commands(r, commands);
4846 + todo_list_add_exec_commands(todo_list, commands);
4847
4844 - if (strbuf_read_file(buf, todo_file, 0) < 0)
4845 - return error_errno(_("could not read '%s'."), todo_file);
4846 -
4847 - if (todo_list_parse_insn_buffer(r, buf->buf, &todo_list)) {
4848 - todo_list_release(&todo_list);
4849 - return error(_("unusable todo list: '%s'"), todo_file);
4850 - }
4851 -
4852 - if (count_commands(&todo_list) == 0) {
4848 + if (count_commands(todo_list) == 0) {
4849 apply_autostash(opts);
4850 sequencer_remove_state(opts);
4855 - todo_list_release(&todo_list);
4851
4852 return error(_("nothing to do"));
4853 }
4854
4860 - strbuf_addch(buf, '\n');
4861 - strbuf_commented_addf(buf, Q_("Rebase %s onto %s (%d command)",
4862 - "Rebase %s onto %s (%d commands)",
4863 - count_commands(&todo_list)),
4864 - shortrevisions, shortonto, count_commands(&todo_list));
4865 - append_todo_help(0, flags & TODO_LIST_KEEP_EMPTY, buf);
4866 -
4867 - if (write_message(buf->buf, buf->len, todo_file, 0)) {
4868 - todo_list_release(&todo_list);
4869 - return -1;
4870 - }
4855 + if (todo_list_write_to_file(r, todo_list, todo_file,
4856 + shortrevisions, shortonto, -1,
4857 + flags | TODO_LIST_SHORTEN_IDS | TODO_LIST_APPEND_TODO_HELP))
4858 + return error_errno(_("could not write '%s'"), todo_file);
4859
4860 if (copy_file(rebase_path_todo_backup(), todo_file, 0666))
4861 return error(_("could not copy '%s' to '%s'."), todo_file,
4862 rebase_path_todo_backup());
4863
4876 - if (transform_todo_file(r, flags | TODO_LIST_SHORTEN_IDS))
4877 - return error(_("could not transform the todo list"));
4878 -
4879 - strbuf_reset(buf);
4880 -
4881 - if (launch_sequence_editor(todo_file, buf, NULL)) {
4864 + if (launch_sequence_editor(todo_file, &new_todo.buf, NULL)) {
4865 apply_autostash(opts);
4866 sequencer_remove_state(opts);
4884 - todo_list_release(&todo_list);
4867
4868 return -1;
4869 }
4870
4889 - strbuf_stripspace(buf, 1);
4890 - if (buf->len == 0) {
4871 + strbuf_stripspace(&new_todo.buf, 1);
4872 + if (new_todo.buf.len == 0) {
4873 apply_autostash(opts);
4874 sequencer_remove_state(opts);
4893 - todo_list_release(&todo_list);
4875 + todo_list_release(&new_todo);
4876
4877 return error(_("nothing to do"));
4878 }
4879
4898 - todo_list_release(&todo_list);
4899 -
4900 - if (check_todo_list_from_file(r)) {
4880 + if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) ||
4881 + todo_list_check(todo_list, &new_todo)) {
4882 + fprintf(stderr, _(edit_todo_list_advice));
4883 checkout_onto(opts, onto_name, onto, orig_head);
4884 + todo_list_release(&new_todo);
4885 +
4886 return -1;
4887 }
4888
4905 - if (transform_todo_file(r, flags & ~(TODO_LIST_SHORTEN_IDS)))
4906 - return error(_("could not transform the todo list"));
4889 + if (todo_list_write_to_file(r, &new_todo, todo_file, NULL, NULL, -1,
4890 + flags & ~(TODO_LIST_SHORTEN_IDS))) {
4891 + todo_list_release(&new_todo);
4892 + return error_errno(_("could not write '%s'"), todo_file);
4893 + }
4894 +
4895 + todo_list_release(&new_todo);
4896
4897 if (opts->allow_ff && skip_unnecessary_picks(r, &oid))
4898 return error(_("could not skip unnecessary pick commands"));
sequencer.h
+1 -1
@@ -152,7 +152,7 @@ int check_todo_list_from_file(struct repository *r);
152 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
153 const char *shortrevisions, const char *onto_name,
154 const char *onto, const char *orig_head, struct string_list *commands,
155 - unsigned autosquash);
155 + unsigned autosquash, struct todo_list *todo_list);
156 int rearrange_squash_in_todo_file(struct repository *r);
157
158 extern const char sign_off_header[];