@@ -14,6 +14,103 @@ static GIT_PATH_FUNC(path_state_dir, "rebase-merge/")
14
14
static GIT_PATH_FUNC (path_squash_onto , "rebase-merge/squash-onto" )
15
15
static GIT_PATH_FUNC (path_interactive , "rebase-merge/interactive" )
16
16
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
+
17
114
static int get_revision_ranges (const char * upstream , const char * onto ,
18
115
const char * * head_hash ,
19
116
char * * revisions , char * * shortrevisions )
@@ -66,13 +163,13 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
66
163
const char * onto , const char * onto_name ,
67
164
const char * squash_onto , const char * head_name ,
68
165
const char * restrict_revision , char * raw_strategies ,
69
- const char * cmd , unsigned autosquash )
166
+ struct string_list * commands , unsigned autosquash )
70
167
{
71
168
int ret ;
72
169
const char * head_hash = NULL ;
73
170
char * revisions = NULL , * shortrevisions = NULL ;
74
171
struct argv_array make_script_args = ARGV_ARRAY_INIT ;
75
- FILE * todo_list ;
172
+ struct todo_list todo_list = TODO_LIST_INIT ;
76
173
77
174
if (prepare_branch_to_be_rebased (opts , switch_to ))
78
175
return -1 ;
@@ -94,34 +191,29 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
94
191
if (!upstream && squash_onto )
95
192
write_file (path_squash_onto (), "%s\n" , squash_onto );
96
193
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
-
105
194
argv_array_pushl (& make_script_args , "" , revisions , NULL );
106
195
if (restrict_revision )
107
196
argv_array_push (& make_script_args , restrict_revision );
108
197
109
- ret = sequencer_make_script (the_repository , todo_list ,
198
+ ret = sequencer_make_script (the_repository , & todo_list . buf ,
110
199
make_script_args .argc , make_script_args .argv ,
111
200
flags );
112
- fclose (todo_list );
113
201
114
202
if (ret )
115
203
error (_ ("could not generate todo list" ));
116
204
else {
117
205
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 );
121
212
}
122
213
123
214
free (revisions );
124
215
free (shortrevisions );
216
+ todo_list_release (& todo_list );
125
217
argv_array_clear (& make_script_args );
126
218
127
219
return ret ;
@@ -140,6 +232,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
140
232
const char * onto = NULL , * onto_name = NULL , * restrict_revision = NULL ,
141
233
* squash_onto = NULL , * upstream = NULL , * head_name = NULL ,
142
234
* switch_to = NULL , * cmd = NULL ;
235
+ struct string_list commands = STRING_LIST_INIT_DUP ;
143
236
char * raw_strategies = NULL ;
144
237
enum {
145
238
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)
224
317
warning (_ ("--[no-]rebase-cousins has no effect without "
225
318
"--rebase-merges" ));
226
319
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
+
227
328
switch (command ) {
228
329
case NONE :
229
330
if (!onto && !upstream )
230
331
die (_ ("a base commit must be provided with --upstream or --onto" ));
231
332
232
333
ret = do_interactive_rebase (& opts , flags , switch_to , upstream , onto ,
233
334
onto_name , squash_onto , head_name , restrict_revision ,
234
- raw_strategies , cmd , autosquash );
335
+ raw_strategies , & commands , autosquash );
235
336
break ;
236
337
case SKIP : {
237
338
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)
243
344
break ;
244
345
}
245
346
case EDIT_TODO :
246
- ret = edit_todo_list ( the_repository , flags );
347
+ ret = edit_todo_file ( flags );
247
348
break ;
248
349
case SHOW_CURRENT_PATCH : {
249
350
struct child_process cmd = CHILD_PROCESS_INIT ;
@@ -256,20 +357,21 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
256
357
}
257
358
case SHORTEN_OIDS :
258
359
case EXPAND_OIDS :
259
- ret = transform_todos ( the_repository , flags );
360
+ ret = transform_todo_file ( flags );
260
361
break ;
261
362
case CHECK_TODO_LIST :
262
- ret = check_todo_list (the_repository );
363
+ ret = check_todo_list_from_file (the_repository );
263
364
break ;
264
365
case REARRANGE_SQUASH :
265
- ret = rearrange_squash ( the_repository );
366
+ ret = rearrange_squash_in_todo_file ( );
266
367
break ;
267
368
case ADD_EXEC :
268
- ret = sequencer_add_exec_commands ( the_repository , cmd );
369
+ ret = add_exec_commands ( & commands );
269
370
break ;
270
371
default :
271
372
BUG ("invalid command '%d'" , command );
272
373
}
273
374
375
+ string_list_clear (& commands , 0 );
274
376
return !!ret ;
275
377
}
0 commit comments