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[];