@@ -246,6 +246,37 @@ static int read_basic_state(struct rebase_options *opts)
246246 return 0 ;
247247}
248248
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+
249280static int apply_autostash (struct rebase_options * opts )
250281{
251282 const char * path = state_dir_path ("autostash" , opts );
@@ -459,13 +490,156 @@ static int reset_head(struct object_id *oid, const char *action,
459490 return ret ;
460491}
461492
493+ static int move_to_original_branch (struct rebase_options * opts )
494+ {
495+ struct strbuf orig_head_reflog = STRBUF_INIT , head_reflog = STRBUF_INIT ;
496+ int ret ;
497+
498+ if (!opts -> head_name )
499+ return 0 ; /* nothing to move back to */
500+
501+ if (!opts -> onto )
502+ BUG ("move_to_original_branch without onto" );
503+
504+ strbuf_addf (& orig_head_reflog , "rebase finished: %s onto %s" ,
505+ opts -> head_name , oid_to_hex (& opts -> onto -> object .oid ));
506+ strbuf_addf (& head_reflog , "rebase finished: returning to %s" ,
507+ opts -> head_name );
508+ ret = reset_head (NULL , "" , opts -> head_name , RESET_HEAD_REFS_ONLY ,
509+ orig_head_reflog .buf , head_reflog .buf );
510+
511+ strbuf_release (& orig_head_reflog );
512+ strbuf_release (& head_reflog );
513+ return ret ;
514+ }
515+
462516static const char * resolvemsg =
463517N_ ("Resolve all conflicts manually, mark them as resolved with\n"
464518"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
465519"You can instead skip this commit: run \"git rebase --skip\".\n"
466520"To abort and get back to the state before \"git rebase\", run "
467521"\"git rebase --abort\"." );
468522
523+ static int run_am (struct rebase_options * opts )
524+ {
525+ struct child_process am = CHILD_PROCESS_INIT ;
526+ struct child_process format_patch = CHILD_PROCESS_INIT ;
527+ struct strbuf revisions = STRBUF_INIT ;
528+ int status ;
529+ char * rebased_patches ;
530+
531+ am .git_cmd = 1 ;
532+ argv_array_push (& am .args , "am" );
533+
534+ if (opts -> action && !strcmp ("continue" , opts -> action )) {
535+ argv_array_push (& am .args , "--resolved" );
536+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
537+ if (opts -> gpg_sign_opt )
538+ argv_array_push (& am .args , opts -> gpg_sign_opt );
539+ status = run_command (& am );
540+ if (status )
541+ return status ;
542+
543+ return move_to_original_branch (opts );
544+ }
545+ if (opts -> action && !strcmp ("skip" , opts -> action )) {
546+ argv_array_push (& am .args , "--skip" );
547+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
548+ status = run_command (& am );
549+ if (status )
550+ return status ;
551+
552+ return move_to_original_branch (opts );
553+ }
554+ if (opts -> action && !strcmp ("show-current-patch" , opts -> action )) {
555+ argv_array_push (& am .args , "--show-current-patch" );
556+ return run_command (& am );
557+ }
558+
559+ strbuf_addf (& revisions , "%s...%s" ,
560+ oid_to_hex (opts -> root ?
561+ /* this is now equivalent to !opts->upstream */
562+ & opts -> onto -> object .oid :
563+ & opts -> upstream -> object .oid ),
564+ oid_to_hex (& opts -> orig_head ));
565+
566+ rebased_patches = xstrdup (git_path ("rebased-patches" ));
567+ format_patch .out = open (rebased_patches ,
568+ O_WRONLY | O_CREAT | O_TRUNC , 0666 );
569+ if (format_patch .out < 0 ) {
570+ status = error_errno (_ ("could not open '%s' for writing" ),
571+ rebased_patches );
572+ free (rebased_patches );
573+ argv_array_clear (& am .args );
574+ return status ;
575+ }
576+
577+ format_patch .git_cmd = 1 ;
578+ argv_array_pushl (& format_patch .args , "format-patch" , "-k" , "--stdout" ,
579+ "--full-index" , "--cherry-pick" , "--right-only" ,
580+ "--src-prefix=a/" , "--dst-prefix=b/" , "--no-renames" ,
581+ "--no-cover-letter" , "--pretty=mboxrd" , NULL );
582+ if (opts -> git_format_patch_opt .len )
583+ argv_array_split (& format_patch .args ,
584+ opts -> git_format_patch_opt .buf );
585+ argv_array_push (& format_patch .args , revisions .buf );
586+ if (opts -> restrict_revision )
587+ argv_array_pushf (& format_patch .args , "^%s" ,
588+ oid_to_hex (& opts -> restrict_revision -> object .oid ));
589+
590+ status = run_command (& format_patch );
591+ if (status ) {
592+ unlink (rebased_patches );
593+ free (rebased_patches );
594+ argv_array_clear (& am .args );
595+
596+ reset_head (& opts -> orig_head , "checkout" , opts -> head_name , 0 ,
597+ "HEAD" , NULL );
598+ error (_ ("\ngit encountered an error while preparing the "
599+ "patches to replay\n"
600+ "these revisions:\n"
601+ "\n %s\n\n"
602+ "As a result, git cannot rebase them." ),
603+ opts -> revisions );
604+
605+ strbuf_release (& revisions );
606+ return status ;
607+ }
608+ strbuf_release (& revisions );
609+
610+ am .in = open (rebased_patches , O_RDONLY );
611+ if (am .in < 0 ) {
612+ status = error_errno (_ ("could not open '%s' for reading" ),
613+ rebased_patches );
614+ free (rebased_patches );
615+ argv_array_clear (& am .args );
616+ return status ;
617+ }
618+
619+ argv_array_pushv (& am .args , opts -> git_am_opts .argv );
620+ argv_array_push (& am .args , "--rebasing" );
621+ argv_array_pushf (& am .args , "--resolvemsg=%s" , resolvemsg );
622+ argv_array_push (& am .args , "--patch-format=mboxrd" );
623+ if (opts -> allow_rerere_autoupdate > 0 )
624+ argv_array_push (& am .args , "--rerere-autoupdate" );
625+ else if (opts -> allow_rerere_autoupdate == 0 )
626+ argv_array_push (& am .args , "--no-rerere-autoupdate" );
627+ if (opts -> gpg_sign_opt )
628+ argv_array_push (& am .args , opts -> gpg_sign_opt );
629+ status = run_command (& am );
630+ unlink (rebased_patches );
631+ free (rebased_patches );
632+
633+ if (!status ) {
634+ return move_to_original_branch (opts );
635+ }
636+
637+ if (is_directory (opts -> state_dir ))
638+ write_basic_state (opts );
639+
640+ return status ;
641+ }
642+
469643static int run_specific_rebase (struct rebase_options * opts )
470644{
471645 const char * argv [] = { NULL , NULL };
@@ -546,6 +720,11 @@ static int run_specific_rebase(struct rebase_options *opts)
546720 goto finished_rebase ;
547721 }
548722
723+ if (opts -> type == REBASE_AM ) {
724+ status = run_am (opts );
725+ goto finished_rebase ;
726+ }
727+
549728 add_var (& script_snippet , "GIT_DIR" , absolute_path (get_git_dir ()));
550729 add_var (& script_snippet , "state_dir" , opts -> state_dir );
551730
0 commit comments