@@ -241,6 +241,37 @@ static int read_basic_state(struct rebase_options *opts)
241
241
return 0 ;
242
242
}
243
243
244
+ static int write_basic_state (struct rebase_options * opts )
245
+ {
246
+ write_file (state_dir_path ("head-name" , opts ), "%s" ,
247
+ opts -> head_name ? opts -> head_name : "detached HEAD" );
248
+ write_file (state_dir_path ("onto" , opts ), "%s" ,
249
+ opts -> onto ? oid_to_hex (& opts -> onto -> object .oid ) : "" );
250
+ write_file (state_dir_path ("orig-head" , opts ), "%s" ,
251
+ oid_to_hex (& opts -> orig_head ));
252
+ write_file (state_dir_path ("quiet" , opts ), "%s" ,
253
+ opts -> flags & REBASE_NO_QUIET ? "" : "t" );
254
+ if (opts -> flags & REBASE_VERBOSE )
255
+ write_file (state_dir_path ("verbose" , opts ), "" );
256
+ if (opts -> strategy )
257
+ write_file (state_dir_path ("strategy" , opts ), "%s" ,
258
+ opts -> strategy );
259
+ if (opts -> strategy_opts )
260
+ write_file (state_dir_path ("strategy_opts" , opts ), "%s" ,
261
+ opts -> strategy_opts );
262
+ if (opts -> allow_rerere_autoupdate >= 0 )
263
+ write_file (state_dir_path ("allow_rerere_autoupdate" , opts ),
264
+ "-%s-rerere-autoupdate" ,
265
+ opts -> allow_rerere_autoupdate ? "" : "-no" );
266
+ if (opts -> gpg_sign_opt )
267
+ write_file (state_dir_path ("gpg_sign_opt" , opts ), "%s" ,
268
+ opts -> gpg_sign_opt );
269
+ if (opts -> signoff )
270
+ write_file (state_dir_path ("strategy" , opts ), "--signoff" );
271
+
272
+ return 0 ;
273
+ }
274
+
244
275
static int apply_autostash (struct rebase_options * opts )
245
276
{
246
277
const char * path = state_dir_path ("autostash" , opts );
@@ -333,6 +364,144 @@ N_("Resolve all conflicts manually, mark them as resolved with\n"
333
364
"To abort and get back to the state before \"git rebase\", run "
334
365
"\"git rebase --abort\"." );
335
366
367
+ static int reset_head (struct object_id * oid , const char * action ,
368
+ const char * switch_to_branch , int detach_head ,
369
+ const char * reflog_orig_head , const char * reflog_head );
370
+
371
+ static int move_to_original_branch (struct rebase_options * opts )
372
+ {
373
+ struct strbuf buf = STRBUF_INIT ;
374
+ int ret ;
375
+
376
+ if (opts -> head_name && opts -> onto )
377
+ strbuf_addf (& buf , "rebase finished: %s onto %s" ,
378
+ opts -> head_name ,
379
+ oid_to_hex (& opts -> onto -> object .oid ));
380
+ ret = reset_head (NULL , "checkout" , opts -> head_name , 0 ,
381
+ "HEAD" , buf .buf );
382
+
383
+ strbuf_release (& buf );
384
+ return ret ;
385
+ }
386
+
387
+ static int run_am (struct rebase_options * opts )
388
+ {
389
+ struct child_process am = CHILD_PROCESS_INIT ;
390
+ struct child_process format_patch = CHILD_PROCESS_INIT ;
391
+ struct strbuf revisions = STRBUF_INIT ;
392
+ int status ;
393
+ char * rebased_patches ;
394
+
395
+ am .git_cmd = 1 ;
396
+ argv_array_push (& am .args , "am" );
397
+
398
+ if (opts -> action && !strcmp ("continue" , opts -> action )) {
399
+ argv_array_push (& am .args , "--resolved" );
400
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
401
+ if (opts -> gpg_sign_opt )
402
+ argv_array_push (& am .args , opts -> gpg_sign_opt );
403
+ status = run_command (& am );
404
+ if (status )
405
+ return status ;
406
+
407
+ return move_to_original_branch (opts );
408
+ }
409
+ if (opts -> action && !strcmp ("skip" , opts -> action )) {
410
+ argv_array_push (& am .args , "--skip" );
411
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
412
+ status = run_command (& am );
413
+ if (status )
414
+ return status ;
415
+
416
+ return move_to_original_branch (opts );
417
+ }
418
+ if (opts -> action && !strcmp ("show-current-patch" , opts -> action )) {
419
+ argv_array_push (& am .args , "--show-current-patch" );
420
+ return run_command (& am );
421
+ }
422
+
423
+ strbuf_addf (& revisions , "%s...%s" ,
424
+ oid_to_hex (opts -> root ?
425
+ /* this is now equivalent to ! -z "$upstream" */
426
+ & opts -> onto -> object .oid :
427
+ & opts -> upstream -> object .oid ),
428
+ oid_to_hex (& opts -> orig_head ));
429
+
430
+ rebased_patches = xstrdup (git_path ("rebased-patches" ));
431
+ format_patch .out = open (rebased_patches , O_WRONLY | O_CREAT , 0666 );
432
+ if (format_patch .out < 0 ) {
433
+ status = error_errno (_ ("could not write '%s'" ),
434
+ rebased_patches );
435
+ free (rebased_patches );
436
+ argv_array_clear (& am .args );
437
+ return status ;
438
+ }
439
+
440
+ format_patch .git_cmd = 1 ;
441
+ argv_array_pushl (& format_patch .args , "format-patch" , "-k" , "--stdout" ,
442
+ "--full-index" , "--cherry-pick" , "--right-only" ,
443
+ "--src-prefix=a/" , "--dst-prefix=b/" , "--no-renames" ,
444
+ "--no-cover-letter" , "--pretty=mboxrd" , NULL );
445
+ if (opts -> git_format_patch_opt .len )
446
+ argv_array_split (& format_patch .args ,
447
+ opts -> git_format_patch_opt .buf );
448
+ argv_array_push (& format_patch .args , revisions .buf );
449
+ if (opts -> restrict_revision )
450
+ argv_array_pushf (& format_patch .args , "^%s" ,
451
+ oid_to_hex (& opts -> restrict_revision -> object .oid ));
452
+
453
+ status = run_command (& format_patch );
454
+ if (status ) {
455
+ unlink (rebased_patches );
456
+ free (rebased_patches );
457
+ argv_array_clear (& am .args );
458
+
459
+ reset_head (& opts -> orig_head , "checkout" , opts -> head_name , 0 ,
460
+ "HEAD" , NULL );
461
+ error (_ ("\ngit encountered an error while preparing the "
462
+ "patches to replay\n"
463
+ "these revisions:\n"
464
+ "\n %s\n\n"
465
+ "As a result, git cannot rebase them." ),
466
+ opts -> revisions );
467
+
468
+ strbuf_release (& revisions );
469
+ return status ;
470
+ }
471
+ strbuf_release (& revisions );
472
+
473
+ am .in = open (rebased_patches , O_RDONLY );
474
+ if (am .in < 0 ) {
475
+ status = error_errno (_ ("could not read '%s'" ),
476
+ rebased_patches );
477
+ free (rebased_patches );
478
+ argv_array_clear (& am .args );
479
+ return status ;
480
+ }
481
+
482
+ argv_array_split (& am .args , opts -> git_am_opt .buf );
483
+ argv_array_push (& am .args , "--rebasing" );
484
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
485
+ argv_array_push (& am .args , "--patch-format=mboxrd" );
486
+ if (opts -> allow_rerere_autoupdate > 0 )
487
+ argv_array_push (& am .args , "--rerere-autoupdate" );
488
+ else if (opts -> allow_rerere_autoupdate == 0 )
489
+ argv_array_push (& am .args , "--no-rerere-autoupdate" );
490
+ if (opts -> gpg_sign_opt )
491
+ argv_array_push (& am .args , opts -> gpg_sign_opt );
492
+ status = run_command (& am );
493
+ unlink (rebased_patches );
494
+ free (rebased_patches );
495
+
496
+ if (!status )
497
+ return move_to_original_branch (opts );
498
+
499
+ if (is_directory (opts -> state_dir ))
500
+ write_basic_state (opts );
501
+
502
+ return status ;
503
+ }
504
+
336
505
static int run_specific_rebase (struct rebase_options * opts )
337
506
{
338
507
const char * argv [] = { NULL , NULL };
@@ -413,6 +582,11 @@ static int run_specific_rebase(struct rebase_options *opts)
413
582
goto finished_rebase ;
414
583
}
415
584
585
+ if (opts -> type == REBASE_AM ) {
586
+ status = run_am (opts );
587
+ goto finished_rebase ;
588
+ }
589
+
416
590
add_var (& script_snippet , "GIT_DIR" , absolute_path (get_git_dir ()));
417
591
add_var (& script_snippet , "state_dir" , opts -> state_dir );
418
592
0 commit comments