@ -147,6 +147,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, "rebase-merge/refs-to-delete")
* command-line.
* command-line.
*/
*/
static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
static GIT_PATH_FUNC(rebase_path_cdate_is_adate, "rebase-merge/cdate_is_adate")
static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")
static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")
@ -879,6 +880,17 @@ static char *get_author(const char *message)
return NULL;
return NULL;
}
}
/* Returns a "date" string that needs to be free()'d by the caller */
static char *read_author_date_or_null(void)
{
char *date;
if (read_author_script(rebase_path_author_script(),
NULL, NULL, &date, 0))
return NULL;
return date;
}
static const char staged_changes_advice[] =
static const char staged_changes_advice[] =
N_("you have staged changes in your working tree\n"
N_("you have staged changes in your working tree\n"
"If these changes are meant to be squashed into the previous commit, run:\n"
"If these changes are meant to be squashed into the previous commit, run:\n"
@ -938,6 +950,24 @@ static int run_git_commit(struct repository *r,
cmd.git_cmd = 1;
cmd.git_cmd = 1;
if (opts->committer_date_is_author_date) {
int res = -1;
struct strbuf datebuf = STRBUF_INIT;
char *date = read_author_date_or_null();
if (!date)
return -1;
strbuf_addf(&datebuf, "@%s", date);
res = setenv("GIT_COMMITTER_DATE", datebuf.buf, 1);
strbuf_release(&datebuf);
free(date);
if (res)
return -1;
}
if (is_rebase_i(opts) && read_env_script(&cmd.env_array)) {
if (is_rebase_i(opts) && read_env_script(&cmd.env_array)) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
const char *gpg_opt = gpg_sign_opt_quoted(opts);
@ -1331,7 +1361,6 @@ static int try_to_commit(struct repository *r,
if (parse_head(r, ¤t_head))
if (parse_head(r, ¤t_head))
return -1;
return -1;
if (flags & AMEND_MSG) {
if (flags & AMEND_MSG) {
const char *exclude_gpgsig[] = { "gpgsig", NULL };
const char *exclude_gpgsig[] = { "gpgsig", NULL };
const char *out_enc = get_commit_output_encoding();
const char *out_enc = get_commit_output_encoding();
@ -1359,6 +1388,30 @@ static int try_to_commit(struct repository *r,
commit_list_insert(current_head, &parents);
commit_list_insert(current_head, &parents);
}
}
if (opts->committer_date_is_author_date) {
int len = strlen(author);
struct ident_split ident;
struct strbuf date = STRBUF_INIT;
if (split_ident_line(&ident, author, len) < 0) {
res = error(_("malformed ident line"));
goto out;
}
if (!ident.date_begin) {
res = error(_("corrupted author without date information"));
goto out;
}
strbuf_addf(&date, "@%.*s %.*s",
(int)(ident.date_end - ident.date_begin), ident.date_begin,
(int)(ident.tz_end - ident.tz_begin), ident.tz_begin);
res = setenv("GIT_COMMITTER_DATE", date.buf, 1);
strbuf_release(&date);
if (res)
goto out;
}
if (write_index_as_tree(&tree, r->index, r->index_file, 0, NULL)) {
if (write_index_as_tree(&tree, r->index, r->index_file, 0, NULL)) {
res = error(_("git write-tree failed to write a tree"));
res = error(_("git write-tree failed to write a tree"));
goto out;
goto out;
@ -2480,6 +2533,11 @@ static int read_populate_opts(struct replay_opts *opts)
opts->signoff = 1;
opts->signoff = 1;
}
}
if (file_exists(rebase_path_cdate_is_adate())) {
opts->allow_ff = 0;
opts->committer_date_is_author_date = 1;
}
if (file_exists(rebase_path_reschedule_failed_exec()))
if (file_exists(rebase_path_reschedule_failed_exec()))
opts->reschedule_failed_exec = 1;
opts->reschedule_failed_exec = 1;
@ -2562,6 +2620,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
write_file(rebase_path_gpg_sign_opt(), "-S%s\n", opts->gpg_sign);
write_file(rebase_path_gpg_sign_opt(), "-S%s\n", opts->gpg_sign);
if (opts->signoff)
if (opts->signoff)
write_file(rebase_path_signoff(), "--signoff\n");
write_file(rebase_path_signoff(), "--signoff\n");
if (opts->committer_date_is_author_date)
write_file(rebase_path_cdate_is_adate(), "%s", "");
if (opts->reschedule_failed_exec)
if (opts->reschedule_failed_exec)
write_file(rebase_path_reschedule_failed_exec(), "%s", "");
write_file(rebase_path_reschedule_failed_exec(), "%s", "");
@ -3650,7 +3710,8 @@ static int pick_commits(struct repository *r,
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
if (opts->allow_ff)
if (opts->allow_ff)
assert(!(opts->signoff || opts->no_commit ||
assert(!(opts->signoff || opts->no_commit ||
opts->record_origin || opts->edit));
opts->record_origin || opts->edit ||
opts->committer_date_is_author_date));
if (read_and_refresh_cache(r, opts))
if (read_and_refresh_cache(r, opts))
return -1;
return -1;