@@ -27,6 +27,19 @@ static GIT_PATH_FUNC(git_path_todo_file, "sequencer/todo")
2727static GIT_PATH_FUNC (git_path_opts_file , "sequencer/opts" )
2828static GIT_PATH_FUNC (git_path_head_file , "sequencer/head" )
2929
30+ /*
31+ * A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
32+ * GIT_AUTHOR_DATE that will be used for the commit that is currently
33+ * being rebased.
34+ */
35+ static GIT_PATH_FUNC (rebase_path_author_script , "rebase-merge/author-script" )
36+
37+ /* We will introduce the 'interactive rebase' mode later */
38+ static inline int is_rebase_i (const struct replay_opts * opts )
39+ {
40+ return 0 ;
41+ }
42+
3043static const char * get_dir (const struct replay_opts * opts )
3144{
3245 return git_path_seq_dir ();
@@ -369,20 +382,80 @@ static int is_index_unchanged(void)
369382 return !hashcmp (active_cache_tree -> sha1 , head_commit -> tree -> object .oid .hash );
370383}
371384
385+ /*
386+ * Read the author-script file into an environment block, ready for use in
387+ * run_command(), that can be free()d afterwards.
388+ */
389+ static char * * read_author_script (void )
390+ {
391+ struct strbuf script = STRBUF_INIT ;
392+ int i , count = 0 ;
393+ char * p , * p2 , * * env ;
394+ size_t env_size ;
395+
396+ if (strbuf_read_file (& script , rebase_path_author_script (), 256 ) <= 0 )
397+ return NULL ;
398+
399+ for (p = script .buf ; * p ; p ++ )
400+ if (skip_prefix (p , "'\\\\''" , (const char * * )& p2 ))
401+ strbuf_splice (& script , p - script .buf , p2 - p , "'" , 1 );
402+ else if (* p == '\'' )
403+ strbuf_splice (& script , p -- - script .buf , 1 , "" , 0 );
404+ else if (* p == '\n' ) {
405+ * p = '\0' ;
406+ count ++ ;
407+ }
408+
409+ env_size = (count + 1 ) * sizeof (* env );
410+ strbuf_grow (& script , env_size );
411+ memmove (script .buf + env_size , script .buf , script .len );
412+ p = script .buf + env_size ;
413+ env = (char * * )strbuf_detach (& script , NULL );
414+
415+ for (i = 0 ; i < count ; i ++ ) {
416+ env [i ] = p ;
417+ p += strlen (p ) + 1 ;
418+ }
419+ env [count ] = NULL ;
420+
421+ return env ;
422+ }
423+
372424/*
373425 * If we are cherry-pick, and if the merge did not result in
374426 * hand-editing, we will hit this commit and inherit the original
375427 * author date and name.
428+ *
376429 * If we are revert, or if our cherry-pick results in a hand merge,
377430 * we had better say that the current user is responsible for that.
431+ *
432+ * An exception is when run_git_commit() is called during an
433+ * interactive rebase: in that case, we will want to retain the
434+ * author metadata.
378435 */
379436static int run_git_commit (const char * defmsg , struct replay_opts * opts ,
380437 int allow_empty )
381438{
439+ char * * env = NULL ;
382440 struct argv_array array ;
383441 int rc ;
384442 const char * value ;
385443
444+ if (is_rebase_i (opts )) {
445+ env = read_author_script ();
446+ if (!env )
447+ return error ("You have staged changes in your working "
448+ "tree. If these changes are meant to be\n"
449+ "squashed into the previous commit, run:\n\n"
450+ " git commit --amend $gpg_sign_opt_quoted\n\n"
451+ "If they are meant to go into a new commit, "
452+ "run:\n\n"
453+ " git commit $gpg_sign_opt_quoted\n\n"
454+ "In both cases, once you're done, continue "
455+ "with:\n\n"
456+ " git rebase --continue\n" );
457+ }
458+
386459 argv_array_init (& array );
387460 argv_array_push (& array , "commit" );
388461 argv_array_push (& array , "-n" );
@@ -391,23 +464,25 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
391464 argv_array_pushf (& array , "-S%s" , opts -> gpg_sign );
392465 if (opts -> signoff )
393466 argv_array_push (& array , "-s" );
394- if (!opts -> edit ) {
395- argv_array_push (& array , "-F" );
396- argv_array_push (& array , defmsg );
397- if (!opts -> signoff &&
398- !opts -> record_origin &&
399- git_config_get_value ("commit.cleanup" , & value ))
400- argv_array_push (& array , "--cleanup=verbatim" );
401- }
467+ if (defmsg )
468+ argv_array_pushl (& array , "-F" , defmsg , NULL );
469+ if (opts -> edit )
470+ argv_array_push (& array , "-e" );
471+ else if (!opts -> signoff && !opts -> record_origin &&
472+ git_config_get_value ("commit.cleanup" , & value ))
473+ argv_array_push (& array , "--cleanup=verbatim" );
402474
403475 if (allow_empty )
404476 argv_array_push (& array , "--allow-empty" );
405477
406478 if (opts -> allow_empty_message )
407479 argv_array_push (& array , "--allow-empty-message" );
408480
409- rc = run_command_v_opt (array .argv , RUN_GIT_CMD );
481+ rc = run_command_v_opt_cd_env (array .argv , RUN_GIT_CMD , NULL ,
482+ (const char * const * )env );
410483 argv_array_clear (& array );
484+ free (env );
485+
411486 return rc ;
412487}
413488
@@ -657,7 +732,8 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
657732 goto leave ;
658733 }
659734 if (!opts -> no_commit )
660- res = run_git_commit (git_path_merge_msg (), opts , allow );
735+ res = run_git_commit (opts -> edit ? NULL : git_path_merge_msg (),
736+ opts , allow );
661737
662738leave :
663739 free_message (commit , & msg );
@@ -879,6 +955,9 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
879955
880956static int read_populate_opts (struct replay_opts * opts )
881957{
958+ if (is_rebase_i (opts ))
959+ return 0 ;
960+
882961 if (!file_exists (git_path_opts_file ()))
883962 return 0 ;
884963 /*
0 commit comments