@@ -592,6 +592,18 @@ static int read_env_script(struct argv_array *env)
592
592
return 0 ;
593
593
}
594
594
595
+ static char * get_author (const char * message )
596
+ {
597
+ size_t len ;
598
+ const char * a ;
599
+
600
+ a = find_commit_header (message , "author" , & len );
601
+ if (a )
602
+ return xmemdupz (a , len );
603
+
604
+ return NULL ;
605
+ }
606
+
595
607
static const char staged_changes_advice [] =
596
608
N_ ("you have staged changes in your working tree\n"
597
609
"If these changes are meant to be squashed into the previous commit, run:\n"
@@ -984,6 +996,160 @@ void print_commit_summary(const char *prefix, const struct object_id *oid,
984
996
strbuf_release (& format );
985
997
}
986
998
999
+ static int parse_head (struct commit * * head )
1000
+ {
1001
+ struct commit * current_head ;
1002
+ struct object_id oid ;
1003
+
1004
+ if (get_oid ("HEAD" , & oid )) {
1005
+ current_head = NULL ;
1006
+ } else {
1007
+ current_head = lookup_commit_reference (& oid );
1008
+ if (!current_head )
1009
+ return error (_ ("could not parse HEAD" ));
1010
+ if (oidcmp (& oid , & current_head -> object .oid )) {
1011
+ warning (_ ("HEAD %s is not a commit!" ),
1012
+ oid_to_hex (& oid ));
1013
+ }
1014
+ if (parse_commit (current_head ))
1015
+ return error (_ ("could not parse HEAD commit" ));
1016
+ }
1017
+ * head = current_head ;
1018
+
1019
+ return 0 ;
1020
+ }
1021
+
1022
+ /*
1023
+ * Try to commit without forking 'git commit'. In some cases we need
1024
+ * to run 'git commit' to display an error message
1025
+ *
1026
+ * Returns:
1027
+ * -1 - error unable to commit
1028
+ * 0 - success
1029
+ * 1 - run 'git commit'
1030
+ */
1031
+ static int try_to_commit (struct strbuf * msg , const char * author ,
1032
+ struct replay_opts * opts , unsigned int flags ,
1033
+ struct object_id * oid )
1034
+ {
1035
+ struct object_id tree ;
1036
+ struct commit * current_head ;
1037
+ struct commit_list * parents = NULL ;
1038
+ struct commit_extra_header * extra = NULL ;
1039
+ struct strbuf err = STRBUF_INIT ;
1040
+ struct strbuf amend_msg = STRBUF_INIT ;
1041
+ char * amend_author = NULL ;
1042
+ const char * gpg_sign ;
1043
+ enum commit_msg_cleanup_mode cleanup ;
1044
+ int res = 0 ;
1045
+
1046
+ if (parse_head (& current_head ))
1047
+ return -1 ;
1048
+
1049
+ if (flags & AMEND_MSG ) {
1050
+ const char * exclude_gpgsig [] = { "gpgsig" , NULL };
1051
+ const char * out_enc = get_commit_output_encoding ();
1052
+ const char * message = logmsg_reencode (current_head , NULL ,
1053
+ out_enc );
1054
+
1055
+ if (!msg ) {
1056
+ const char * orig_message = NULL ;
1057
+
1058
+ find_commit_subject (message , & orig_message );
1059
+ msg = & amend_msg ;
1060
+ strbuf_addstr (msg , orig_message );
1061
+ }
1062
+ author = amend_author = get_author (message );
1063
+ unuse_commit_buffer (current_head , message );
1064
+ if (!author ) {
1065
+ res = error (_ ("unable to parse commit author" ));
1066
+ goto out ;
1067
+ }
1068
+ parents = copy_commit_list (current_head -> parents );
1069
+ extra = read_commit_extra_headers (current_head , exclude_gpgsig );
1070
+ } else if (current_head ) {
1071
+ commit_list_insert (current_head , & parents );
1072
+ }
1073
+
1074
+ cleanup = (flags & CLEANUP_MSG ) ? COMMIT_MSG_CLEANUP_ALL :
1075
+ default_msg_cleanup ;
1076
+ if (cleanup != COMMIT_MSG_CLEANUP_NONE )
1077
+ strbuf_stripspace (msg , cleanup == COMMIT_MSG_CLEANUP_ALL );
1078
+ if (!opts -> allow_empty_message && message_is_empty (msg , cleanup )) {
1079
+ res = 1 ; /* run 'git commit' to display error message */
1080
+ goto out ;
1081
+ }
1082
+
1083
+ gpg_sign = opts -> gpg_sign ? opts -> gpg_sign : default_gpg_sign ;
1084
+
1085
+ if (write_cache_as_tree (tree .hash , 0 , NULL )) {
1086
+ res = error (_ ("git write-tree failed to write a tree" ));
1087
+ goto out ;
1088
+ }
1089
+
1090
+ if (!(flags & ALLOW_EMPTY ) && !oidcmp (current_head ?
1091
+ & current_head -> tree -> object .oid :
1092
+ & empty_tree_oid , & tree )) {
1093
+ res = 1 ; /* run 'git commit' to display error message */
1094
+ goto out ;
1095
+ }
1096
+
1097
+ if (commit_tree_extended (msg -> buf , msg -> len , tree .hash , parents ,
1098
+ oid -> hash , author , gpg_sign , extra )) {
1099
+ res = error (_ ("failed to write commit object" ));
1100
+ goto out ;
1101
+ }
1102
+
1103
+ if (update_head_with_reflog (current_head , oid ,
1104
+ getenv ("GIT_REFLOG_ACTION" ), msg , & err )) {
1105
+ res = error ("%s" , err .buf );
1106
+ goto out ;
1107
+ }
1108
+
1109
+ if (flags & AMEND_MSG )
1110
+ commit_post_rewrite (current_head , oid );
1111
+
1112
+ out :
1113
+ free_commit_extra_headers (extra );
1114
+ strbuf_release (& err );
1115
+ strbuf_release (& amend_msg );
1116
+ free (amend_author );
1117
+
1118
+ return res ;
1119
+ }
1120
+
1121
+ static int do_commit (const char * msg_file , const char * author ,
1122
+ struct replay_opts * opts , unsigned int flags )
1123
+ {
1124
+ int res = 1 ;
1125
+
1126
+ if (!(flags & EDIT_MSG ) && !(flags & VERIFY_MSG )) {
1127
+ struct object_id oid ;
1128
+ struct strbuf sb = STRBUF_INIT ;
1129
+
1130
+ if (msg_file && strbuf_read_file (& sb , msg_file , 2048 ) < 0 )
1131
+ return error_errno (_ ("unable to read commit message "
1132
+ "from '%s'" ),
1133
+ msg_file );
1134
+
1135
+ res = try_to_commit (msg_file ? & sb : NULL , author , opts , flags ,
1136
+ & oid );
1137
+ strbuf_release (& sb );
1138
+ if (!res ) {
1139
+ unlink (git_path_cherry_pick_head ());
1140
+ unlink (git_path_merge_msg ());
1141
+ if (!is_rebase_i (opts ))
1142
+ print_commit_summary (NULL , & oid ,
1143
+ SUMMARY_SHOW_AUTHOR_DATE );
1144
+ return res ;
1145
+ }
1146
+ }
1147
+ if (res == 1 )
1148
+ return run_git_commit (msg_file , opts , flags );
1149
+
1150
+ return res ;
1151
+ }
1152
+
987
1153
static int is_original_commit_empty (struct commit * commit )
988
1154
{
989
1155
const struct object_id * ptree_oid ;
@@ -1235,6 +1401,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
1235
1401
struct object_id head ;
1236
1402
struct commit * base , * next , * parent ;
1237
1403
const char * base_label , * next_label ;
1404
+ char * author = NULL ;
1238
1405
struct commit_message msg = { NULL , NULL , NULL , NULL };
1239
1406
struct strbuf msgbuf = STRBUF_INIT ;
1240
1407
int res , unborn = 0 , allow ;
@@ -1351,6 +1518,8 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
1351
1518
strbuf_addstr (& msgbuf , oid_to_hex (& commit -> object .oid ));
1352
1519
strbuf_addstr (& msgbuf , ")\n" );
1353
1520
}
1521
+ if (!is_fixup (command ))
1522
+ author = get_author (msg .message );
1354
1523
}
1355
1524
1356
1525
if (command == TODO_REWORD )
@@ -1436,9 +1605,13 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
1436
1605
goto leave ;
1437
1606
} else if (allow )
1438
1607
flags |= ALLOW_EMPTY ;
1439
- if (!opts -> no_commit )
1608
+ if (!opts -> no_commit ) {
1440
1609
fast_forward_edit :
1441
- res = run_git_commit (msg_file , opts , flags );
1610
+ if (author || command == TODO_REVERT || (flags & AMEND_MSG ))
1611
+ res = do_commit (msg_file , author , opts , flags );
1612
+ else
1613
+ res = error (_ ("unable to parse commit author" ));
1614
+ }
1442
1615
1443
1616
if (!res && final_fixup ) {
1444
1617
unlink (rebase_path_fixup_msg ());
@@ -1447,6 +1620,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
1447
1620
1448
1621
leave :
1449
1622
free_message (commit , & msg );
1623
+ free (author );
1450
1624
update_abort_safety_file ();
1451
1625
1452
1626
return res ;
0 commit comments