@@ -91,6 +91,7 @@ struct rebase_options {
91
91
REBASE_INTERACTIVE_EXPLICIT = 1 <<4 ,
92
92
} flags ;
93
93
struct strbuf git_am_opt ;
94
+ const char * action ;
94
95
};
95
96
96
97
static int is_interactive (struct rebase_options * opts )
@@ -115,6 +116,62 @@ static const char *state_dir_path(const char *filename, struct rebase_options *o
115
116
return path .buf ;
116
117
}
117
118
119
+ /* Read one file, then strip line endings */
120
+ static int read_one (const char * path , struct strbuf * buf )
121
+ {
122
+ if (strbuf_read_file (buf , path , 0 ) < 0 )
123
+ return error_errno (_ ("could not read '%s'" ), path );
124
+ strbuf_trim_trailing_newline (buf );
125
+ return 0 ;
126
+ }
127
+
128
+ /* Initialize the rebase options from the state directory. */
129
+ static int read_basic_state (struct rebase_options * opts )
130
+ {
131
+ struct strbuf head_name = STRBUF_INIT ;
132
+ struct strbuf buf = STRBUF_INIT ;
133
+ struct object_id oid ;
134
+
135
+ if (read_one (state_dir_path ("head-name" , opts ), & head_name ) ||
136
+ read_one (state_dir_path ("onto" , opts ), & buf ))
137
+ return -1 ;
138
+ opts -> head_name = starts_with (head_name .buf , "refs/" ) ?
139
+ xstrdup (head_name .buf ) : NULL ;
140
+ strbuf_release (& head_name );
141
+ if (get_oid (buf .buf , & oid ))
142
+ return error (_ ("could not get 'onto': '%s'" ), buf .buf );
143
+ opts -> onto = lookup_commit_or_die (& oid , buf .buf );
144
+
145
+ /*
146
+ * We always write to orig-head, but interactive rebase used to write to
147
+ * head. Fall back to reading from head to cover for the case that the
148
+ * user upgraded git with an ongoing interactive rebase.
149
+ */
150
+ strbuf_reset (& buf );
151
+ if (file_exists (state_dir_path ("orig-head" , opts ))) {
152
+ if (read_one (state_dir_path ("orig-head" , opts ), & buf ))
153
+ return -1 ;
154
+ } else if (read_one (state_dir_path ("head" , opts ), & buf ))
155
+ return -1 ;
156
+ if (get_oid (buf .buf , & opts -> orig_head ))
157
+ return error (_ ("invalid orig-head: '%s'" ), buf .buf );
158
+
159
+ strbuf_reset (& buf );
160
+ if (read_one (state_dir_path ("quiet" , opts ), & buf ))
161
+ return -1 ;
162
+ if (buf .len )
163
+ opts -> flags &= ~REBASE_NO_QUIET ;
164
+ else
165
+ opts -> flags |= REBASE_NO_QUIET ;
166
+
167
+ if (file_exists (state_dir_path ("verbose" , opts )))
168
+ opts -> flags |= REBASE_VERBOSE ;
169
+
170
+ strbuf_release (& buf );
171
+
172
+ return 0 ;
173
+ }
174
+
118
175
static int finish_rebase (struct rebase_options * opts )
119
176
{
120
177
struct strbuf dir = STRBUF_INIT ;
@@ -168,12 +225,13 @@ static int run_specific_rebase(struct rebase_options *opts)
168
225
add_var (& script_snippet , "state_dir" , opts -> state_dir );
169
226
170
227
add_var (& script_snippet , "upstream_name" , opts -> upstream_name );
171
- add_var (& script_snippet , "upstream" ,
172
- oid_to_hex (& opts -> upstream -> object .oid ));
228
+ add_var (& script_snippet , "upstream" , opts -> upstream ?
229
+ oid_to_hex (& opts -> upstream -> object .oid ) : NULL );
173
230
add_var (& script_snippet , "head_name" ,
174
231
opts -> head_name ? opts -> head_name : "detached HEAD" );
175
232
add_var (& script_snippet , "orig_head" , oid_to_hex (& opts -> orig_head ));
176
- add_var (& script_snippet , "onto" , oid_to_hex (& opts -> onto -> object .oid ));
233
+ add_var (& script_snippet , "onto" , opts -> onto ?
234
+ oid_to_hex (& opts -> onto -> object .oid ) : NULL );
177
235
add_var (& script_snippet , "onto_name" , opts -> onto_name );
178
236
add_var (& script_snippet , "revisions" , opts -> revisions );
179
237
add_var (& script_snippet , "restrict_revision" , opts -> restrict_revision ?
@@ -189,6 +247,7 @@ static int run_specific_rebase(struct rebase_options *opts)
189
247
opts -> flags & REBASE_FORCE ? "t" : "" );
190
248
if (opts -> switch_to )
191
249
add_var (& script_snippet , "switch_to" , opts -> switch_to );
250
+ add_var (& script_snippet , "action" , opts -> action ? opts -> action : "" );
192
251
193
252
switch (opts -> type ) {
194
253
case REBASE_AM :
@@ -400,12 +459,16 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
400
459
.git_am_opt = STRBUF_INIT ,
401
460
};
402
461
const char * branch_name ;
403
- int ret , flags , in_progress = 0 ;
462
+ int ret , flags , total_argc , in_progress = 0 ;
404
463
int ok_to_skip_pre_rebase = 0 ;
405
464
struct strbuf msg = STRBUF_INIT ;
406
465
struct strbuf revisions = STRBUF_INIT ;
407
466
struct strbuf buf = STRBUF_INIT ;
408
467
struct object_id merge_base ;
468
+ enum {
469
+ NO_ACTION ,
470
+ ACTION_CONTINUE ,
471
+ } action = NO_ACTION ;
409
472
struct option builtin_rebase_options [] = {
410
473
OPT_STRING (0 , "onto" , & options .onto_name ,
411
474
N_ ("revision" ),
@@ -427,6 +490,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
427
490
OPT_BIT (0 , "no-ff" , & options .flags ,
428
491
N_ ("cherry-pick all commits, even if unchanged" ),
429
492
REBASE_FORCE ),
493
+ OPT_CMDMODE (0 , "continue" , & action , N_ ("continue" ),
494
+ ACTION_CONTINUE ),
430
495
OPT_END (),
431
496
};
432
497
@@ -480,14 +545,55 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
480
545
if (options .type != REBASE_UNSPECIFIED )
481
546
in_progress = 1 ;
482
547
548
+ total_argc = argc ;
483
549
argc = parse_options (argc , argv , prefix ,
484
550
builtin_rebase_options ,
485
551
builtin_rebase_usage , 0 );
486
552
553
+ if (action != NO_ACTION && total_argc != 2 ) {
554
+ usage_with_options (builtin_rebase_usage ,
555
+ builtin_rebase_options );
556
+ }
557
+
487
558
if (argc > 2 )
488
559
usage_with_options (builtin_rebase_usage ,
489
560
builtin_rebase_options );
490
561
562
+ switch (action ) {
563
+ case ACTION_CONTINUE : {
564
+ struct object_id head ;
565
+ struct lock_file lock_file = LOCK_INIT ;
566
+ int fd ;
567
+
568
+ options .action = "continue" ;
569
+
570
+ /* Sanity check */
571
+ if (get_oid ("HEAD" , & head ))
572
+ die (_ ("Cannot read HEAD" ));
573
+
574
+ fd = hold_locked_index (& lock_file , 0 );
575
+ if (read_index (the_repository -> index ) < 0 )
576
+ die (_ ("could not read index" ));
577
+ refresh_index (the_repository -> index , REFRESH_QUIET , NULL , NULL ,
578
+ NULL );
579
+ if (0 <= fd )
580
+ update_index_if_able (the_repository -> index ,
581
+ & lock_file );
582
+ rollback_lock_file (& lock_file );
583
+
584
+ if (has_unstaged_changes (1 )) {
585
+ puts (_ ("You must edit all merge conflicts and then\n"
586
+ "mark them as resolved using git add" ));
587
+ exit (1 );
588
+ }
589
+ if (read_basic_state (& options ))
590
+ exit (1 );
591
+ goto run_rebase ;
592
+ }
593
+ default :
594
+ die ("TODO" );
595
+ }
596
+
491
597
/* Make sure no rebase is in progress */
492
598
if (in_progress ) {
493
599
const char * last_slash = strrchr (options .state_dir , '/' );
@@ -719,6 +825,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
719
825
720
826
options .revisions = revisions .buf ;
721
827
828
+ run_rebase :
722
829
ret = !!run_specific_rebase (& options );
723
830
724
831
cleanup :
0 commit comments