Skip to content

Commit 464c824

Browse files
committed
Merge branch 'ag/sequencer-reduce-rewriting-todo' into pw/rebase-i-internal
* ag/sequencer-reduce-rewriting-todo: rebase--interactive: move transform_todo_file() sequencer: use edit_todo_list() in complete_action() rebase-interactive: rewrite edit_todo_list() to handle the initial edit rebase-interactive: append_todo_help() changes rebase-interactive: use todo_list_write_to_file() in edit_todo_list() sequencer: refactor skip_unnecessary_picks() to work on a todo_list rebase--interactive: move rearrange_squash_in_todo_file() rebase--interactive: move sequencer_add_exec_commands() sequencer: change complete_action() to use the refactored functions sequencer: make sequencer_make_script() write its script to a strbuf sequencer: refactor rearrange_squash() to work on a todo_list sequencer: refactor sequencer_add_exec_commands() to work on a todo_list sequencer: refactor check_todo_list() to work on a todo_list sequencer: introduce todo_list_write_to_file() sequencer: refactor transform_todos() to work on a todo_list sequencer: remove the 'arg' field from todo_item sequencer: make the todo_list structure public sequencer: changes in parse_insn_buffer()
2 parents e902e9b + ed35d18 commit 464c824

File tree

5 files changed

+553
-482
lines changed

5 files changed

+553
-482
lines changed

builtin/rebase--interactive.c

Lines changed: 123 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,103 @@ static GIT_PATH_FUNC(path_state_dir, "rebase-merge/")
1414
static GIT_PATH_FUNC(path_squash_onto, "rebase-merge/squash-onto")
1515
static GIT_PATH_FUNC(path_interactive, "rebase-merge/interactive")
1616

17+
static int add_exec_commands(struct string_list *commands)
18+
{
19+
const char *todo_file = rebase_path_todo();
20+
struct todo_list todo_list = TODO_LIST_INIT;
21+
int res;
22+
23+
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
24+
return error_errno(_("could not read '%s'."), todo_file);
25+
26+
if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
27+
&todo_list)) {
28+
todo_list_release(&todo_list);
29+
return error(_("unusable todo list: '%s'"), todo_file);
30+
}
31+
32+
todo_list_add_exec_commands(&todo_list, commands);
33+
res = todo_list_write_to_file(the_repository, &todo_list,
34+
todo_file, NULL, NULL, -1, 0);
35+
todo_list_release(&todo_list);
36+
37+
if (res)
38+
return error_errno(_("could not write '%s'."), todo_file);
39+
return 0;
40+
}
41+
42+
static int rearrange_squash_in_todo_file(void)
43+
{
44+
const char *todo_file = rebase_path_todo();
45+
struct todo_list todo_list = TODO_LIST_INIT;
46+
int res = 0;
47+
48+
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
49+
return error_errno(_("could not read '%s'."), todo_file);
50+
if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
51+
&todo_list)) {
52+
todo_list_release(&todo_list);
53+
return error(_("unusable todo list: '%s'"), todo_file);
54+
}
55+
56+
res = todo_list_rearrange_squash(&todo_list);
57+
if (!res)
58+
res = todo_list_write_to_file(the_repository, &todo_list,
59+
todo_file, NULL, NULL, -1, 0);
60+
61+
todo_list_release(&todo_list);
62+
63+
if (res)
64+
return error_errno(_("could not write '%s'."), todo_file);
65+
return 0;
66+
}
67+
68+
static int transform_todo_file(unsigned flags)
69+
{
70+
const char *todo_file = rebase_path_todo();
71+
struct todo_list todo_list = TODO_LIST_INIT;
72+
int res;
73+
74+
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
75+
return error_errno(_("could not read '%s'."), todo_file);
76+
77+
if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
78+
&todo_list)) {
79+
todo_list_release(&todo_list);
80+
return error(_("unusable todo list: '%s'"), todo_file);
81+
}
82+
83+
res = todo_list_write_to_file(the_repository, &todo_list, todo_file,
84+
NULL, NULL, -1, flags);
85+
todo_list_release(&todo_list);
86+
87+
if (res)
88+
return error_errno(_("could not write '%s'."), todo_file);
89+
return 0;
90+
}
91+
92+
static int edit_todo_file(unsigned flags)
93+
{
94+
const char *todo_file = rebase_path_todo();
95+
struct todo_list todo_list = TODO_LIST_INIT,
96+
new_todo = TODO_LIST_INIT;
97+
int res = 0;
98+
99+
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
100+
return error_errno(_("could not read '%s'."), todo_file);
101+
102+
strbuf_stripspace(&todo_list.buf, 1);
103+
res = edit_todo_list(the_repository, &todo_list, &new_todo, NULL, NULL, flags);
104+
if (!res && todo_list_write_to_file(the_repository, &new_todo, todo_file,
105+
NULL, NULL, -1, flags & ~(TODO_LIST_SHORTEN_IDS)))
106+
res = error_errno(_("could not write '%s'"), todo_file);
107+
108+
todo_list_release(&todo_list);
109+
todo_list_release(&new_todo);
110+
111+
return res;
112+
}
113+
17114
static int get_revision_ranges(const char *upstream, const char *onto,
18115
const char **head_hash,
19116
char **revisions, char **shortrevisions)
@@ -66,13 +163,13 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
66163
const char *onto, const char *onto_name,
67164
const char *squash_onto, const char *head_name,
68165
const char *restrict_revision, char *raw_strategies,
69-
const char *cmd, unsigned autosquash)
166+
struct string_list *commands, unsigned autosquash)
70167
{
71168
int ret;
72169
const char *head_hash = NULL;
73170
char *revisions = NULL, *shortrevisions = NULL;
74171
struct argv_array make_script_args = ARGV_ARRAY_INIT;
75-
FILE *todo_list;
172+
struct todo_list todo_list = TODO_LIST_INIT;
76173

77174
if (prepare_branch_to_be_rebased(opts, switch_to))
78175
return -1;
@@ -94,34 +191,29 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
94191
if (!upstream && squash_onto)
95192
write_file(path_squash_onto(), "%s\n", squash_onto);
96193

97-
todo_list = fopen(rebase_path_todo(), "w");
98-
if (!todo_list) {
99-
free(revisions);
100-
free(shortrevisions);
101-
102-
return error_errno(_("could not open %s"), rebase_path_todo());
103-
}
104-
105194
argv_array_pushl(&make_script_args, "", revisions, NULL);
106195
if (restrict_revision)
107196
argv_array_push(&make_script_args, restrict_revision);
108197

109-
ret = sequencer_make_script(the_repository, todo_list,
198+
ret = sequencer_make_script(the_repository, &todo_list.buf,
110199
make_script_args.argc, make_script_args.argv,
111200
flags);
112-
fclose(todo_list);
113201

114202
if (ret)
115203
error(_("could not generate todo list"));
116204
else {
117205
discard_cache();
118-
ret = complete_action(the_repository, opts, flags,
119-
shortrevisions, onto_name, onto,
120-
head_hash, cmd, autosquash);
206+
if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
207+
&todo_list))
208+
BUG("unusable todo list");
209+
210+
ret = complete_action(the_repository, opts, flags, shortrevisions, onto_name,
211+
onto, head_hash, commands, autosquash, &todo_list);
121212
}
122213

123214
free(revisions);
124215
free(shortrevisions);
216+
todo_list_release(&todo_list);
125217
argv_array_clear(&make_script_args);
126218

127219
return ret;
@@ -140,6 +232,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
140232
const char *onto = NULL, *onto_name = NULL, *restrict_revision = NULL,
141233
*squash_onto = NULL, *upstream = NULL, *head_name = NULL,
142234
*switch_to = NULL, *cmd = NULL;
235+
struct string_list commands = STRING_LIST_INIT_DUP;
143236
char *raw_strategies = NULL;
144237
enum {
145238
NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH,
@@ -224,14 +317,22 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
224317
warning(_("--[no-]rebase-cousins has no effect without "
225318
"--rebase-merges"));
226319

320+
if (cmd && *cmd) {
321+
string_list_split(&commands, cmd, '\n', -1);
322+
323+
/* rebase.c adds a new line to cmd after every command,
324+
* so here the last command is always empty */
325+
string_list_remove_empty_items(&commands, 0);
326+
}
327+
227328
switch (command) {
228329
case NONE:
229330
if (!onto && !upstream)
230331
die(_("a base commit must be provided with --upstream or --onto"));
231332

232333
ret = do_interactive_rebase(&opts, flags, switch_to, upstream, onto,
233334
onto_name, squash_onto, head_name, restrict_revision,
234-
raw_strategies, cmd, autosquash);
335+
raw_strategies, &commands, autosquash);
235336
break;
236337
case SKIP: {
237338
struct string_list merge_rr = STRING_LIST_INIT_DUP;
@@ -243,7 +344,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
243344
break;
244345
}
245346
case EDIT_TODO:
246-
ret = edit_todo_list(the_repository, flags);
347+
ret = edit_todo_file(flags);
247348
break;
248349
case SHOW_CURRENT_PATCH: {
249350
struct child_process cmd = CHILD_PROCESS_INIT;
@@ -256,20 +357,21 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
256357
}
257358
case SHORTEN_OIDS:
258359
case EXPAND_OIDS:
259-
ret = transform_todos(the_repository, flags);
360+
ret = transform_todo_file(flags);
260361
break;
261362
case CHECK_TODO_LIST:
262-
ret = check_todo_list(the_repository);
363+
ret = check_todo_list_from_file(the_repository);
263364
break;
264365
case REARRANGE_SQUASH:
265-
ret = rearrange_squash(the_repository);
366+
ret = rearrange_squash_in_todo_file();
266367
break;
267368
case ADD_EXEC:
268-
ret = sequencer_add_exec_commands(the_repository, cmd);
369+
ret = add_exec_commands(&commands);
269370
break;
270371
default:
271372
BUG("invalid command '%d'", command);
272373
}
273374

375+
string_list_clear(&commands, 0);
274376
return !!ret;
275377
}

0 commit comments

Comments
 (0)