@@ -246,6 +246,37 @@ static int read_basic_state(struct rebase_options *opts)
246
246
return 0 ;
247
247
}
248
248
249
+ static int write_basic_state (struct rebase_options * opts )
250
+ {
251
+ write_file (state_dir_path ("head-name" , opts ), "%s" ,
252
+ opts -> head_name ? opts -> head_name : "detached HEAD" );
253
+ write_file (state_dir_path ("onto" , opts ), "%s" ,
254
+ opts -> onto ? oid_to_hex (& opts -> onto -> object .oid ) : "" );
255
+ write_file (state_dir_path ("orig-head" , opts ), "%s" ,
256
+ oid_to_hex (& opts -> orig_head ));
257
+ write_file (state_dir_path ("quiet" , opts ), "%s" ,
258
+ opts -> flags & REBASE_NO_QUIET ? "" : "t" );
259
+ if (opts -> flags & REBASE_VERBOSE )
260
+ write_file (state_dir_path ("verbose" , opts ), "%s" , "" );
261
+ if (opts -> strategy )
262
+ write_file (state_dir_path ("strategy" , opts ), "%s" ,
263
+ opts -> strategy );
264
+ if (opts -> strategy_opts )
265
+ write_file (state_dir_path ("strategy_opts" , opts ), "%s" ,
266
+ opts -> strategy_opts );
267
+ if (opts -> allow_rerere_autoupdate >= 0 )
268
+ write_file (state_dir_path ("allow_rerere_autoupdate" , opts ),
269
+ "-%s-rerere-autoupdate" ,
270
+ opts -> allow_rerere_autoupdate ? "" : "-no" );
271
+ if (opts -> gpg_sign_opt )
272
+ write_file (state_dir_path ("gpg_sign_opt" , opts ), "%s" ,
273
+ opts -> gpg_sign_opt );
274
+ if (opts -> signoff )
275
+ write_file (state_dir_path ("strategy" , opts ), "--signoff" );
276
+
277
+ return 0 ;
278
+ }
279
+
249
280
static int apply_autostash (struct rebase_options * opts )
250
281
{
251
282
const char * path = state_dir_path ("autostash" , opts );
@@ -453,13 +484,160 @@ static int reset_head(struct object_id *oid, const char *action,
453
484
return ret ;
454
485
}
455
486
487
+ static int move_to_original_branch (struct rebase_options * opts )
488
+ {
489
+ struct strbuf orig_head_reflog = STRBUF_INIT , head_reflog = STRBUF_INIT ;
490
+ int ret ;
491
+
492
+ if (!opts -> head_name )
493
+ return 0 ; /* nothing to move back to */
494
+
495
+ if (!opts -> onto )
496
+ BUG ("move_to_original_branch without onto" );
497
+
498
+ strbuf_addf (& orig_head_reflog , "rebase finished: %s onto %s" ,
499
+ opts -> head_name , oid_to_hex (& opts -> onto -> object .oid ));
500
+ strbuf_addf (& head_reflog , "rebase finished: returning to %s" ,
501
+ opts -> head_name );
502
+ ret = reset_head (NULL , "checkout" , opts -> head_name ,
503
+ RESET_HEAD_REFS_ONLY ,
504
+ orig_head_reflog .buf , head_reflog .buf );
505
+
506
+ strbuf_release (& orig_head_reflog );
507
+ strbuf_release (& head_reflog );
508
+ return ret ;
509
+ }
510
+
456
511
static const char * resolvemsg =
457
512
N_ ("Resolve all conflicts manually, mark them as resolved with\n"
458
513
"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
459
514
"You can instead skip this commit: run \"git rebase --skip\".\n"
460
515
"To abort and get back to the state before \"git rebase\", run "
461
516
"\"git rebase --abort\"." );
462
517
518
+ static int run_am (struct rebase_options * opts )
519
+ {
520
+ struct child_process am = CHILD_PROCESS_INIT ;
521
+ struct child_process format_patch = CHILD_PROCESS_INIT ;
522
+ struct strbuf revisions = STRBUF_INIT ;
523
+ int status ;
524
+ char * rebased_patches ;
525
+
526
+ am .git_cmd = 1 ;
527
+ argv_array_push (& am .args , "am" );
528
+
529
+ if (opts -> action && !strcmp ("continue" , opts -> action )) {
530
+ argv_array_push (& am .args , "--resolved" );
531
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
532
+ if (opts -> gpg_sign_opt )
533
+ argv_array_push (& am .args , opts -> gpg_sign_opt );
534
+ status = run_command (& am );
535
+ if (status )
536
+ return status ;
537
+
538
+ discard_cache ();
539
+ return move_to_original_branch (opts );
540
+ }
541
+ if (opts -> action && !strcmp ("skip" , opts -> action )) {
542
+ argv_array_push (& am .args , "--skip" );
543
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
544
+ status = run_command (& am );
545
+ if (status )
546
+ return status ;
547
+
548
+ discard_cache ();
549
+ return move_to_original_branch (opts );
550
+ }
551
+ if (opts -> action && !strcmp ("show-current-patch" , opts -> action )) {
552
+ argv_array_push (& am .args , "--show-current-patch" );
553
+ return run_command (& am );
554
+ }
555
+
556
+ strbuf_addf (& revisions , "%s...%s" ,
557
+ oid_to_hex (opts -> root ?
558
+ /* this is now equivalent to ! -z "$upstream" */
559
+ & opts -> onto -> object .oid :
560
+ & opts -> upstream -> object .oid ),
561
+ oid_to_hex (& opts -> orig_head ));
562
+
563
+ rebased_patches = xstrdup (git_path ("rebased-patches" ));
564
+ format_patch .out = open (rebased_patches ,
565
+ O_WRONLY | O_CREAT | O_TRUNC , 0666 );
566
+ if (format_patch .out < 0 ) {
567
+ status = error_errno (_ ("could not write '%s'" ),
568
+ rebased_patches );
569
+ free (rebased_patches );
570
+ argv_array_clear (& am .args );
571
+ return status ;
572
+ }
573
+
574
+ format_patch .git_cmd = 1 ;
575
+ argv_array_pushl (& format_patch .args , "format-patch" , "-k" , "--stdout" ,
576
+ "--full-index" , "--cherry-pick" , "--right-only" ,
577
+ "--src-prefix=a/" , "--dst-prefix=b/" , "--no-renames" ,
578
+ "--no-cover-letter" , "--pretty=mboxrd" , NULL );
579
+ if (opts -> git_format_patch_opt .len )
580
+ argv_array_split (& format_patch .args ,
581
+ opts -> git_format_patch_opt .buf );
582
+ argv_array_push (& format_patch .args , revisions .buf );
583
+ if (opts -> restrict_revision )
584
+ argv_array_pushf (& format_patch .args , "^%s" ,
585
+ oid_to_hex (& opts -> restrict_revision -> object .oid ));
586
+
587
+ status = run_command (& format_patch );
588
+ if (status ) {
589
+ unlink (rebased_patches );
590
+ free (rebased_patches );
591
+ argv_array_clear (& am .args );
592
+
593
+ reset_head (& opts -> orig_head , "checkout" , opts -> head_name , 0 ,
594
+ "HEAD" , NULL );
595
+ error (_ ("\ngit encountered an error while preparing the "
596
+ "patches to replay\n"
597
+ "these revisions:\n"
598
+ "\n %s\n\n"
599
+ "As a result, git cannot rebase them." ),
600
+ opts -> revisions );
601
+
602
+ strbuf_release (& revisions );
603
+ return status ;
604
+ }
605
+ strbuf_release (& revisions );
606
+
607
+ am .in = open (rebased_patches , O_RDONLY );
608
+ if (am .in < 0 ) {
609
+ status = error_errno (_ ("could not read '%s'" ),
610
+ rebased_patches );
611
+ free (rebased_patches );
612
+ argv_array_clear (& am .args );
613
+ return status ;
614
+ }
615
+
616
+ argv_array_pushv (& am .args , opts -> git_am_opts .argv );
617
+ argv_array_push (& am .args , "--rebasing" );
618
+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
619
+ argv_array_push (& am .args , "--patch-format=mboxrd" );
620
+ if (opts -> allow_rerere_autoupdate > 0 )
621
+ argv_array_push (& am .args , "--rerere-autoupdate" );
622
+ else if (opts -> allow_rerere_autoupdate == 0 )
623
+ argv_array_push (& am .args , "--no-rerere-autoupdate" );
624
+ if (opts -> gpg_sign_opt )
625
+ argv_array_push (& am .args , opts -> gpg_sign_opt );
626
+ status = run_command (& am );
627
+ unlink (rebased_patches );
628
+ free (rebased_patches );
629
+
630
+ if (!status ) {
631
+ discard_cache ();
632
+ return move_to_original_branch (opts );
633
+ }
634
+
635
+ if (is_directory (opts -> state_dir ))
636
+ write_basic_state (opts );
637
+
638
+ return status ;
639
+ }
640
+
463
641
static int run_specific_rebase (struct rebase_options * opts )
464
642
{
465
643
const char * argv [] = { NULL , NULL };
@@ -540,6 +718,11 @@ static int run_specific_rebase(struct rebase_options *opts)
540
718
goto finished_rebase ;
541
719
}
542
720
721
+ if (opts -> type == REBASE_AM ) {
722
+ status = run_am (opts );
723
+ goto finished_rebase ;
724
+ }
725
+
543
726
add_var (& script_snippet , "GIT_DIR" , absolute_path (get_git_dir ()));
544
727
add_var (& script_snippet , "state_dir" , opts -> state_dir );
545
728
0 commit comments