sequencer: make sequencer_make_script() write its script to a strbuf

This makes sequencer_make_script() write its script to a strbuf (ie. the buffer of a todo_list) instead of a FILE. This reduce the amount of read/write made by rebase interactive. 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 d358fc286d1da690fb4acea629457faa9010944a
3 files changed +28 -31
builtin/rebase--interactive.c
+8 -5
@@ -71,7 +71,8 @@ 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;
74 + FILE *todo_list_file;
75 + struct todo_list todo_list = TODO_LIST_INIT;
76
77 if (prepare_branch_to_be_rebased(opts, switch_to))
78 return -1;
@@ -93,8 +94,8 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
94 if (!upstream && squash_onto)
95 write_file(path_squash_onto(), "%s\n", squash_onto);
96
96 - todo_list = fopen(rebase_path_todo(), "w");
97 - if (!todo_list) {
97 + todo_list_file = fopen(rebase_path_todo(), "w");
98 + if (!todo_list_file) {
99 free(revisions);
100 free(shortrevisions);
101
@@ -105,10 +106,11 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
106 if (restrict_revision)
107 argv_array_push(&make_script_args, restrict_revision);
108
108 - ret = sequencer_make_script(the_repository, todo_list,
109 + ret = sequencer_make_script(the_repository, &todo_list.buf,
110 make_script_args.argc, make_script_args.argv,
111 flags);
111 - fclose(todo_list);
112 + fputs(todo_list.buf.buf, todo_list_file);
113 + fclose(todo_list_file);
114
115 if (ret)
116 error(_("could not generate todo list"));
@@ -121,6 +123,7 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
123
124 free(revisions);
125 free(shortrevisions);
126 + todo_list_release(&todo_list);
127 argv_array_clear(&make_script_args);
128
129 return ret;
sequencer.c
+18 -23
@@ -4215,7 +4215,7 @@ static const char *label_oid(struct object_id *oid, const char *label,
4215 }
4216
4217 static int make_script_with_merges(struct pretty_print_context *pp,
4218 - struct rev_info *revs, FILE *out,
4218 + struct rev_info *revs, struct strbuf *out,
4219 unsigned flags)
4220 {
4221 int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
@@ -4360,7 +4360,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4360 * gathering commits not yet shown, reversing the list on the fly,
4361 * then outputting that list (labeling revisions as needed).
4362 */
4363 - fprintf(out, "%s onto\n", cmd_label);
4363 + strbuf_addf(out, "%s onto\n", cmd_label);
4364 for (iter = tips; iter; iter = iter->next) {
4365 struct commit_list *list = NULL, *iter2;
4366
@@ -4370,9 +4370,9 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4370 entry = oidmap_get(&state.commit2label, &commit->object.oid);
4371
4372 if (entry)
4373 - fprintf(out, "\n%c Branch %s\n", comment_line_char, entry->string);
4373 + strbuf_addf(out, "\n%c Branch %s\n", comment_line_char, entry->string);
4374 else
4375 - fprintf(out, "\n");
4375 + strbuf_addch(out, '\n');
4376
4377 while (oidset_contains(&interesting, &commit->object.oid) &&
4378 !oidset_contains(&shown, &commit->object.oid)) {
@@ -4385,8 +4385,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4385 }
4386
4387 if (!commit)
4388 - fprintf(out, "%s %s\n", cmd_reset,
4389 - rebase_cousins ? "onto" : "[new root]");
4388 + strbuf_addf(out, "%s %s\n", cmd_reset,
4389 + rebase_cousins ? "onto" : "[new root]");
4390 else {
4391 const char *to = NULL;
4392
@@ -4399,12 +4399,12 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4399 &state);
4400
4401 if (!to || !strcmp(to, "onto"))
4402 - fprintf(out, "%s onto\n", cmd_reset);
4402 + strbuf_addf(out, "%s onto\n", cmd_reset);
4403 else {
4404 strbuf_reset(&oneline);
4405 pretty_print_commit(pp, commit, &oneline);
4406 - fprintf(out, "%s %s # %s\n",
4407 - cmd_reset, to, oneline.buf);
4406 + strbuf_addf(out, "%s %s # %s\n",
4407 + cmd_reset, to, oneline.buf);
4408 }
4409 }
4410
@@ -4413,11 +4413,11 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4413 entry = oidmap_get(&commit2todo, oid);
4414 /* only show if not already upstream */
4415 if (entry)
4416 - fprintf(out, "%s\n", entry->string);
4416 + strbuf_addf(out, "%s\n", entry->string);
4417 entry = oidmap_get(&state.commit2label, oid);
4418 if (entry)
4419 - fprintf(out, "%s %s\n",
4420 - cmd_label, entry->string);
4419 + strbuf_addf(out, "%s %s\n",
4420 + cmd_label, entry->string);
4421 oidset_insert(&shown, oid);
4422 }
4423
@@ -4439,13 +4439,11 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4439 return 0;
4440 }
4441
4442 -int sequencer_make_script(struct repository *r, FILE *out,
4443 - int argc, const char **argv,
4444 - unsigned flags)
4442 +int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
4443 + const char **argv, unsigned flags)
4444 {
4445 char *format = NULL;
4446 struct pretty_print_context pp = {0};
4448 - struct strbuf buf = STRBUF_INIT;
4447 struct rev_info revs;
4448 struct commit *commit;
4449 int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
@@ -4488,16 +4486,13 @@ int sequencer_make_script(struct repository *r, FILE *out,
4486
4487 if (!is_empty && (commit->object.flags & PATCHSAME))
4488 continue;
4491 - strbuf_reset(&buf);
4489 if (!keep_empty && is_empty)
4493 - strbuf_addf(&buf, "%c ", comment_line_char);
4494 - strbuf_addf(&buf, "%s %s ", insn,
4490 + strbuf_addf(out, "%c ", comment_line_char);
4491 + strbuf_addf(out, "%s %s ", insn,
4492 oid_to_hex(&commit->object.oid));
4496 - pretty_print_commit(&pp, commit, &buf);
4497 - strbuf_addch(&buf, '\n');
4498 - fputs(buf.buf, out);
4493 + pretty_print_commit(&pp, commit, out);
4494 + strbuf_addch(out, '\n');
4495 }
4500 - strbuf_release(&buf);
4496 return 0;
4497 }
4498
sequencer.h
+2 -3
@@ -142,9 +142,8 @@ int sequencer_remove_state(struct replay_opts *opts);
142 #define TODO_LIST_REBASE_COUSINS (1U << 4)
143 #define TODO_LIST_APPEND_TODO_HELP (1U << 5)
144
145 -int sequencer_make_script(struct repository *r, FILE *out, int argc,
146 - const char **argv,
147 - unsigned flags);
145 +int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
146 + const char **argv, unsigned flags);
147
148 int sequencer_add_exec_commands(struct repository *r,
149 struct string_list *commands);