@@ -37,6 +37,17 @@ static GIT_PATH_FUNC(git_path_rebase_dir, "rebase-merge")
3737 * file and written to the tail of 'done'.
3838 */
3939static GIT_PATH_FUNC (git_path_rebase_todo , "rebase-merge/git-rebase-todo" )
40+ /*
41+ * The commit message that is planned to be used for any changes that
42+ * need to be committed following a user interaction.
43+ */
44+ static GIT_PATH_FUNC (git_path_rebase_msg , "rebase-merge/message" )
45+ /*
46+ * A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
47+ * GIT_AUTHOR_DATE that will be used for the commit that is currently
48+ * being rebased.
49+ */
50+ static GIT_PATH_FUNC (author_script , "rebase-merge/author-script" )
4051/*
4152 * When an "edit" rebase command is being processed, the SHA1 of the
4253 * commit to be edited is recorded in this file. When "git rebase
@@ -401,20 +412,76 @@ static int is_index_unchanged(void)
401412 return !hashcmp (active_cache_tree -> sha1 , head_commit -> tree -> object .oid .hash );
402413}
403414
415+ static char * * read_author_script ()
416+ {
417+ struct strbuf script = STRBUF_INIT ;
418+ int i , count = 0 ;
419+ char * p , * p2 , * * env ;
420+ size_t env_size ;
421+
422+ if (strbuf_read_file (& script , author_script (), 256 ) <= 0 )
423+ return NULL ;
424+
425+ for (p = script .buf ; * p ; p ++ )
426+ if (skip_prefix (p , "'\\\\''" , (const char * * )& p2 ))
427+ strbuf_splice (& script , p - script .buf , p2 - p , "'" , 1 );
428+ else if (* p == '\'' )
429+ strbuf_splice (& script , p -- - script .buf , 1 , "" , 0 );
430+ else if (* p == '\n' ) {
431+ * p = '\0' ;
432+ count ++ ;
433+ }
434+
435+ env_size = (count + 1 ) * sizeof (* env );
436+ strbuf_grow (& script , env_size );
437+ memmove (script .buf + env_size , script .buf , script .len );
438+ p = script .buf + env_size ;
439+ env = (char * * )strbuf_detach (& script , NULL );
440+
441+ for (i = 0 ; i < count ; i ++ ) {
442+ env [i ] = p ;
443+ p += strlen (p ) + 1 ;
444+ }
445+ env [count ] = NULL ;
446+
447+ return env ;
448+ }
449+
404450/*
405451 * If we are cherry-pick, and if the merge did not result in
406452 * hand-editing, we will hit this commit and inherit the original
407453 * author date and name.
408454 * If we are revert, or if our cherry-pick results in a hand merge,
409- * we had better say that the current user is responsible for that.
455+ * we had better say that the current user is responsible for that
456+ * (except, of course, while running an interactive rebase).
410457 */
411- static int run_git_commit (const char * defmsg , struct replay_opts * opts ,
458+ int sequencer_commit (const char * defmsg , struct replay_opts * opts ,
412459 int allow_empty )
413460{
461+ char * * env = NULL ;
414462 struct argv_array array ;
415463 int rc ;
416464 const char * value ;
417465
466+ if (IS_REBASE_I ()) {
467+ if (!defmsg )
468+ defmsg = git_path_rebase_msg ();
469+
470+ env = read_author_script ();
471+ if (!env )
472+ /* TODO: gpg_sign_opt */
473+ return error ("You have staged changes in your working "
474+ "tree. If these changes are meant to be\n"
475+ "squashed into the previous commit, run:\n\n"
476+ " git commit --amend $gpg_sign_opt_quoted\n\n"
477+ "If they are meant to go into a new commit, "
478+ "run:\n\n"
479+ " git commit $gpg_sign_opt_quoted\n\n"
480+ "In both case, once you're done, continue "
481+ "with:\n\n"
482+ " git rebase --continue\n" );
483+ }
484+
418485 argv_array_init (& array );
419486 argv_array_push (& array , "commit" );
420487 argv_array_push (& array , "-n" );
@@ -423,23 +490,28 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
423490 argv_array_pushf (& array , "-S%s" , opts -> gpg_sign );
424491 if (opts -> signoff )
425492 argv_array_push (& array , "-s" );
426- if (!opts -> edit ) {
493+ if (!opts -> edit || IS_REBASE_I () ) {
427494 argv_array_push (& array , "-F" );
428495 argv_array_push (& array , defmsg );
429496 if (!opts -> signoff &&
430497 !opts -> record_origin &&
431498 git_config_get_value ("commit.cleanup" , & value ))
432499 argv_array_push (& array , "--cleanup=verbatim" );
433500 }
501+ if (opts -> edit && IS_REBASE_I ())
502+ argv_array_push (& array , "-e" );
434503
435504 if (allow_empty )
436505 argv_array_push (& array , "--allow-empty" );
437506
438507 if (opts -> allow_empty_message )
439508 argv_array_push (& array , "--allow-empty-message" );
440509
441- rc = run_command_v_opt (array .argv , RUN_GIT_CMD );
510+ rc = run_command_v_opt_cd_env (array .argv , RUN_GIT_CMD , NULL ,
511+ (const char * const * )env );
442512 argv_array_clear (& array );
513+ free (env );
514+
443515 return rc ;
444516}
445517
@@ -693,7 +765,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
693765 goto leave ;
694766 }
695767 if (!opts -> no_commit )
696- res = run_git_commit (git_path_merge_msg (), opts , allow );
768+ res = sequencer_commit (git_path_merge_msg (), opts , allow );
697769
698770leave :
699771 free_message (commit , & msg );
0 commit comments