@@ -50,6 +50,73 @@ enum rebase_type {
50
50
REBASE_PRESERVE_MERGES
51
51
};
52
52
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
+
53
120
static int add_exec_commands (struct string_list * commands )
54
121
{
55
122
const char * todo_file = rebase_path_todo ();
@@ -265,32 +332,30 @@ static const char * const builtin_rebase_interactive_usage[] = {
265
332
266
333
int cmd_rebase__interactive (int argc , const char * * argv , const char * prefix )
267
334
{
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 ;
274
338
struct object_id squash_onto = null_oid ;
275
- struct object_id * squash_onto_opt = NULL ;
276
339
struct string_list commands = STRING_LIST_INIT_DUP ;
277
- char * raw_strategies = NULL ;
278
340
enum {
279
341
NONE = 0 , CONTINUE , SKIP , EDIT_TODO , SHOW_CURRENT_PATCH ,
280
342
SHORTEN_OIDS , EXPAND_OIDS , CHECK_TODO_LIST , REARRANGE_SQUASH , ADD_EXEC
281
343
} command = 0 ;
282
344
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" )),
285
348
OPT_BOOL (0 , "allow-empty-message" , & opts .allow_empty_message ,
286
349
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 ,
289
352
N_ ("keep original branch points of cousins" )),
290
- OPT_BOOL (0 , "autosquash" , & autosquash ,
353
+ OPT_BOOL (0 , "autosquash" , & opts . autosquash ,
291
354
N_ ("move commits that begin with squash!/fixup!" )),
292
355
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 ),
294
359
OPT_CMDMODE (0 , "continue" , & command , N_ ("continue rebase" ),
295
360
CONTINUE ),
296
361
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)
308
373
N_ ("rearrange fixup/squash lines" ), REARRANGE_SQUASH ),
309
374
OPT_CMDMODE (0 , "add-exec-commands" , & command ,
310
375
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" ),
312
377
PARSE_OPT_NONEG , parse_opt_commit , 0 },
313
- { OPTION_CALLBACK , 0 , "restrict-revision" , & restrict_revision ,
378
+ { OPTION_CALLBACK , 0 , "restrict-revision" , & opts . restrict_revision ,
314
379
N_ ("restrict-revision" ), N_ ("restrict revision" ),
315
380
PARSE_OPT_NONEG , parse_opt_commit , 0 },
316
381
{ OPTION_CALLBACK , 0 , "squash-onto" , & squash_onto , N_ ("squash-onto" ),
317
382
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" ),
319
384
N_ ("the upstream commit" ), PARSE_OPT_NONEG , parse_opt_commit ,
320
385
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" ),
323
388
N_ ("GPG-sign commits" ),
324
389
PARSE_OPT_OPTARG , NULL , (intptr_t ) "" },
325
390
OPT_STRING (0 , "strategy" , & opts .strategy , N_ ("strategy" ),
326
391
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" ),
328
393
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" ),
330
395
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 ),
334
399
OPT_BOOL (0 , "reschedule-failed-exec" , & opts .reschedule_failed_exec ,
335
400
N_ ("automatically re-schedule any `exec` that fails" )),
336
401
OPT_END ()
337
402
};
338
403
339
- sequencer_init_config (& opts );
340
- git_config_get_bool ("rebase.abbreviatecommands" , & abbreviate_commands );
404
+ opts .rebase_cousins = -1 ;
341
405
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 );
345
407
346
408
if (argc == 1 )
347
409
usage_with_options (builtin_rebase_interactive_usage , options );
348
410
349
411
argc = parse_options (argc , argv , NULL , options ,
350
412
builtin_rebase_interactive_usage , PARSE_OPT_KEEP_ARGV0 );
351
413
352
- opts .gpg_sign = xstrdup_or_null (opts .gpg_sign );
353
-
354
414
if (!is_null_oid (& squash_onto ))
355
- squash_onto_opt = & squash_onto ;
415
+ opts . squash_onto = & squash_onto ;
356
416
357
- flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0 ;
417
+ flags |= opts . keep_empty ? TODO_LIST_KEEP_EMPTY : 0 ;
358
418
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 ;
361
421
flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0 ;
362
422
363
- if (rebase_cousins >= 0 && !rebase_merges )
423
+ if (opts . rebase_cousins >= 0 && !opts . rebase_merges )
364
424
warning (_ ("--[no-]rebase-cousins has no effect without "
365
425
"--rebase-merges" ));
366
426
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 );
369
429
370
430
/* rebase.c adds a new line to cmd after every command,
371
431
* so here the last command is always empty */
372
432
string_list_remove_empty_items (& commands , 0 );
373
433
}
374
434
375
435
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 )
378
439
die (_ ("a base commit must be provided with --upstream or --onto" ));
379
440
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 );
383
444
break ;
445
+ }
384
446
case SKIP : {
385
447
struct string_list merge_rr = STRING_LIST_INIT_DUP ;
386
448
387
449
rerere_clear (the_repository , & merge_rr );
450
+ }
388
451
/* 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 );
391
456
break ;
392
457
}
393
458
case EDIT_TODO :
@@ -446,45 +511,6 @@ static int use_builtin_rebase(void)
446
511
return ret ;
447
512
}
448
513
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
-
488
514
static int is_interactive (struct rebase_options * opts )
489
515
{
490
516
return opts -> type == REBASE_INTERACTIVE ||
@@ -1380,13 +1406,7 @@ static int check_exec_cmd(const char *cmd)
1380
1406
1381
1407
int cmd_rebase (int argc , const char * * argv , const char * prefix )
1382
1408
{
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 ;
1390
1410
const char * branch_name ;
1391
1411
int ret , flags , total_argc , in_progress = 0 ;
1392
1412
int ok_to_skip_pre_rebase = 0 ;
@@ -1539,6 +1559,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1539
1559
trace_repo_setup (prefix );
1540
1560
setup_work_tree ();
1541
1561
1562
+ options .allow_empty_message = 1 ;
1542
1563
git_config (rebase_config , & options );
1543
1564
1544
1565
strbuf_reset (& buf );
0 commit comments