Skip to content

Commit

Permalink
rebase -i: support --ignore-date
Browse files Browse the repository at this point in the history
rebase am already has this flag to "lie" about the author date
by changing it to the committer (current) date. Let's add the same
for interactive machinery.

Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>
  • Loading branch information
r1walz committed Aug 5, 2019
1 parent 28a54cd commit 554377d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 14 deletions.
6 changes: 3 additions & 3 deletions Documentation/git-rebase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,8 @@ See also INCOMPATIBLE OPTIONS below.
as the committer date. This implies --force-rebase.

--ignore-date::
This flag is passed to 'git am' to change the author date
of the rebased commits (see linkgit:git-am[1]).
Lie about the author date by re-setting it to the value
same as committer (current) date. This implies --force-rebase.
+
See also INCOMPATIBLE OPTIONS below.

Expand Down Expand Up @@ -526,7 +526,6 @@ INCOMPATIBLE OPTIONS

The following options:

* --ignore-date
* --whitespace
* -C

Expand All @@ -552,6 +551,7 @@ In addition, the following pairs of options are incompatible:
* --preserve-merges and --rebase-merges
* --preserve-merges and --ignore-whitespace
* --preserve-merges and --committer-date-is-author-date
* --preserve-merges and --ignore-date
* --rebase-merges and --ignore-whitespace
* --rebase-merges and --strategy
* --rebase-merges and --strategy-option
Expand Down
17 changes: 11 additions & 6 deletions builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct rebase_options {
char *gpg_sign_opt;
int autostash;
int committer_date_is_author_date;
int ignore_date;
char *cmd;
int allow_empty_message;
int rebase_merges, rebase_cousins;
Expand Down Expand Up @@ -116,6 +117,7 @@ static struct replay_opts get_replay_opts(struct rebase_options *opts)
replay.reschedule_failed_exec = opts->reschedule_failed_exec;
replay.committer_date_is_author_date =
opts->committer_date_is_author_date;
replay.ignore_date = opts->ignore_date;
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
replay.strategy = opts->strategy;

Expand Down Expand Up @@ -535,7 +537,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
warning(_("--[no-]rebase-cousins has no effect without "
"--rebase-merges"));

if (opts.committer_date_is_author_date)
if (opts.committer_date_is_author_date ||
opts.ignore_date)
opts.flags |= REBASE_FORCE;

return !!run_rebase_interactive(&opts, command);
Expand Down Expand Up @@ -978,6 +981,8 @@ static int run_am(struct rebase_options *opts)
argv_array_push(&am.args, "--ignore-whitespace");
if (opts->committer_date_is_author_date)
argv_array_push(&opts->git_am_opts, "--committer-date-is-author-date");
if (opts->ignore_date)
argv_array_push(&opts->git_am_opts, "--ignore-date");
if (opts->action && !strcmp("continue", opts->action)) {
argv_array_push(&am.args, "--resolved");
argv_array_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
Expand Down Expand Up @@ -1428,8 +1433,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "committer-date-is-author-date",
&options.committer_date_is_author_date,
N_("make committer date match author date")),
OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL,
N_("passed to 'git am'"), PARSE_OPT_NOARG),
OPT_BOOL(0, "ignore-date", &options.ignore_date,
"ignore author date and use current date"),
OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
N_("passed to 'git apply'"), 0),
OPT_BOOL(0, "ignore-whitespace", &options.ignore_whitespace,
Expand Down Expand Up @@ -1694,13 +1699,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
state_dir_base, cmd_live_rebase, buf.buf);
}

if (options.committer_date_is_author_date)
if (options.committer_date_is_author_date ||
options.ignore_date)
options.flags |= REBASE_FORCE;

for (i = 0; i < options.git_am_opts.argc; i++) {
const char *option = options.git_am_opts.argv[i], *p;
if (!strcmp(option, "--ignore-date") ||
!strcmp(option, "--whitespace=fix") ||
if (!strcmp(option, "--whitespace=fix") ||
!strcmp(option, "--whitespace=strip"))
options.flags |= REBASE_FORCE;
else if (skip_prefix(option, "-C", &p)) {
Expand Down
48 changes: 43 additions & 5 deletions sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, "rebase-merge/refs-to-delete")
*/
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_ignore_date, "rebase-merge/ignore_date")
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_quiet, "rebase-merge/quiet")
Expand Down Expand Up @@ -928,6 +929,17 @@ static int setenv_committer_date_to_author_date(void)
return res;
}

static void ignore_author_date(const char **author)
{
struct strbuf new_author = STRBUF_INIT;
char *idx = memchr(*author, '>', strlen(*author));

strbuf_add(&new_author, *author, idx - *author);
strbuf_addstr(&new_author, "> ");
datestamp(&new_author);
*author = strbuf_detach(&new_author, NULL);
}

static const char staged_changes_advice[] =
N_("you have staged changes in your working tree\n"
"If these changes are meant to be squashed into the previous commit, run:\n"
Expand Down Expand Up @@ -985,7 +997,7 @@ static int run_git_commit(struct repository *r,
{
struct child_process cmd = CHILD_PROCESS_INIT;

if (opts->committer_date_is_author_date &&
if (opts->committer_date_is_author_date && !opts->ignore_date &&
setenv_committer_date_to_author_date())
return 1;
if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) {
Expand Down Expand Up @@ -1013,10 +1025,18 @@ static int run_git_commit(struct repository *r,

if (res <= 0)
res = error_errno(_("could not read '%s'"), defmsg);
else
else {
if (opts->ignore_date) {
if (!author)
BUG("ignore-date can only be used with "
"rebase -i, which must set the "
"author before committing the tree");
ignore_author_date(&author);
}
res = commit_tree(msg.buf, msg.len, cache_tree_oid,
NULL, &root_commit, author,
opts->gpg_sign);
}

strbuf_release(&msg);
strbuf_release(&script);
Expand Down Expand Up @@ -1046,6 +1066,8 @@ static int run_git_commit(struct repository *r,
argv_array_push(&cmd.args, "--amend");
if (opts->gpg_sign)
argv_array_pushf(&cmd.args, "-S%s", opts->gpg_sign);
if (opts->ignore_date)
argv_array_pushf(&cmd.args, "--date=%ld", time(NULL));
if (defmsg)
argv_array_pushl(&cmd.args, "-F", defmsg, NULL);
else if (!(flags & EDIT_MSG))
Expand Down Expand Up @@ -1425,7 +1447,7 @@ static int try_to_commit(struct repository *r,
if (parse_head(r, &current_head))
return -1;
if (!(flags & AMEND_MSG) && opts->committer_date_is_author_date &&
setenv_committer_date_to_author_date())
!opts->ignore_date && setenv_committer_date_to_author_date())
return -1;
if (flags & AMEND_MSG) {
const char *exclude_gpgsig[] = { "gpgsig", NULL };
Expand All @@ -1447,7 +1469,7 @@ static int try_to_commit(struct repository *r,
res = error(_("unable to parse commit author"));
goto out;
}
if (opts->committer_date_is_author_date) {
if (opts->committer_date_is_author_date && !opts->ignore_date) {
char *date;
int len = strlen(author);
char *idx = memchr(author, '>', len);
Expand Down Expand Up @@ -1507,6 +1529,11 @@ static int try_to_commit(struct repository *r,

reset_ident_date();

if (opts->ignore_date) {
ignore_author_date(&author);
free(amend_author);
amend_author = (char *)author;
}
if (commit_tree_extended(msg->buf, msg->len, &tree, parents,
oid, author, opts->gpg_sign, extra)) {
res = error(_("failed to write commit object"));
Expand Down Expand Up @@ -2583,6 +2610,11 @@ static int read_populate_opts(struct replay_opts *opts)
opts->committer_date_is_author_date = 1;
}

if (file_exists(rebase_path_ignore_date())) {
opts->allow_ff = 0;
opts->ignore_date = 1;
}

if (file_exists(rebase_path_reschedule_failed_exec()))
opts->reschedule_failed_exec = 1;

Expand Down Expand Up @@ -2667,6 +2699,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,
write_file(rebase_path_signoff(), "--signoff\n");
if (opts->committer_date_is_author_date)
write_file(rebase_path_cdate_is_adate(), "%s", "");
if (opts->ignore_date)
write_file(rebase_path_ignore_date(), "%s", "");
if (opts->reschedule_failed_exec)
write_file(rebase_path_reschedule_failed_exec(), "%s", "");

Expand Down Expand Up @@ -3484,6 +3518,9 @@ static int do_merge(struct repository *r,
argv_array_push(&cmd.args, git_path_merge_msg(r));
if (opts->gpg_sign)
argv_array_push(&cmd.args, opts->gpg_sign);
if (opts->ignore_date)
argv_array_pushf(&cmd.args,
"GIT_AUTHOR_DATE=%ld", time(NULL));

/* Add the tips to be merged */
for (j = to_merge; j; j = j->next)
Expand Down Expand Up @@ -3756,7 +3793,8 @@ static int pick_commits(struct repository *r,
if (opts->allow_ff)
assert(!(opts->signoff || opts->no_commit ||
opts->record_origin || opts->edit ||
opts->committer_date_is_author_date));
opts->committer_date_is_author_date ||
opts->ignore_date));
if (read_and_refresh_cache(r, opts))
return -1;

Expand Down
1 change: 1 addition & 0 deletions sequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct replay_opts {
int quiet;
int reschedule_failed_exec;
int committer_date_is_author_date;
int ignore_date;

int mainline;

Expand Down
16 changes: 16 additions & 0 deletions t/t3433-rebase-options-compatibility.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,20 @@ test_expect_success '--committer-date-is-author-date works with interactive back
test_cmp authortime committertime
'

# Checking for +0000 in author time is enough since default
# timezone is UTC, but the timezone used while committing
# sets to +0530.
test_expect_success '--ignore-date works with am backend' '
git commit --amend --date="$GIT_AUTHOR_DATE" &&
git rebase --ignore-date HEAD^ &&
git show HEAD --pretty="format:%ai" >authortime &&
grep "+0000" authortime
'

test_expect_success '--ignore-date works with interactive backend' '
git commit --amend --date="$GIT_AUTHOR_DATE" &&
git rebase --ignore-date -i HEAD^ &&
git show HEAD --pretty="format:%ai" >authortime &&
grep "+0000" authortime
'
test_done

0 comments on commit 554377d

Please sign in to comment.