Re: [PATCH v7 4/5] rebase -i: support --ignore-date
From: Johannes Schindelin <hidden>
Date: 2020-08-13 14:07:54
Hi Phillip, On Thu, 16 Jul 2020, Phillip Wood wrote:
quoted hunk ↗ jump to hunk
@@ -957,7 +976,11 @@ static int run_git_commit(struct repository *r, if (opts->committer_date_is_author_date) argv_array_pushf(&cmd.env_array, "GIT_COMMITTER_DATE=%s", + opts->ignore_date ? + "" : author_date_from_env_array(&cmd.env_array)); + if (opts->ignore_date) + argv_array_push(&cmd.env_array, "GIT_AUTHOR_DATE=");
Technically, if we switched those two `if` blocks, we would not have to edit the committer date one. But this way is much clearer.
quoted hunk ↗ jump to hunk
argv_array_push(&cmd.args, "commit");@@ -1388,7 +1411,8 @@ static int try_to_commit(struct repository *r, ident.date_begin, (int)(ident.tz_end - ident.tz_begin), ident.tz_begin); - res = setenv("GIT_COMMITTER_DATE", date.buf, 1); + res = setenv("GIT_COMMITTER_DATE", + opts->ignore_date ? "" : date.buf, 1);
Isn't this constructing the `date` string for nothing, if
`opts->ignore_date` is set?
I would much rather see it done this way:
- if (opts->committer_date_is_author_date) {
+ if (opts->committer_date_is_author_date && opts->ignore_date)
+ setenv("GIT_COMMITTER_DATE", "", 1);
+ else if (opts->committer_date_is_author_date) {
Not enough of a reason to re-roll, though.
quoted hunk ↗ jump to hunk
strbuf_release(&date); if (res)@@ -1454,6 +1478,16 @@ static int try_to_commit(struct repository *r, reset_ident_date(); + if (opts->ignore_date) { + author = ignore_author_date(author); + if (!author) { + res = -1; + goto out; + } + free(author_to_free);
A better cadence might be to first `free(author_to_free)`, then assign `author = author_to_free = ignore_author_date(author);` (at least in my perspective, it reads more naturally). But again, not a big reason for a re-roll. The rest of the patch looks good to me. Thank you, Dscho
+ author_to_free = (char *)author;
quoted hunk ↗ jump to hunk
+ } + if (commit_tree_extended(msg->buf, msg->len, &tree, parents, oid, author, opts->gpg_sign, extra)) { res = error(_("failed to write commit object"));@@ -2583,6 +2617,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;@@ -2675,6 +2714,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name, write_file(rebase_path_keep_redundant_commits(), "%s", ""); 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", "");@@ -3597,7 +3638,11 @@ static int do_merge(struct repository *r, if (opts->committer_date_is_author_date) argv_array_pushf(&cmd.env_array, "GIT_COMMITTER_DATE=%s", + opts->ignore_date ? + "" : author_date_from_env_array(&cmd.env_array)); + if (opts->ignore_date) + argv_array_push(&cmd.env_array, "GIT_AUTHOR_DATE="); cmd.git_cmd = 1; argv_array_push(&cmd.args, "merge");@@ -3877,7 +3922,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;diff --git a/sequencer.h b/sequencer.h index 4ab94119ae..3587878e3b 100644 --- a/sequencer.h +++ b/sequencer.h@@ -46,6 +46,7 @@ struct replay_opts { int quiet; int reschedule_failed_exec; int committer_date_is_author_date; + int ignore_date; int mainline;diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh index 50a63d8ebe..0ede2b8900 100755 --- a/t/t3436-rebase-more-options.sh +++ b/t/t3436-rebase-more-options.sh@@ -108,6 +108,62 @@ test_expect_success '--committer-date-is-author-date works when committing confl test_ctime_is_atime -1 ' +# Checking for +0000 in the author date is sufficient since the +# default timezone is UTC but the timezone used while committing is +# +0530. The inverted logic in the grep is necessary to check all the +# author dates in the file. +test_ctime_is_ignored () { + git log $1 --format=%ai >authortime && + ! grep -v +0000 authortime +} + +test_expect_success '--ignore-date works with apply backend' ' + git commit --amend --date="$GIT_AUTHOR_DATE" && + git rebase --apply --ignore-date HEAD^ && + test_ctime_is_ignored -1 +' + +test_expect_success '--ignore-date works with merge backend' ' + git commit --amend --date="$GIT_AUTHOR_DATE" && + git rebase --ignore-date -m HEAD^ && + test_ctime_is_ignored -1 +' + +test_expect_success '--ignore-date works after conflict resolution' ' + test_must_fail git rebase --ignore-date -m \ + --onto commit2^^ commit2^ commit2 && + echo resolved >foo && + git add foo && + git rebase --continue && + test_ctime_is_ignored -1 +' + +test_expect_success '--ignore-date works with rebase -r' ' + git checkout side && + git merge --no-ff commit3 && + git rebase -r --root --ignore-date && + test_ctime_is_ignored +' + +test_expect_success '--ignore-date with --committer-date-is-author-date works' ' + test_must_fail git rebase -m --committer-date-is-author-date \ + --ignore-date --onto commit2^^ commit2^ commit3 && + git checkout --theirs foo && + git add foo && + git rebase --continue && + test_ctime_is_atime -2 && + test_ctime_is_ignored -2 +' + +test_expect_success '--ignore-date --committer-date-is-author-date works when forking merge' ' + GIT_SEQUENCE_EDITOR="echo \"merge -C $(git rev-parse HEAD) commit3\">" \ + PATH="./test-bin:$PATH" git rebase -i --strategy=test \ + --ignore-date --committer-date-is-author-date \ + side side && + test_ctime_is_atime -1 && + test_ctime_is_ignored -1 + ' + # This must be the last test in this file test_expect_success '$EDITOR and friends are unchanged' ' test_editor_unchanged --2.27.0