@@ -50,6 +50,73 @@ enum rebase_type {
5050 REBASE_PRESERVE_MERGES
5151};
5252
53+ struct rebase_options {
54+ enum rebase_type type ;
55+ const char * state_dir ;
56+ struct commit * upstream ;
57+ const char * upstream_name ;
58+ const char * upstream_arg ;
59+ char * head_name ;
60+ struct object_id orig_head ;
61+ struct commit * onto ;
62+ const char * onto_name ;
63+ const char * revisions ;
64+ const char * switch_to ;
65+ int root ;
66+ struct object_id * squash_onto ;
67+ struct commit * restrict_revision ;
68+ int dont_finish_rebase ;
69+ enum {
70+ REBASE_NO_QUIET = 1 <<0 ,
71+ REBASE_VERBOSE = 1 <<1 ,
72+ REBASE_DIFFSTAT = 1 <<2 ,
73+ REBASE_FORCE = 1 <<3 ,
74+ REBASE_INTERACTIVE_EXPLICIT = 1 <<4 ,
75+ } flags ;
76+ struct argv_array git_am_opts ;
77+ const char * action ;
78+ int signoff ;
79+ int allow_rerere_autoupdate ;
80+ int keep_empty ;
81+ int autosquash ;
82+ char * gpg_sign_opt ;
83+ int autostash ;
84+ char * cmd ;
85+ int allow_empty_message ;
86+ int rebase_merges , rebase_cousins ;
87+ char * strategy , * strategy_opts ;
88+ struct strbuf git_format_patch_opt ;
89+ int reschedule_failed_exec ;
90+ };
91+
92+ #define REBASE_OPTIONS_INIT { \
93+ .type = REBASE_UNSPECIFIED, \
94+ .flags = REBASE_NO_QUIET, \
95+ .git_am_opts = ARGV_ARRAY_INIT, \
96+ .git_format_patch_opt = STRBUF_INIT \
97+ }
98+
99+ static struct replay_opts get_replay_opts (const struct rebase_options * opts )
100+ {
101+ struct replay_opts replay = REPLAY_OPTS_INIT ;
102+
103+ replay .action = REPLAY_INTERACTIVE_REBASE ;
104+ sequencer_init_config (& replay );
105+
106+ replay .signoff = opts -> signoff ;
107+ replay .allow_ff = !(opts -> flags & REBASE_FORCE );
108+ if (opts -> allow_rerere_autoupdate )
109+ replay .allow_rerere_auto = opts -> allow_rerere_autoupdate ;
110+ replay .allow_empty = 1 ;
111+ replay .allow_empty_message = opts -> allow_empty_message ;
112+ replay .verbose = opts -> flags & REBASE_VERBOSE ;
113+ replay .reschedule_failed_exec = opts -> reschedule_failed_exec ;
114+ replay .gpg_sign = xstrdup_or_null (opts -> gpg_sign_opt );
115+ replay .strategy = opts -> strategy ;
116+
117+ return replay ;
118+ }
119+
53120static int add_exec_commands (struct string_list * commands )
54121{
55122 const char * todo_file = rebase_path_todo ();
@@ -265,32 +332,30 @@ static const char * const builtin_rebase_interactive_usage[] = {
265332
266333int cmd_rebase__interactive (int argc , const char * * argv , const char * prefix )
267334{
268- struct replay_opts opts = REPLAY_OPTS_INIT ;
269- unsigned flags = 0 , keep_empty = 0 , rebase_merges = 0 , autosquash = 0 ;
270- int abbreviate_commands = 0 , rebase_cousins = -1 , ret = 0 ;
271- const char * onto_name = NULL , * head_name = NULL , * switch_to = NULL ,
272- * cmd = NULL ;
273- struct commit * onto = NULL , * upstream = NULL , * restrict_revision = NULL ;
335+ struct rebase_options opts = REBASE_OPTIONS_INIT ;
336+ unsigned flags = 0 ;
337+ int abbreviate_commands = 0 , ret = 0 ;
274338 struct object_id squash_onto = null_oid ;
275- struct object_id * squash_onto_opt = NULL ;
276339 struct string_list commands = STRING_LIST_INIT_DUP ;
277- char * raw_strategies = NULL ;
278340 enum {
279341 NONE = 0 , CONTINUE , SKIP , EDIT_TODO , SHOW_CURRENT_PATCH ,
280342 SHORTEN_OIDS , EXPAND_OIDS , CHECK_TODO_LIST , REARRANGE_SQUASH , ADD_EXEC
281343 } command = 0 ;
282344 struct option options [] = {
283- OPT_BOOL (0 , "ff" , & opts .allow_ff , N_ ("allow fast-forward" )),
284- OPT_BOOL (0 , "keep-empty" , & keep_empty , N_ ("keep empty commits" )),
345+ OPT_NEGBIT (0 , "ff" , & opts .flags , N_ ("allow fast-forward" ),
346+ REBASE_FORCE ),
347+ OPT_BOOL (0 , "keep-empty" , & opts .keep_empty , N_ ("keep empty commits" )),
285348 OPT_BOOL (0 , "allow-empty-message" , & opts .allow_empty_message ,
286349 N_ ("allow commits with empty messages" )),
287- OPT_BOOL (0 , "rebase-merges" , & rebase_merges , N_ ("rebase merge commits" )),
288- OPT_BOOL (0 , "rebase-cousins" , & rebase_cousins ,
350+ OPT_BOOL (0 , "rebase-merges" , & opts . rebase_merges , N_ ("rebase merge commits" )),
351+ OPT_BOOL (0 , "rebase-cousins" , & opts . rebase_cousins ,
289352 N_ ("keep original branch points of cousins" )),
290- OPT_BOOL (0 , "autosquash" , & autosquash ,
353+ OPT_BOOL (0 , "autosquash" , & opts . autosquash ,
291354 N_ ("move commits that begin with squash!/fixup!" )),
292355 OPT_BOOL (0 , "signoff" , & opts .signoff , N_ ("sign commits" )),
293- OPT__VERBOSE (& opts .verbose , N_ ("be verbose" )),
356+ OPT_BIT ('v' , "verbose" , & opts .flags ,
357+ N_ ("display a diffstat of what changed upstream" ),
358+ REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT ),
294359 OPT_CMDMODE (0 , "continue" , & command , N_ ("continue rebase" ),
295360 CONTINUE ),
296361 OPT_CMDMODE (0 , "skip" , & command , N_ ("skip commit" ), SKIP ),
@@ -308,86 +373,86 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
308373 N_ ("rearrange fixup/squash lines" ), REARRANGE_SQUASH ),
309374 OPT_CMDMODE (0 , "add-exec-commands" , & command ,
310375 N_ ("insert exec commands in todo list" ), ADD_EXEC ),
311- { OPTION_CALLBACK , 0 , "onto" , & onto , N_ ("onto" ), N_ ("onto" ),
376+ { OPTION_CALLBACK , 0 , "onto" , & opts . onto , N_ ("onto" ), N_ ("onto" ),
312377 PARSE_OPT_NONEG , parse_opt_commit , 0 },
313- { OPTION_CALLBACK , 0 , "restrict-revision" , & restrict_revision ,
378+ { OPTION_CALLBACK , 0 , "restrict-revision" , & opts . restrict_revision ,
314379 N_ ("restrict-revision" ), N_ ("restrict revision" ),
315380 PARSE_OPT_NONEG , parse_opt_commit , 0 },
316381 { OPTION_CALLBACK , 0 , "squash-onto" , & squash_onto , N_ ("squash-onto" ),
317382 N_ ("squash onto" ), PARSE_OPT_NONEG , parse_opt_object_id , 0 },
318- { OPTION_CALLBACK , 0 , "upstream" , & upstream , N_ ("upstream" ),
383+ { OPTION_CALLBACK , 0 , "upstream" , & opts . upstream , N_ ("upstream" ),
319384 N_ ("the upstream commit" ), PARSE_OPT_NONEG , parse_opt_commit ,
320385 0 },
321- OPT_STRING (0 , "head-name" , & head_name , N_ ("head-name" ), N_ ("head name" )),
322- { OPTION_STRING , 'S' , "gpg-sign" , & opts .gpg_sign , N_ ("key-id" ),
386+ OPT_STRING (0 , "head-name" , & opts . head_name , N_ ("head-name" ), N_ ("head name" )),
387+ { OPTION_STRING , 'S' , "gpg-sign" , & opts .gpg_sign_opt , N_ ("key-id" ),
323388 N_ ("GPG-sign commits" ),
324389 PARSE_OPT_OPTARG , NULL , (intptr_t ) "" },
325390 OPT_STRING (0 , "strategy" , & opts .strategy , N_ ("strategy" ),
326391 N_ ("rebase strategy" )),
327- OPT_STRING (0 , "strategy-opts" , & raw_strategies , N_ ("strategy-opts" ),
392+ OPT_STRING (0 , "strategy-opts" , & opts . strategy_opts , N_ ("strategy-opts" ),
328393 N_ ("strategy options" )),
329- OPT_STRING (0 , "switch-to" , & switch_to , N_ ("switch-to" ),
394+ OPT_STRING (0 , "switch-to" , & opts . switch_to , N_ ("switch-to" ),
330395 N_ ("the branch or commit to checkout" )),
331- OPT_STRING (0 , "onto-name" , & onto_name , N_ ("onto-name" ), N_ ("onto name" )),
332- OPT_STRING (0 , "cmd" , & cmd , N_ ("cmd" ), N_ ("the command to run" )),
333- OPT_RERERE_AUTOUPDATE (& opts .allow_rerere_auto ),
396+ OPT_STRING (0 , "onto-name" , & opts . onto_name , N_ ("onto-name" ), N_ ("onto name" )),
397+ OPT_STRING (0 , "cmd" , & opts . cmd , N_ ("cmd" ), N_ ("the command to run" )),
398+ OPT_RERERE_AUTOUPDATE (& opts .allow_rerere_autoupdate ),
334399 OPT_BOOL (0 , "reschedule-failed-exec" , & opts .reschedule_failed_exec ,
335400 N_ ("automatically re-schedule any `exec` that fails" )),
336401 OPT_END ()
337402 };
338403
339- sequencer_init_config (& opts );
340- git_config_get_bool ("rebase.abbreviatecommands" , & abbreviate_commands );
404+ opts .rebase_cousins = -1 ;
341405
342- opts .action = REPLAY_INTERACTIVE_REBASE ;
343- opts .allow_ff = 1 ;
344- opts .allow_empty = 1 ;
406+ git_config_get_bool ("rebase.abbreviatecommands" , & abbreviate_commands );
345407
346408 if (argc == 1 )
347409 usage_with_options (builtin_rebase_interactive_usage , options );
348410
349411 argc = parse_options (argc , argv , NULL , options ,
350412 builtin_rebase_interactive_usage , PARSE_OPT_KEEP_ARGV0 );
351413
352- opts .gpg_sign = xstrdup_or_null (opts .gpg_sign );
353-
354414 if (!is_null_oid (& squash_onto ))
355- squash_onto_opt = & squash_onto ;
415+ opts . squash_onto = & squash_onto ;
356416
357- flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0 ;
417+ flags |= opts . keep_empty ? TODO_LIST_KEEP_EMPTY : 0 ;
358418 flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0 ;
359- flags |= rebase_merges ? TODO_LIST_REBASE_MERGES : 0 ;
360- flags |= rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0 ;
419+ flags |= opts . rebase_merges ? TODO_LIST_REBASE_MERGES : 0 ;
420+ flags |= opts . rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0 ;
361421 flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0 ;
362422
363- if (rebase_cousins >= 0 && !rebase_merges )
423+ if (opts . rebase_cousins >= 0 && !opts . rebase_merges )
364424 warning (_ ("--[no-]rebase-cousins has no effect without "
365425 "--rebase-merges" ));
366426
367- if (cmd && * cmd ) {
368- string_list_split (& commands , cmd , '\n' , -1 );
427+ if (opts . cmd && * opts . cmd ) {
428+ string_list_split (& commands , opts . cmd , '\n' , -1 );
369429
370430 /* rebase.c adds a new line to cmd after every command,
371431 * so here the last command is always empty */
372432 string_list_remove_empty_items (& commands , 0 );
373433 }
374434
375435 switch (command ) {
376- case NONE :
377- if (!onto && !upstream )
436+ case NONE : {
437+ struct replay_opts replay_opts = get_replay_opts (& opts );
438+ if (!opts .onto && !opts .upstream )
378439 die (_ ("a base commit must be provided with --upstream or --onto" ));
379440
380- ret = do_interactive_rebase (& opts , flags , switch_to , upstream , onto ,
381- onto_name , squash_onto_opt , head_name , restrict_revision ,
382- raw_strategies , & commands , autosquash );
441+ ret = do_interactive_rebase (& replay_opts , flags , opts . switch_to , opts . upstream , opts . onto ,
442+ opts . onto_name , opts . squash_onto , opts . head_name , opts . restrict_revision ,
443+ opts . strategy_opts , & commands , opts . autosquash );
383444 break ;
445+ }
384446 case SKIP : {
385447 struct string_list merge_rr = STRING_LIST_INIT_DUP ;
386448
387449 rerere_clear (the_repository , & merge_rr );
450+ }
388451 /* fallthrough */
389- case CONTINUE :
390- ret = sequencer_continue (the_repository , & opts );
452+ case CONTINUE : {
453+ struct replay_opts replay_opts = get_replay_opts (& opts );
454+
455+ ret = sequencer_continue (the_repository , & replay_opts );
391456 break ;
392457 }
393458 case EDIT_TODO :
@@ -446,45 +511,6 @@ static int use_builtin_rebase(void)
446511 return ret ;
447512}
448513
449- struct rebase_options {
450- enum rebase_type type ;
451- const char * state_dir ;
452- struct commit * upstream ;
453- const char * upstream_name ;
454- const char * upstream_arg ;
455- char * head_name ;
456- struct object_id orig_head ;
457- struct commit * onto ;
458- const char * onto_name ;
459- const char * revisions ;
460- const char * switch_to ;
461- int root ;
462- struct object_id * squash_onto ;
463- struct commit * restrict_revision ;
464- int dont_finish_rebase ;
465- enum {
466- REBASE_NO_QUIET = 1 <<0 ,
467- REBASE_VERBOSE = 1 <<1 ,
468- REBASE_DIFFSTAT = 1 <<2 ,
469- REBASE_FORCE = 1 <<3 ,
470- REBASE_INTERACTIVE_EXPLICIT = 1 <<4 ,
471- } flags ;
472- struct argv_array git_am_opts ;
473- const char * action ;
474- int signoff ;
475- int allow_rerere_autoupdate ;
476- int keep_empty ;
477- int autosquash ;
478- char * gpg_sign_opt ;
479- int autostash ;
480- char * cmd ;
481- int allow_empty_message ;
482- int rebase_merges , rebase_cousins ;
483- char * strategy , * strategy_opts ;
484- struct strbuf git_format_patch_opt ;
485- int reschedule_failed_exec ;
486- };
487-
488514static int is_interactive (struct rebase_options * opts )
489515{
490516 return opts -> type == REBASE_INTERACTIVE ||
@@ -1380,13 +1406,7 @@ static int check_exec_cmd(const char *cmd)
13801406
13811407int cmd_rebase (int argc , const char * * argv , const char * prefix )
13821408{
1383- struct rebase_options options = {
1384- .type = REBASE_UNSPECIFIED ,
1385- .flags = REBASE_NO_QUIET ,
1386- .git_am_opts = ARGV_ARRAY_INIT ,
1387- .allow_empty_message = 1 ,
1388- .git_format_patch_opt = STRBUF_INIT ,
1389- };
1409+ struct rebase_options options = REBASE_OPTIONS_INIT ;
13901410 const char * branch_name ;
13911411 int ret , flags , total_argc , in_progress = 0 ;
13921412 int ok_to_skip_pre_rebase = 0 ;
@@ -1539,6 +1559,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
15391559 trace_repo_setup (prefix );
15401560 setup_work_tree ();
15411561
1562+ options .allow_empty_message = 1 ;
15421563 git_config (rebase_config , & options );
15431564
15441565 strbuf_reset (& buf );
0 commit comments