{"thread":{"id":"51475","subject":"[GSoC][PATCH 0/1] rebase -i: support --ignore-whitespace","startedAt":"2019-07-12T18:53:01Z","lastAt":"2019-08-02T21:00:32Z","messageCount":32,"participants":["Rohit Ashiwal","Junio C Hamano","Phillip Wood","Elijah Newren","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"378901","messageId":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":null,"subject":"[GSoC][PATCH 0/1] rebase -i: support --ignore-whitespace","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-12T18:50:14Z","receivedAt":"2019-07-12T18:53:01Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"[cc'ing Phillip Wood, Martin Ågren and Dscho; they might be interested]\n\nThere are two backends available for rebasing, viz, the am and the interactive.\nNaturally, there shall be some features that are implemented in one but not in\nthe other. One such flag is --ignore-whitespace which indicated merge mechanism\nto treat lines with only whitespace changes as unchanged.\n\nNB: am's --ignore-space-change (also aliased --ignore-whitespace; see git-apply's\ndescription) not only share the same name with diff's --ignore-space-change and\nmerge's -Xignore-space-change, but the similarity in naming appears to have been\nintentional with am's --ignore-space-change being designed to have the same\nfunctionality (see e.g. the commit messages for f008cef (\"Merge branch\n'jc/apply-ignore-whitespace'\", 2014-06-04) and 4e5dd04 (\"merge-recursive: options\nto ignore whitespace changes\", 2010-08-26)).\n\nFor the most part, these options do provide the same behaviour. However, there\nare some edge cases where both apply's --ignore-space-change and merge's\n-Xignore-space-change fall short of optimal behaviour, and that too in different\nways. Fixing these differences in edge cases is left for future work.\n\nRohit Ashiwal (1):\n  rebase -i: add --ignore-whitespace flag\n\n Documentation/git-rebase.txt            |  9 +++-\n builtin/rebase.c                        | 24 +++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 5 files changed, 95 insertions(+), 6 deletions(-)\n create mode 100755 t/t3431-rebase-options-compatibility.sh\n\n-- \n2.21.0\n\n"},{"id":"378902","messageId":"20190712185015.20585-2-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-12T18:50:15Z","receivedAt":"2019-07-12T18:53:04Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"There are two backends available for rebasing, viz, the am and the\ninteractive. Naturally, there shall be some features that are\nimplemented in one but not in the other. One such flag is\n--ignore-whitespace which indicates merge mechanism to treat lines\nwith only whitespace changes as unchanged. Wire the interactive\nrebase to also understand the --ignore-whitespace flag by\ntranslating it to -Xignore-space-change.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n Documentation/git-rebase.txt            |  9 +++-\n builtin/rebase.c                        | 24 +++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 5 files changed, 95 insertions(+), 6 deletions(-)\n create mode 100755 t/t3431-rebase-options-compatibility.sh\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 5e4e92764..eda52ed82 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -371,8 +371,13 @@ If either <upstream> or --root is given on the command line, then the\n default is `--no-fork-point`, otherwise the default is `--fork-point`.\n \n --ignore-whitespace::\n+\tThis flag is either passed to the 'git apply' program\n+\t(see linkgit:git-apply[1]), or to 'git merge' program\n+\t(see linkgit:git-merge[1]) as `-Xignore-space-change`,\n+\tdepending on which backend is selected by other options.\n+\n --whitespace=<option>::\n-\tThese flag are passed to the 'git apply' program\n+\tThis flag is passed to the 'git apply' program\n \t(see linkgit:git-apply[1]) that applies the patch.\n +\n See also INCOMPATIBLE OPTIONS below.\n@@ -520,7 +525,6 @@ The following options:\n  * --committer-date-is-author-date\n  * --ignore-date\n  * --whitespace\n- * --ignore-whitespace\n  * -C\n \n are incompatible with the following options:\n@@ -543,6 +547,7 @@ In addition, the following pairs of options are incompatible:\n  * --preserve-merges and --interactive\n  * --preserve-merges and --signoff\n  * --preserve-merges and --rebase-merges\n+ * --rebase-merges and --ignore-whitespace\n  * --rebase-merges and --strategy\n  * --rebase-merges and --strategy-option\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex db6ca9bd7..c55957c31 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -79,6 +79,7 @@ struct rebase_options {\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n \tint autosquash;\n+\tint ignore_whitespace;\n \tchar *gpg_sign_opt;\n \tint autostash;\n \tchar *cmd;\n@@ -376,6 +377,17 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n \tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n \n+\tif (opts->ignore_whitespace) {\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tif (opts->strategy_opts)\n+\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n+\n+\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n+\t\tfree(opts->strategy_opts);\n+\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n+\t}\n+\n \tswitch (command) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n@@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n \t\t\tN_(\"GPG-sign commits\"),\n \t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n+\t\tOPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n+\t\t\t N_(\"ignore changes in whitespace\")),\n \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n \t\t\t   N_(\"rebase strategy\")),\n \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n@@ -954,6 +968,8 @@ static int run_am(struct rebase_options *opts)\n \tam.git_cmd = 1;\n \targv_array_push(&am.args, \"am\");\n \n+\tif (opts->ignore_whitespace)\n+\t\targv_array_push(&am.args, \"--ignore-whitespace\");\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\targv_array_push(&am.args, \"--resolved\");\n \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1401,9 +1417,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n-\t\tOPT_PASSTHRU_ARGV(0, \"ignore-whitespace\", &options.git_am_opts,\n-\t\t\t\t  NULL, N_(\"passed to 'git am'\"),\n-\t\t\t\t  PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n \t\t\t\t  &options.git_am_opts, NULL,\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n@@ -1411,6 +1424,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n \t\t\t\t  N_(\"passed to 'git apply'\"), 0),\n+\t\tOPT_BOOL(0, \"ignore-whitespace\", &options.ignore_whitespace,\n+\t\t\t N_(\"ignore changes in whitespace\")),\n \t\tOPT_PASSTHRU_ARGV(0, \"whitespace\", &options.git_am_opts,\n \t\t\t\t  N_(\"action\"), N_(\"passed to 'git apply'\"), 0),\n \t\tOPT_BIT('f', \"force-rebase\", &options.flags,\n@@ -1821,6 +1836,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (options.rebase_merges) {\n+\t\tif (options.ignore_whitespace)\n+\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n+\t\t\t      \"'--ignore-whitespace'\"));\n \t\tif (strategy_options.nr)\n \t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n \t\t\t      \"'--strategy-option'\"));\ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d..303047a13 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -43,6 +43,7 @@ struct replay_opts {\n \tint verbose;\n \tint quiet;\n \tint reschedule_failed_exec;\n+\tint ignore_whitespace;\n \n \tint mainline;\n \ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex a5868ea15..4342f79ee 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -61,7 +61,6 @@ test_rebase_am_only () {\n }\n \n test_rebase_am_only --whitespace=fix\n-test_rebase_am_only --ignore-whitespace\n test_rebase_am_only --committer-date-is-author-date\n test_rebase_am_only -C4\n \ndiff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\nnew file mode 100755\nindex 000000000..f38ae6f5f\n--- /dev/null\n+++ b/t/t3431-rebase-options-compatibility.sh\n@@ -0,0 +1,66 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2019 Rohit Ashiwal\n+#\n+\n+test_description='tests to ensure compatibility between am and interactive backends'\n+\n+. ./test-lib.sh\n+\n+# This is a special case in which both am and interactive backends\n+# provide the same outputs. It was done intentionally because\n+# --ignore-whitespace both the backends fall short of optimal\n+# behaviour.\n+test_expect_success 'setup' '\n+\tgit checkout -b topic &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\tQline 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\tgit commit -am \"update file\" &&\n+\tgit tag side &&\n+\n+\tgit checkout --orphan master &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\t        line 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tgit tag main\n+'\n+\n+test_expect_success '--ignore-whitespace works with am backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_expect_success '--ignore-whitespace works with interactive backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase --merge main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --merge --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_done\n-- \n2.21.0\n\n"},{"id":"378903","messageId":"20190712185357.21211-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH 0/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-12T18:53:55Z","receivedAt":"2019-07-12T18:56:45Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"rebase am already has this flag to \"lie\" about the committer date, i.e., by\nchanging it to the author date. Let's add the same for interactive machinery.\nThis will get us a step closer to the ultimate aim of achieving consistency\nbetween sequencer commands.\n\nNB: To reduce merge conflicts on the reviewer's part, I've based this patch\nseries on my previous patch series[1].\n\n[1]: https://public-inbox.org/git/20190712185015.20585-1-rohit.ashiwal265@gmail.com/\n\nRohit Ashiwal (2):\n  sequencer: add NULL checks under read_author_script\n  rebase -i: support --committer-date-is-author-date\n\n Documentation/git-rebase.txt            |  7 ++-\n builtin/rebase.c                        | 23 +++++++--\n sequencer.c                             | 62 +++++++++++++++++++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 15 ++++++\n 6 files changed, 97 insertions(+), 12 deletions(-)\n\n-- \n2.21.0\n\n"},{"id":"378904","messageId":"20190712185357.21211-2-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH 1/2] sequencer: add NULL checks under read_author_script","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-12T18:53:56Z","receivedAt":"2019-07-12T18:56:48Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"read_author_script reads name, email and author date from the author\nscript. However, it does not check if the arguments are NULL. Adding\nNULL checks will allow us to selectively get the required value, for\nexample:\n\n    char *date;\n    if (read_author_script(_path_, NULL, NULL, &date, _int_))\n\t    die(_(\"failed to read author date\"));\n    /* needs to be free()'d */\n    return date;\n\nAdd NULL checks for better control over the information retrieved.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n sequencer.c | 16 +++++++++++++---\n 1 file changed, 13 insertions(+), 3 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex f88a97fb1..a2d7b0925 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -821,9 +821,19 @@ int read_author_script(const char *path, char **name, char **email, char **date,\n \t\terror(_(\"missing 'GIT_AUTHOR_DATE'\"));\n \tif (date_i < 0 || email_i < 0 || date_i < 0 || err)\n \t\tgoto finish;\n-\t*name = kv.items[name_i].util;\n-\t*email = kv.items[email_i].util;\n-\t*date = kv.items[date_i].util;\n+\n+\tif (name)\n+\t\t*name = kv.items[name_i].util;\n+\telse\n+\t\tfree(kv.items[name_i].util);\n+\tif (email)\n+\t\t*email = kv.items[email_i].util;\n+\telse\n+\t\tfree(kv.items[email_i].util);\n+\tif (date)\n+\t\t*date = kv.items[date_i].util;\n+\telse\n+\t\tfree(kv.items[date_i].util);\n \tretval = 0;\n finish:\n \tstring_list_clear(&kv, !!retval);\n-- \n2.21.0\n\n"},{"id":"378905","messageId":"20190712185357.21211-3-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-12T18:53:57Z","receivedAt":"2019-07-12T18:56:52Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"rebase am already has this flag to \"lie\" about the committer date\nby changing it to the author date. Let's add the same for\ninteractive machinery.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n Documentation/git-rebase.txt            |  7 ++--\n builtin/rebase.c                        | 23 ++++++++++---\n sequencer.c                             | 46 ++++++++++++++++++++++++-\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 15 ++++++++\n 6 files changed, 84 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex eda52ed82..ddd111de6 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -383,8 +383,12 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.\n See also INCOMPATIBLE OPTIONS below.\n \n --committer-date-is-author-date::\n+\tInstead of recording the time the rebased commits are\n+\tcreated as the committer date, reuse the author date\n+\tas the committer date. This implies --force-rebase.\n+\n --ignore-date::\n-\tThese flags are passed to 'git am' to easily change the dates\n+\tThis flag is passed to 'git am' to change the author date\n \tof the rebased commits (see linkgit:git-am[1]).\n +\n See also INCOMPATIBLE OPTIONS below.\n@@ -522,7 +526,6 @@ INCOMPATIBLE OPTIONS\n \n The following options:\n \n- * --committer-date-is-author-date\n  * --ignore-date\n  * --whitespace\n  * -C\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c55957c31..82a3f7743 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -82,6 +82,7 @@ struct rebase_options {\n \tint ignore_whitespace;\n \tchar *gpg_sign_opt;\n \tint autostash;\n+\tint committer_date_is_author_date;\n \tchar *cmd;\n \tint allow_empty_message;\n \tint rebase_merges, rebase_cousins;\n@@ -113,6 +114,8 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treplay.allow_empty_message = opts->allow_empty_message;\n \treplay.verbose = opts->flags & REBASE_VERBOSE;\n \treplay.reschedule_failed_exec = opts->reschedule_failed_exec;\n+\treplay.committer_date_is_author_date =\n+\t\t\t\t\topts->committer_date_is_author_date;\n \treplay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);\n \treplay.strategy = opts->strategy;\n \tif (opts->strategy_opts)\n@@ -467,6 +470,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"autosquash\", &opts.autosquash,\n \t\t\t N_(\"move commits that begin with squash!/fixup!\")),\n \t\tOPT_BOOL(0, \"signoff\", &opts.signoff, N_(\"sign commits\")),\n+\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n+\t\t\t &opts.committer_date_is_author_date,\n+\t\t\t N_(\"make committer date match author date\")),\n \t\tOPT_BIT('v', \"verbose\", &opts.flags,\n \t\t\tN_(\"display a diffstat of what changed upstream\"),\n \t\t\tREBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),\n@@ -532,6 +538,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n \t\t\t  \"--rebase-merges\"));\n \n+\tif (opts.committer_date_is_author_date)\n+\t\topts.flags |= REBASE_FORCE;\n+\n \treturn !!run_rebase_interactive(&opts, command);\n }\n \n@@ -970,6 +979,8 @@ static int run_am(struct rebase_options *opts)\n \n \tif (opts->ignore_whitespace)\n \t\targv_array_push(&am.args, \"--ignore-whitespace\");\n+\tif (opts->committer_date_is_author_date)\n+\t\targv_array_push(&opts->git_am_opts, \"--committer-date-is-author-date\");\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\targv_array_push(&am.args, \"--resolved\");\n \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1417,9 +1428,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n-\t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n-\t\t\t\t  &options.git_am_opts, NULL,\n-\t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n+\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n+\t\t\t &options.committer_date_is_author_date,\n+\t\t\t N_(\"make committer date match author date\")),\n \t\tOPT_PASSTHRU_ARGV(0, \"ignore-date\", &options.git_am_opts, NULL,\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n@@ -1686,10 +1697,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t    state_dir_base, cmd_live_rebase, buf.buf);\n \t}\n \n+\tif (options.committer_date_is_author_date)\n+\t\toptions.flags |= REBASE_FORCE;\n+\n \tfor (i = 0; i < options.git_am_opts.argc; i++) {\n \t\tconst char *option = options.git_am_opts.argv[i], *p;\n-\t\tif (!strcmp(option, \"--committer-date-is-author-date\") ||\n-\t\t    !strcmp(option, \"--ignore-date\") ||\n+\t\tif (!strcmp(option, \"--ignore-date\") ||\n \t\t    !strcmp(option, \"--whitespace=fix\") ||\n \t\t    !strcmp(option, \"--whitespace=strip\"))\n \t\t\toptions.flags |= REBASE_FORCE;\ndiff --git a/sequencer.c b/sequencer.c\nindex a2d7b0925..a65f01a42 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -147,6 +147,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, \"rebase-merge/refs-to-delete\")\n  * command-line.\n  */\n static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, \"rebase-merge/gpg_sign_opt\")\n+static GIT_PATH_FUNC(rebase_path_cdate_is_adate, \"rebase-merge/cdate_is_adate\")\n static GIT_PATH_FUNC(rebase_path_orig_head, \"rebase-merge/orig-head\")\n static GIT_PATH_FUNC(rebase_path_verbose, \"rebase-merge/verbose\")\n static GIT_PATH_FUNC(rebase_path_quiet, \"rebase-merge/quiet\")\n@@ -876,6 +877,18 @@ static char *get_author(const char *message)\n \treturn NULL;\n }\n \n+/* Returns a \"date\" string that needs to be free()'d by the caller */\n+static char *read_author_date_or_die(void)\n+{\n+\tchar *date;\n+\n+\tif (read_author_script(rebase_path_author_script(),\n+\t\t\t       NULL, NULL, &date, 0))\n+\t\tdie(_(\"failed to read author date\"));\n+\n+\treturn date;\n+}\n+\n /* Read author-script and return an ident line (author <email> timestamp) */\n static const char *read_author_ident(struct strbuf *buf)\n {\n@@ -986,10 +999,17 @@ static int run_git_commit(struct repository *r,\n \n \t\tif (res <= 0)\n \t\t\tres = error_errno(_(\"could not read '%s'\"), defmsg);\n-\t\telse\n+\t\telse {\n+\t\t\tif (opts->committer_date_is_author_date) {\n+\t\t\t\tchar *date = read_author_date_or_die();\n+\t\t\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n+\t\t\t\tfree(date);\n+\t\t\t}\n+\n \t\t\tres = commit_tree(msg.buf, msg.len, cache_tree_oid,\n \t\t\t\t\t  NULL, &root_commit, author,\n \t\t\t\t\t  opts->gpg_sign);\n+\t\t}\n \n \t\tstrbuf_release(&msg);\n \t\tstrbuf_release(&script);\n@@ -1019,6 +1039,11 @@ static int run_git_commit(struct repository *r,\n \t\targv_array_push(&cmd.args, \"--amend\");\n \tif (opts->gpg_sign)\n \t\targv_array_pushf(&cmd.args, \"-S%s\", opts->gpg_sign);\n+\tif (opts->committer_date_is_author_date) {\n+\t\tchar *date = read_author_date_or_die();\n+\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n+\t\tfree(date);\n+\t}\n \tif (defmsg)\n \t\targv_array_pushl(&cmd.args, \"-F\", defmsg, NULL);\n \telse if (!(flags & EDIT_MSG))\n@@ -1467,6 +1492,12 @@ static int try_to_commit(struct repository *r,\n \n \treset_ident_date();\n \n+\tif (opts->committer_date_is_author_date) {\n+\t\tchar *date = read_author_date_or_die();\n+\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n+\t\tfree(date);\n+\t}\n+\n \tif (commit_tree_extended(msg->buf, msg->len, &tree, parents,\n \t\t\t\t oid, author, opts->gpg_sign, extra)) {\n \t\tres = error(_(\"failed to write commit object\"));\n@@ -2538,6 +2569,11 @@ static int read_populate_opts(struct replay_opts *opts)\n \t\t\topts->signoff = 1;\n \t\t}\n \n+\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n+\t\t\topts->allow_ff = 0;\n+\t\t\topts->committer_date_is_author_date = 1;\n+\t\t}\n+\n \t\tif (file_exists(rebase_path_reschedule_failed_exec()))\n \t\t\topts->reschedule_failed_exec = 1;\n \n@@ -2620,6 +2656,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n \t\twrite_file(rebase_path_gpg_sign_opt(), \"-S%s\\n\", opts->gpg_sign);\n \tif (opts->signoff)\n \t\twrite_file(rebase_path_signoff(), \"--signoff\\n\");\n+\tif (opts->committer_date_is_author_date)\n+\t\twrite_file(rebase_path_cdate_is_adate(), \"%s\", \"\");\n \tif (opts->reschedule_failed_exec)\n \t\twrite_file(rebase_path_reschedule_failed_exec(), \"%s\", \"\");\n \n@@ -3437,6 +3475,12 @@ static int do_merge(struct repository *r,\n \t\targv_array_push(&cmd.args, git_path_merge_msg(r));\n \t\tif (opts->gpg_sign)\n \t\t\targv_array_push(&cmd.args, opts->gpg_sign);\n+\t\tif (opts->committer_date_is_author_date) {\n+\t\t\tchar *date = read_author_date_or_die();\n+\t\t\targv_array_pushf(&cmd.env_array,\n+\t\t\t\t\t \"GIT_COMMITTER_DATE=%s\", date);\n+\t\t\tfree(date);\n+\t\t}\n \n \t\t/* Add the tips to be merged */\n \t\tfor (j = to_merge; j; j = j->next)\ndiff --git a/sequencer.h b/sequencer.h\nindex 303047a13..0cfe184fc 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -44,6 +44,7 @@ struct replay_opts {\n \tint quiet;\n \tint reschedule_failed_exec;\n \tint ignore_whitespace;\n+\tint committer_date_is_author_date;\n \n \tint mainline;\n \ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex 4342f79ee..7402f7e3d 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -61,7 +61,6 @@ test_rebase_am_only () {\n }\n \n test_rebase_am_only --whitespace=fix\n-test_rebase_am_only --committer-date-is-author-date\n test_rebase_am_only -C4\n \n test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\ndiff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\nindex f38ae6f5f..a06d55dfc 100755\n--- a/t/t3431-rebase-options-compatibility.sh\n+++ b/t/t3431-rebase-options-compatibility.sh\n@@ -7,6 +7,9 @@ test_description='tests to ensure compatibility between am and interactive backe\n \n . ./test-lib.sh\n \n+GIT_AUTHOR_DATE=\"1999-04-02T08:03:20+05:30\"\n+export GIT_AUTHOR_DATE\n+\n # This is a special case in which both am and interactive backends\n # provide the same outputs. It was done intentionally because\n # --ignore-whitespace both the backends fall short of optimal\n@@ -63,4 +66,16 @@ test_expect_success '--ignore-whitespace works with interactive backend' '\n \ttest_cmp expect file\n '\n \n+test_expect_success '--committer-date-is-author-date works with interactive backend' '\n+\tgit rebase -f HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n+\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n+\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n+\t! test_cmp at ct &&\n+\tgit rebase -i --committer-date-is-author-date HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n+\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n+\ttest_cmp authortime committertime\n+'\n+\n test_done\n-- \n2.21.0\n\n"},{"id":"378930","messageId":"20190714113117.11748-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185357.21211-3-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-14T11:31:17Z","receivedAt":"2019-07-14T11:34:05Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"On Sat, 13 Jul 2019 00:23:57 +0530 Rohit Ashiwal <rohit.ashiwal265@gmail.com> wrote:\n>\n> rebase am already has this flag to \"lie\" about the committer date\n> by changing it to the author date. Let's add the same for\n> interactive machinery.\n>\n> Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n> [...]\n>\n> +test_expect_success '--committer-date-is-author-date works with interactive backend' '\n> +\tgit rebase -f HEAD^ &&\n> +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n> +\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n> +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n> +\t! test_cmp at ct &&\n                   ^~~^~~~~\nSlight mistake in changing names, I'll change it after a full review,\nplease ignore till then.\n\n> +\tgit rebase -i --committer-date-is-author-date HEAD^ &&\n> +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n> +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n> +\ttest_cmp authortime committertime\n> +'\n\nWe should also include a test for am backend since the flag is not\ndirectly passed to the am after the application of this patch.\n\n> +\n>  test_done\n> --\n> 2.21.0\n\nBest\nRohit\n\n"},{"id":"378949","messageId":"xmqqlfwz41vl.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190712185015.20585-2-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-15T17:57:18Z","receivedAt":"2019-07-15T17:57:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> +\tif (opts->ignore_whitespace) {\n> +\t\tstruct strbuf buf = STRBUF_INIT;\n> +\n> +\t\tif (opts->strategy_opts)\n> +\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n> +\n> +\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n> +\t\tfree(opts->strategy_opts);\n\nIs this call to free() safe?\n\n> +\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n> +\t}\n> +\n> @@ -1821,6 +1836,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t}\n>  \n>  \tif (options.rebase_merges) {\n> +\t\tif (options.ignore_whitespace)\n> +\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n> +\t\t\t      \"'--ignore-whitespace'\"));\n\nHmph, this is unfortunate.  The patch is not making things worse, though.\n\n\n\n\n"},{"id":"378950","messageId":"xmqqh87n41iv.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190712185357.21211-2-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH 1/2] sequencer: add NULL checks under read_author_script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-15T18:04:56Z","receivedAt":"2019-07-15T18:05:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> +\tif (name)\n> +\t\t*name = kv.items[name_i].util;\n> +\telse\n> +\t\tfree(kv.items[name_i].util);\n> +\tif (email)\n> +\t\t*email = kv.items[email_i].util;\n> +\telse\n> +\t\tfree(kv.items[email_i].util);\n> +\tif (date)\n> +\t\t*date = kv.items[date_i].util;\n> +\telse\n> +\t\tfree(kv.items[date_i].util);\n>  \tretval = 0;\n\nSome of the .util field may have been freed and others may have\ntaken possession by the caller at this point.\n\n>  finish:\n>  \tstring_list_clear(&kv, !!retval);\n\nAnd we tell string_list_clear() not to free the .util field, so\nkv.items[].util won't leak, which is good.\n"},{"id":"378953","messageId":"20190715220010.8146-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"xmqqlfwz41vl.fsf@gitster-ct.c.googlers.com","subject":"Re: [GSoC][PATCH 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-15T22:00:10Z","receivedAt":"2019-07-15T22:02:56Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Junio\n\nOn Mon, 15 Jul 2019 10:57:18 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n> \n> Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n> \n> > +\tif (opts->ignore_whitespace) {\n> > +\t\tstruct strbuf buf = STRBUF_INIT;\n> > +\n> > +\t\tif (opts->strategy_opts)\n> > +\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n> > +\n> > +\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n> > +\t\tfree(opts->strategy_opts);\n> \n> Is this call to free() safe?\n\nYes, as far as I can tell. Since up till now, `strategy_opts` is\neither \"NULL\" or xstrdup()'d string. There is no double free involved.\n\n> > +\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n> > +\t}\n> > +\n> > @@ -1821,6 +1836,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n> >  \t}\n> >\n> >  \tif (options.rebase_merges) {\n> > +\t\tif (options.ignore_whitespace)\n> > +\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n> > +\t\t\t      \"'--ignore-whitespace'\"));\n> \n> Hmph, this is unfortunate.  The patch is not making things worse, though.\n\nActually, there is no need for --rebase-merges and --ignore-whitespace\nto be \"incompatible\". My mentors also agree on this one. Making them\nwork in harmony will be handled in another patch series.\n\nBest\nRohit\n\n"},{"id":"378954","messageId":"xmqqd0ib3q8x.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190715220010.8146-1-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-15T22:08:30Z","receivedAt":"2019-07-15T22:08:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> Hi Junio\n>\n> On Mon, 15 Jul 2019 10:57:18 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n>> \n>> Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n>> \n>> > +\tif (opts->ignore_whitespace) {\n>> > +\t\tstruct strbuf buf = STRBUF_INIT;\n>> > +\n>> > +\t\tif (opts->strategy_opts)\n>> > +\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n>> > +\n>> > +\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n>> > +\t\tfree(opts->strategy_opts);\n>> \n>> Is this call to free() safe?\n>\n> Yes, as far as I can tell. Since up till now, `strategy_opts` is\n> either \"NULL\" or xstrdup()'d string. There is no double free involved.\n\nDoesn't it also come from handling OPT_STRING() via parse_options(),\nwhich gives a pointer from argv[], freeing something that is not\nallocated in the first place?\n\n"},{"id":"378955","messageId":"20190715224217.18556-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"xmqqd0ib3q8x.fsf@gitster-ct.c.googlers.com","subject":"Re: [GSoC][PATCH 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-15T22:42:17Z","receivedAt":"2019-07-15T22:45:02Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Junio\n\nOn Mon, 15 Jul 2019 15:08:30 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Doesn't it also come from handling OPT_STRING() via parse_options(),\n> which gives a pointer from argv[], freeing something that is not\n> allocated in the first place?\n\nAh! The path from cmd_rebase__interactive! A simple workaround could be:\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c55957c31f..afe376c3fe 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -525,6 +525,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n        argc = parse_options(argc, argv, NULL, options,\n                        builtin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n\n+       opts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n+\n        if (!is_null_oid(&squash_onto))\n                opts.squash_onto = &squash_onto;\n\n"},{"id":"379067","messageId":"20190718185514.20108-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v2 0/1] rebase -i: support --ignore-whitespace","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-18T18:55:13Z","receivedAt":"2019-07-18T18:58:24Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Another revision to keep the thread alive.\n\nRohit Ashiwal (1):\n  rebase -i: add --ignore-whitespace flag\n\n Documentation/git-rebase.txt            |  9 +++-\n builtin/rebase.c                        | 26 ++++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 5 files changed, 97 insertions(+), 6 deletions(-)\n create mode 100755 t/t3431-rebase-options-compatibility.sh\n\nRange-diff:\n1:  7dda0de288 ! 1:  a1bb91fe43 rebase -i: add --ignore-whitespace flag\n    @@ -85,6 +85,15 @@\n      \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n      \t\t\t   N_(\"rebase strategy\")),\n      \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n    +@@\n    + \targc = parse_options(argc, argv, NULL, options,\n    + \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n    + \n    ++\topts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n    ++\n    + \tif (!is_null_oid(&squash_onto))\n    + \t\topts.squash_onto = &squash_onto;\n    + \n     @@\n      \tam.git_cmd = 1;\n      \targv_array_push(&am.args, \"am\");\n-- \n2.21.0\n\n"},{"id":"379068","messageId":"20190718185514.20108-2-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190718185514.20108-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-18T18:55:14Z","receivedAt":"2019-07-18T18:58:29Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"There are two backends available for rebasing, viz, the am and the\ninteractive. Naturally, there shall be some features that are\nimplemented in one but not in the other. One such flag is\n--ignore-whitespace which indicates merge mechanism to treat lines\nwith only whitespace changes as unchanged. Wire the interactive\nrebase to also understand the --ignore-whitespace flag by\ntranslating it to -Xignore-space-change.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n Documentation/git-rebase.txt            |  9 +++-\n builtin/rebase.c                        | 26 ++++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 5 files changed, 97 insertions(+), 6 deletions(-)\n create mode 100755 t/t3431-rebase-options-compatibility.sh\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 5e4e927647..eda52ed824 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -371,8 +371,13 @@ If either <upstream> or --root is given on the command line, then the\n default is `--no-fork-point`, otherwise the default is `--fork-point`.\n \n --ignore-whitespace::\n+\tThis flag is either passed to the 'git apply' program\n+\t(see linkgit:git-apply[1]), or to 'git merge' program\n+\t(see linkgit:git-merge[1]) as `-Xignore-space-change`,\n+\tdepending on which backend is selected by other options.\n+\n --whitespace=<option>::\n-\tThese flag are passed to the 'git apply' program\n+\tThis flag is passed to the 'git apply' program\n \t(see linkgit:git-apply[1]) that applies the patch.\n +\n See also INCOMPATIBLE OPTIONS below.\n@@ -520,7 +525,6 @@ The following options:\n  * --committer-date-is-author-date\n  * --ignore-date\n  * --whitespace\n- * --ignore-whitespace\n  * -C\n \n are incompatible with the following options:\n@@ -543,6 +547,7 @@ In addition, the following pairs of options are incompatible:\n  * --preserve-merges and --interactive\n  * --preserve-merges and --signoff\n  * --preserve-merges and --rebase-merges\n+ * --rebase-merges and --ignore-whitespace\n  * --rebase-merges and --strategy\n  * --rebase-merges and --strategy-option\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex db6ca9bd7d..afe376c3fe 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -79,6 +79,7 @@ struct rebase_options {\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n \tint autosquash;\n+\tint ignore_whitespace;\n \tchar *gpg_sign_opt;\n \tint autostash;\n \tchar *cmd;\n@@ -376,6 +377,17 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n \tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n \n+\tif (opts->ignore_whitespace) {\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tif (opts->strategy_opts)\n+\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n+\n+\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n+\t\tfree(opts->strategy_opts);\n+\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n+\t}\n+\n \tswitch (command) {\n \tcase ACTION_NONE: {\n \t\tif (!opts->onto && !opts->upstream)\n@@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n \t\t\tN_(\"GPG-sign commits\"),\n \t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n+\t\tOPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n+\t\t\t N_(\"ignore changes in whitespace\")),\n \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n \t\t\t   N_(\"rebase strategy\")),\n \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n@@ -511,6 +525,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, NULL, options,\n \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n \n+\topts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n+\n \tif (!is_null_oid(&squash_onto))\n \t\topts.squash_onto = &squash_onto;\n \n@@ -954,6 +970,8 @@ static int run_am(struct rebase_options *opts)\n \tam.git_cmd = 1;\n \targv_array_push(&am.args, \"am\");\n \n+\tif (opts->ignore_whitespace)\n+\t\targv_array_push(&am.args, \"--ignore-whitespace\");\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\targv_array_push(&am.args, \"--resolved\");\n \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1401,9 +1419,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n-\t\tOPT_PASSTHRU_ARGV(0, \"ignore-whitespace\", &options.git_am_opts,\n-\t\t\t\t  NULL, N_(\"passed to 'git am'\"),\n-\t\t\t\t  PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n \t\t\t\t  &options.git_am_opts, NULL,\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n@@ -1411,6 +1426,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n \t\t\t\t  N_(\"passed to 'git apply'\"), 0),\n+\t\tOPT_BOOL(0, \"ignore-whitespace\", &options.ignore_whitespace,\n+\t\t\t N_(\"ignore changes in whitespace\")),\n \t\tOPT_PASSTHRU_ARGV(0, \"whitespace\", &options.git_am_opts,\n \t\t\t\t  N_(\"action\"), N_(\"passed to 'git apply'\"), 0),\n \t\tOPT_BIT('f', \"force-rebase\", &options.flags,\n@@ -1821,6 +1838,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (options.rebase_merges) {\n+\t\tif (options.ignore_whitespace)\n+\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n+\t\t\t      \"'--ignore-whitespace'\"));\n \t\tif (strategy_options.nr)\n \t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n \t\t\t      \"'--strategy-option'\"));\ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d4..303047a133 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -43,6 +43,7 @@ struct replay_opts {\n \tint verbose;\n \tint quiet;\n \tint reschedule_failed_exec;\n+\tint ignore_whitespace;\n \n \tint mainline;\n \ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex a5868ea152..4342f79eea 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -61,7 +61,6 @@ test_rebase_am_only () {\n }\n \n test_rebase_am_only --whitespace=fix\n-test_rebase_am_only --ignore-whitespace\n test_rebase_am_only --committer-date-is-author-date\n test_rebase_am_only -C4\n \ndiff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\nnew file mode 100755\nindex 0000000000..f38ae6f5fc\n--- /dev/null\n+++ b/t/t3431-rebase-options-compatibility.sh\n@@ -0,0 +1,66 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2019 Rohit Ashiwal\n+#\n+\n+test_description='tests to ensure compatibility between am and interactive backends'\n+\n+. ./test-lib.sh\n+\n+# This is a special case in which both am and interactive backends\n+# provide the same outputs. It was done intentionally because\n+# --ignore-whitespace both the backends fall short of optimal\n+# behaviour.\n+test_expect_success 'setup' '\n+\tgit checkout -b topic &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\tQline 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\tgit commit -am \"update file\" &&\n+\tgit tag side &&\n+\n+\tgit checkout --orphan master &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\t        line 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tgit tag main\n+'\n+\n+test_expect_success '--ignore-whitespace works with am backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_expect_success '--ignore-whitespace works with interactive backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase --merge main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --merge --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_done\n-- \n2.21.0\n\n"},{"id":"379069","messageId":"20190718190314.20549-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185357.21211-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v2 0/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-18T19:03:12Z","receivedAt":"2019-07-18T19:06:06Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Another revision to keep this thread alive.\n\nRohit Ashiwal (2):\n  sequencer: add NULL checks under read_author_script\n  rebase -i: support --committer-date-is-author-date\n\n Documentation/git-rebase.txt            |  7 ++-\n builtin/rebase.c                        | 23 +++++++--\n sequencer.c                             | 62 +++++++++++++++++++++++--\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 21 +++++++++\n 6 files changed, 103 insertions(+), 12 deletions(-)\n\nRange-diff:\n1:  6d2a5a382d ! 1:  a1bb91fe43 rebase -i: add --ignore-whitespace flag\n    @@ -85,6 +85,15 @@\n      \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n      \t\t\t   N_(\"rebase strategy\")),\n      \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n    +@@\n    + \targc = parse_options(argc, argv, NULL, options,\n    + \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n    + \n    ++\topts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n    ++\n    + \tif (!is_null_oid(&squash_onto))\n    + \t\topts.squash_onto = &squash_onto;\n    + \n     @@\n      \tam.git_cmd = 1;\n      \targv_array_push(&am.args, \"am\");\n2:  3e6a67410c = 2:  597d282fa6 sequencer: add NULL checks under read_author_script\n3:  3d5f2e2960 ! 3:  33cfc0f890 rebase -i: support --committer-date-is-author-date\n    @@ -262,14 +262,20 @@\n      \ttest_cmp expect file\n      '\n      \n    -+test_expect_success '--committer-date-is-author-date works with interactive backend' '\n    ++test_expect_success '--committer-date-is-author-date works with am backend' '\n\n    It is implied that --force-rebase will change the committer date.\n    We can add a test (somewhere else) that will check so, but that will\n    be moot IMO.\n\n     +\tgit rebase -f HEAD^ &&\n    ++\tgit rebase --committer-date-is-author-date HEAD^ &&\n     +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n     +\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n     +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n    -+\t! test_cmp at ct &&\n    ++\ttest_cmp authortime committertime\n    ++'\n    ++\n    ++test_expect_success '--committer-date-is-author-date works with interactive backend' '\n    ++\tgit rebase -f HEAD^ &&\n     +\tgit rebase -i --committer-date-is-author-date HEAD^ &&\n     +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n    ++\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n     +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n     +\ttest_cmp authortime committertime\n     +'\n-- \n2.21.0\n\n"},{"id":"379070","messageId":"20190718190314.20549-2-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190718190314.20549-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v2 1/2] sequencer: add NULL checks under read_author_script","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-18T19:03:13Z","receivedAt":"2019-07-18T19:06:10Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"read_author_script reads name, email and author date from the author\nscript. However, it does not check if the arguments are NULL. Adding\nNULL checks will allow us to selectively get the required value, for\nexample:\n\n    char *date;\n    if (read_author_script(_path_, NULL, NULL, &date, _int_))\n\t    die(_(\"failed to read author date\"));\n    /* needs to be free()'d */\n    return date;\n\nAdd NULL checks for better control over the information retrieved.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n sequencer.c | 16 +++++++++++++---\n 1 file changed, 13 insertions(+), 3 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex f88a97fb10..a2d7b0925e 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -821,9 +821,19 @@ int read_author_script(const char *path, char **name, char **email, char **date,\n \t\terror(_(\"missing 'GIT_AUTHOR_DATE'\"));\n \tif (date_i < 0 || email_i < 0 || date_i < 0 || err)\n \t\tgoto finish;\n-\t*name = kv.items[name_i].util;\n-\t*email = kv.items[email_i].util;\n-\t*date = kv.items[date_i].util;\n+\n+\tif (name)\n+\t\t*name = kv.items[name_i].util;\n+\telse\n+\t\tfree(kv.items[name_i].util);\n+\tif (email)\n+\t\t*email = kv.items[email_i].util;\n+\telse\n+\t\tfree(kv.items[email_i].util);\n+\tif (date)\n+\t\t*date = kv.items[date_i].util;\n+\telse\n+\t\tfree(kv.items[date_i].util);\n \tretval = 0;\n finish:\n \tstring_list_clear(&kv, !!retval);\n-- \n2.21.0\n\n"},{"id":"379071","messageId":"20190718190314.20549-3-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190718190314.20549-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-18T19:03:14Z","receivedAt":"2019-07-18T19:06:15Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"rebase am already has this flag to \"lie\" about the committer date\nby changing it to the author date. Let's add the same for\ninteractive machinery.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n Documentation/git-rebase.txt            |  7 ++--\n builtin/rebase.c                        | 23 ++++++++++---\n sequencer.c                             | 46 ++++++++++++++++++++++++-\n sequencer.h                             |  1 +\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3431-rebase-options-compatibility.sh | 21 +++++++++++\n 6 files changed, 90 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex eda52ed824..ddd111de69 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -383,8 +383,12 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.\n See also INCOMPATIBLE OPTIONS below.\n \n --committer-date-is-author-date::\n+\tInstead of recording the time the rebased commits are\n+\tcreated as the committer date, reuse the author date\n+\tas the committer date. This implies --force-rebase.\n+\n --ignore-date::\n-\tThese flags are passed to 'git am' to easily change the dates\n+\tThis flag is passed to 'git am' to change the author date\n \tof the rebased commits (see linkgit:git-am[1]).\n +\n See also INCOMPATIBLE OPTIONS below.\n@@ -522,7 +526,6 @@ INCOMPATIBLE OPTIONS\n \n The following options:\n \n- * --committer-date-is-author-date\n  * --ignore-date\n  * --whitespace\n  * -C\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex afe376c3fe..c317fbe53c 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -82,6 +82,7 @@ struct rebase_options {\n \tint ignore_whitespace;\n \tchar *gpg_sign_opt;\n \tint autostash;\n+\tint committer_date_is_author_date;\n \tchar *cmd;\n \tint allow_empty_message;\n \tint rebase_merges, rebase_cousins;\n@@ -113,6 +114,8 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treplay.allow_empty_message = opts->allow_empty_message;\n \treplay.verbose = opts->flags & REBASE_VERBOSE;\n \treplay.reschedule_failed_exec = opts->reschedule_failed_exec;\n+\treplay.committer_date_is_author_date =\n+\t\t\t\t\topts->committer_date_is_author_date;\n \treplay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);\n \treplay.strategy = opts->strategy;\n \tif (opts->strategy_opts)\n@@ -467,6 +470,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"autosquash\", &opts.autosquash,\n \t\t\t N_(\"move commits that begin with squash!/fixup!\")),\n \t\tOPT_BOOL(0, \"signoff\", &opts.signoff, N_(\"sign commits\")),\n+\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n+\t\t\t &opts.committer_date_is_author_date,\n+\t\t\t N_(\"make committer date match author date\")),\n \t\tOPT_BIT('v', \"verbose\", &opts.flags,\n \t\t\tN_(\"display a diffstat of what changed upstream\"),\n \t\t\tREBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),\n@@ -534,6 +540,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n \t\t\t  \"--rebase-merges\"));\n \n+\tif (opts.committer_date_is_author_date)\n+\t\topts.flags |= REBASE_FORCE;\n+\n \treturn !!run_rebase_interactive(&opts, command);\n }\n \n@@ -972,6 +981,8 @@ static int run_am(struct rebase_options *opts)\n \n \tif (opts->ignore_whitespace)\n \t\targv_array_push(&am.args, \"--ignore-whitespace\");\n+\tif (opts->committer_date_is_author_date)\n+\t\targv_array_push(&opts->git_am_opts, \"--committer-date-is-author-date\");\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\targv_array_push(&am.args, \"--resolved\");\n \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1419,9 +1430,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n-\t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n-\t\t\t\t  &options.git_am_opts, NULL,\n-\t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n+\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n+\t\t\t &options.committer_date_is_author_date,\n+\t\t\t N_(\"make committer date match author date\")),\n \t\tOPT_PASSTHRU_ARGV(0, \"ignore-date\", &options.git_am_opts, NULL,\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n@@ -1688,10 +1699,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t    state_dir_base, cmd_live_rebase, buf.buf);\n \t}\n \n+\tif (options.committer_date_is_author_date)\n+\t\toptions.flags |= REBASE_FORCE;\n+\n \tfor (i = 0; i < options.git_am_opts.argc; i++) {\n \t\tconst char *option = options.git_am_opts.argv[i], *p;\n-\t\tif (!strcmp(option, \"--committer-date-is-author-date\") ||\n-\t\t    !strcmp(option, \"--ignore-date\") ||\n+\t\tif (!strcmp(option, \"--ignore-date\") ||\n \t\t    !strcmp(option, \"--whitespace=fix\") ||\n \t\t    !strcmp(option, \"--whitespace=strip\"))\n \t\t\toptions.flags |= REBASE_FORCE;\ndiff --git a/sequencer.c b/sequencer.c\nindex a2d7b0925e..a65f01a422 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -147,6 +147,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, \"rebase-merge/refs-to-delete\")\n  * command-line.\n  */\n static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, \"rebase-merge/gpg_sign_opt\")\n+static GIT_PATH_FUNC(rebase_path_cdate_is_adate, \"rebase-merge/cdate_is_adate\")\n static GIT_PATH_FUNC(rebase_path_orig_head, \"rebase-merge/orig-head\")\n static GIT_PATH_FUNC(rebase_path_verbose, \"rebase-merge/verbose\")\n static GIT_PATH_FUNC(rebase_path_quiet, \"rebase-merge/quiet\")\n@@ -876,6 +877,18 @@ static char *get_author(const char *message)\n \treturn NULL;\n }\n \n+/* Returns a \"date\" string that needs to be free()'d by the caller */\n+static char *read_author_date_or_die(void)\n+{\n+\tchar *date;\n+\n+\tif (read_author_script(rebase_path_author_script(),\n+\t\t\t       NULL, NULL, &date, 0))\n+\t\tdie(_(\"failed to read author date\"));\n+\n+\treturn date;\n+}\n+\n /* Read author-script and return an ident line (author <email> timestamp) */\n static const char *read_author_ident(struct strbuf *buf)\n {\n@@ -986,10 +999,17 @@ static int run_git_commit(struct repository *r,\n \n \t\tif (res <= 0)\n \t\t\tres = error_errno(_(\"could not read '%s'\"), defmsg);\n-\t\telse\n+\t\telse {\n+\t\t\tif (opts->committer_date_is_author_date) {\n+\t\t\t\tchar *date = read_author_date_or_die();\n+\t\t\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n+\t\t\t\tfree(date);\n+\t\t\t}\n+\n \t\t\tres = commit_tree(msg.buf, msg.len, cache_tree_oid,\n \t\t\t\t\t  NULL, &root_commit, author,\n \t\t\t\t\t  opts->gpg_sign);\n+\t\t}\n \n \t\tstrbuf_release(&msg);\n \t\tstrbuf_release(&script);\n@@ -1019,6 +1039,11 @@ static int run_git_commit(struct repository *r,\n \t\targv_array_push(&cmd.args, \"--amend\");\n \tif (opts->gpg_sign)\n \t\targv_array_pushf(&cmd.args, \"-S%s\", opts->gpg_sign);\n+\tif (opts->committer_date_is_author_date) {\n+\t\tchar *date = read_author_date_or_die();\n+\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n+\t\tfree(date);\n+\t}\n \tif (defmsg)\n \t\targv_array_pushl(&cmd.args, \"-F\", defmsg, NULL);\n \telse if (!(flags & EDIT_MSG))\n@@ -1467,6 +1492,12 @@ static int try_to_commit(struct repository *r,\n \n \treset_ident_date();\n \n+\tif (opts->committer_date_is_author_date) {\n+\t\tchar *date = read_author_date_or_die();\n+\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n+\t\tfree(date);\n+\t}\n+\n \tif (commit_tree_extended(msg->buf, msg->len, &tree, parents,\n \t\t\t\t oid, author, opts->gpg_sign, extra)) {\n \t\tres = error(_(\"failed to write commit object\"));\n@@ -2538,6 +2569,11 @@ static int read_populate_opts(struct replay_opts *opts)\n \t\t\topts->signoff = 1;\n \t\t}\n \n+\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n+\t\t\topts->allow_ff = 0;\n+\t\t\topts->committer_date_is_author_date = 1;\n+\t\t}\n+\n \t\tif (file_exists(rebase_path_reschedule_failed_exec()))\n \t\t\topts->reschedule_failed_exec = 1;\n \n@@ -2620,6 +2656,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n \t\twrite_file(rebase_path_gpg_sign_opt(), \"-S%s\\n\", opts->gpg_sign);\n \tif (opts->signoff)\n \t\twrite_file(rebase_path_signoff(), \"--signoff\\n\");\n+\tif (opts->committer_date_is_author_date)\n+\t\twrite_file(rebase_path_cdate_is_adate(), \"%s\", \"\");\n \tif (opts->reschedule_failed_exec)\n \t\twrite_file(rebase_path_reschedule_failed_exec(), \"%s\", \"\");\n \n@@ -3437,6 +3475,12 @@ static int do_merge(struct repository *r,\n \t\targv_array_push(&cmd.args, git_path_merge_msg(r));\n \t\tif (opts->gpg_sign)\n \t\t\targv_array_push(&cmd.args, opts->gpg_sign);\n+\t\tif (opts->committer_date_is_author_date) {\n+\t\t\tchar *date = read_author_date_or_die();\n+\t\t\targv_array_pushf(&cmd.env_array,\n+\t\t\t\t\t \"GIT_COMMITTER_DATE=%s\", date);\n+\t\t\tfree(date);\n+\t\t}\n \n \t\t/* Add the tips to be merged */\n \t\tfor (j = to_merge; j; j = j->next)\ndiff --git a/sequencer.h b/sequencer.h\nindex 303047a133..0cfe184fc2 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -44,6 +44,7 @@ struct replay_opts {\n \tint quiet;\n \tint reschedule_failed_exec;\n \tint ignore_whitespace;\n+\tint committer_date_is_author_date;\n \n \tint mainline;\n \ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex 4342f79eea..7402f7e3da 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -61,7 +61,6 @@ test_rebase_am_only () {\n }\n \n test_rebase_am_only --whitespace=fix\n-test_rebase_am_only --committer-date-is-author-date\n test_rebase_am_only -C4\n \n test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\ndiff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\nindex f38ae6f5fc..c3f7f6d5d0 100755\n--- a/t/t3431-rebase-options-compatibility.sh\n+++ b/t/t3431-rebase-options-compatibility.sh\n@@ -7,6 +7,9 @@ test_description='tests to ensure compatibility between am and interactive backe\n \n . ./test-lib.sh\n \n+GIT_AUTHOR_DATE=\"1999-04-02T08:03:20+05:30\"\n+export GIT_AUTHOR_DATE\n+\n # This is a special case in which both am and interactive backends\n # provide the same outputs. It was done intentionally because\n # --ignore-whitespace both the backends fall short of optimal\n@@ -63,4 +66,22 @@ test_expect_success '--ignore-whitespace works with interactive backend' '\n \ttest_cmp expect file\n '\n \n+test_expect_success '--committer-date-is-author-date works with am backend' '\n+\tgit rebase -f HEAD^ &&\n+\tgit rebase --committer-date-is-author-date HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n+\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n+\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n+\ttest_cmp authortime committertime\n+'\n+\n+test_expect_success '--committer-date-is-author-date works with interactive backend' '\n+\tgit rebase -f HEAD^ &&\n+\tgit rebase -i --committer-date-is-author-date HEAD^ &&\n+\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n+\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n+\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n+\ttest_cmp authortime committertime\n+'\n+\n test_done\n-- \n2.21.0\n\n"},{"id":"379118","messageId":"xmqqa7d9vhq0.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190718190314.20549-1-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 0/2] rebase -i: support --committer-date-is-author-date","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-19T21:26:31Z","receivedAt":"2019-07-19T21:26:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> Another revision to keep this thread alive.\n\nAnd on top of what commit have these two been built on?\n"},{"id":"379119","messageId":"xmqq5znxvhdu.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190718185514.20108-2-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-19T21:33:49Z","receivedAt":"2019-07-19T21:33:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n>  t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n\nIsn't 3431 already taken?\n\n>  5 files changed, 97 insertions(+), 6 deletions(-)\n>  create mode 100755 t/t3431-rebase-options-compatibility.sh\n> ...\n> +\tgit checkout --orphan master &&\n> +\tq_to_tab >file <<-EOF &&\n> +\tline 1\n> +\t        line 2\n> +\tline 3\n> +\tEOF\n\nThis will trigger \"indent-with-space\".  Instead of using q-to-tab,\nperhaps something like this would be more appropriate (not limited\nto this piece, but also other ones in this script that actually do\nuse Q to visualize a tab)?\n\n\tsed -e \"s/^|//\" >file <<-EOF &&\n\t|line 1\n\t|        line 2\n\t|line 3\n\tEOF\n\n"},{"id":"379120","messageId":"xmqq1rylvgqr.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"xmqqa7d9vhq0.fsf@gitster-ct.c.googlers.com","subject":"Re: [GSoC][PATCH v2 0/2] rebase -i: support --committer-date-is-author-date","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-19T21:47:40Z","receivedAt":"2019-07-19T21:47:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n>\n>> Another revision to keep this thread alive.\n>\n> And on top of what commit have these two been built on?\n\nI had trouble figuring out where to base the other one, on top of\nwhich these two apply.  Why are these split into separate topics?\n"},{"id":"379128","messageId":"xmqqwogdtzxc.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190718190314.20549-3-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-19T22:36:15Z","receivedAt":"2019-07-19T22:36:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> @@ -1688,10 +1699,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t\t    state_dir_base, cmd_live_rebase, buf.buf);\n>  \t}\n>  \n> +\tif (options.committer_date_is_author_date)\n> +\t\toptions.flags |= REBASE_FORCE;\n> +\n>  \tfor (i = 0; i < options.git_am_opts.argc; i++) {\n>  \t\tconst char *option = options.git_am_opts.argv[i], *p;\n> -\t\tif (!strcmp(option, \"--committer-date-is-author-date\") ||\n> -\t\t    !strcmp(option, \"--ignore-date\") ||\n> +\t\tif (!strcmp(option, \"--ignore-date\") ||\n>  \t\t    !strcmp(option, \"--whitespace=fix\") ||\n>  \t\t    !strcmp(option, \"--whitespace=strip\"))\n>  \t\t\toptions.flags |= REBASE_FORCE;\n\nThis is needed here, because am-opts no longer has the\ncommitter-date-is-author-date passed through with the\nparse_options() call in cmd_rebase(), which makes sense.\n\n> diff --git a/sequencer.c b/sequencer.c\n> index a2d7b0925e..a65f01a422 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -986,10 +999,17 @@ static int run_git_commit(struct repository *r,\n>  \n>  \t\tif (res <= 0)\n>  \t\t\tres = error_errno(_(\"could not read '%s'\"), defmsg);\n> -\t\telse\n> +\t\telse {\n> +\t\t\tif (opts->committer_date_is_author_date) {\n> +\t\t\t\tchar *date = read_author_date_or_die();\n> +\t\t\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n> +\t\t\t\tfree(date);\n> +\t\t\t}\n\nHmph, are we sure that author-script is always available at this\npoint so that a call to read_author_date_or_die() is safe?  There\nare three callers to the run_git_commit() function and I am not sure\nif codepaths that reach all of them prepared the input to the\nread_author_script() helper.\n\n> @@ -1019,6 +1039,11 @@ static int run_git_commit(struct repository *r,\n>  \t\targv_array_push(&cmd.args, \"--amend\");\n>  \tif (opts->gpg_sign)\n>  \t\targv_array_pushf(&cmd.args, \"-S%s\", opts->gpg_sign);\n> +\tif (opts->committer_date_is_author_date) {\n> +\t\tchar *date = read_author_date_or_die();\n> +\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n> +\t\tfree(date);\n> +\t}\n>  \tif (defmsg)\n>  \t\targv_array_pushl(&cmd.args, \"-F\", defmsg, NULL);\n>  \telse if (!(flags & EDIT_MSG))\n> @@ -1467,6 +1492,12 @@ static int try_to_commit(struct repository *r,\n>  \n>  \treset_ident_date();\n>  \n> +\tif (opts->committer_date_is_author_date) {\n> +\t\tchar *date = read_author_date_or_die();\n> +\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n> +\t\tfree(date);\n> +\t}\n> +\n\nIn the same function, we seem to be grabbing the author ident by\ncalling get_author(message), where the message is an in-core copy of\na commit object, which suggests me that we may not necessarily be\nworking with the on-disk information read_author_date_or_die() is\nprepared to deal with.  Are we sure we have the needed information\non disk so that read_author_date_or_die() will read the correct\ninformation from the disk?\n\n> @@ -2538,6 +2569,11 @@ static int read_populate_opts(struct replay_opts *opts)\n>  \t\t\topts->signoff = 1;\n>  \t\t}\n>  \n> +\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n> +\t\t\topts->allow_ff = 0;\n> +\t\t\topts->committer_date_is_author_date = 1;\n> +\t\t}\n> +\n>  \t\tif (file_exists(rebase_path_reschedule_failed_exec()))\n>  \t\t\topts->reschedule_failed_exec = 1;\n>  \n> @@ -2620,6 +2656,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n>  \t\twrite_file(rebase_path_gpg_sign_opt(), \"-S%s\\n\", opts->gpg_sign);\n>  \tif (opts->signoff)\n>  \t\twrite_file(rebase_path_signoff(), \"--signoff\\n\");\n> +\tif (opts->committer_date_is_author_date)\n> +\t\twrite_file(rebase_path_cdate_is_adate(), \"%s\", \"\");\n>  \tif (opts->reschedule_failed_exec)\n>  \t\twrite_file(rebase_path_reschedule_failed_exec(), \"%s\", \"\");\n\nThese two are propagating the option across rebase invocations, and\nthey should be correct (as correct as how correctly other options\nare propagated ;-)).\n\n> @@ -3437,6 +3475,12 @@ static int do_merge(struct repository *r,\n>  \t\targv_array_push(&cmd.args, git_path_merge_msg(r));\n>  \t\tif (opts->gpg_sign)\n>  \t\t\targv_array_push(&cmd.args, opts->gpg_sign);\n> +\t\tif (opts->committer_date_is_author_date) {\n> +\t\t\tchar *date = read_author_date_or_die();\n> +\t\t\targv_array_pushf(&cmd.env_array,\n> +\t\t\t\t\t \"GIT_COMMITTER_DATE=%s\", date);\n> +\t\t\tfree(date);\n\nThis codepath does have read_env_script() which reads from the\nauthor script an earlier call to write_author_script() would have\nleft on disk (at least when do_merge() is called with 'commit'\nargument, anyway), so we should be able to read from it (or the\nexisting code is already buggy---and this patch just makes it\nslightly worse by depending on a wrong assumption even more).  OK.\n\n"},{"id":"379135","messageId":"7f53b294-57f7-77bf-ca0a-e9621227377c@gmail.com","threadId":"51475","inReplyTo":"20190718190314.20549-3-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2019-07-20T14:56:50Z","receivedAt":"2019-07-20T14:56:57Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Rohit\n\nIt's good to see this patch reducing the differences between the rebase \nbackends.\n\nOn 18/07/2019 20:03, Rohit Ashiwal wrote:\n> rebase am already has this flag to \"lie\" about the committer date\n> by changing it to the author date. Let's add the same for\n> interactive machinery.\n> \n> Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n> ---\n>   Documentation/git-rebase.txt            |  7 ++--\n>   builtin/rebase.c                        | 23 ++++++++++---\n>   sequencer.c                             | 46 ++++++++++++++++++++++++-\n>   sequencer.h                             |  1 +\n>   t/t3422-rebase-incompatible-options.sh  |  1 -\n>   t/t3431-rebase-options-compatibility.sh | 21 +++++++++++\n>   6 files changed, 90 insertions(+), 9 deletions(-)\n> \n> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\n> index eda52ed824..ddd111de69 100644\n> --- a/Documentation/git-rebase.txt\n> +++ b/Documentation/git-rebase.txt\n> @@ -383,8 +383,12 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.\n>   See also INCOMPATIBLE OPTIONS below.\n>   \n>   --committer-date-is-author-date::\n> +\tInstead of recording the time the rebased commits are\n> +\tcreated as the committer date, reuse the author date\n> +\tas the committer date. This implies --force-rebase.\n> +\n>   --ignore-date::\n> -\tThese flags are passed to 'git am' to easily change the dates\n> +\tThis flag is passed to 'git am' to change the author date\n>   \tof the rebased commits (see linkgit:git-am[1]).\n>   +\n>   See also INCOMPATIBLE OPTIONS below.\n> @@ -522,7 +526,6 @@ INCOMPATIBLE OPTIONS\n>   \n>   The following options:\n>   \n> - * --committer-date-is-author-date\n>    * --ignore-date\n>    * --whitespace\n>    * -C\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index afe376c3fe..c317fbe53c 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -82,6 +82,7 @@ struct rebase_options {\n>   \tint ignore_whitespace;\n>   \tchar *gpg_sign_opt;\n>   \tint autostash;\n> +\tint committer_date_is_author_date;\n>   \tchar *cmd;\n>   \tint allow_empty_message;\n>   \tint rebase_merges, rebase_cousins;\n> @@ -113,6 +114,8 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n>   \treplay.allow_empty_message = opts->allow_empty_message;\n>   \treplay.verbose = opts->flags & REBASE_VERBOSE;\n>   \treplay.reschedule_failed_exec = opts->reschedule_failed_exec;\n> +\treplay.committer_date_is_author_date =\n> +\t\t\t\t\topts->committer_date_is_author_date;\n>   \treplay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);\n>   \treplay.strategy = opts->strategy;\n>   \tif (opts->strategy_opts)\n> @@ -467,6 +470,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>   \t\tOPT_BOOL(0, \"autosquash\", &opts.autosquash,\n>   \t\t\t N_(\"move commits that begin with squash!/fixup!\")),\n>   \t\tOPT_BOOL(0, \"signoff\", &opts.signoff, N_(\"sign commits\")),\n> +\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n> +\t\t\t &opts.committer_date_is_author_date,\n> +\t\t\t N_(\"make committer date match author date\")),\n\nI guess it's good to do this for completeness but does \nrebase--preserver-merges.sh support --committer-date-is-author-date? It \nis the only caller of rebase--interactive I think so would be the only \nuser of this code.\n\n>   \t\tOPT_BIT('v', \"verbose\", &opts.flags,\n>   \t\t\tN_(\"display a diffstat of what changed upstream\"),\n>   \t\t\tREBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),\n> @@ -534,6 +540,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>   \t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n>   \t\t\t  \"--rebase-merges\"));\n>   \n> +\tif (opts.committer_date_is_author_date)\n> +\t\topts.flags |= REBASE_FORCE;\n> +\n>   \treturn !!run_rebase_interactive(&opts, command);\n>   }\n>   \n> @@ -972,6 +981,8 @@ static int run_am(struct rebase_options *opts)\n>   \n>   \tif (opts->ignore_whitespace)\n>   \t\targv_array_push(&am.args, \"--ignore-whitespace\");\n> +\tif (opts->committer_date_is_author_date)\n> +\t\targv_array_push(&opts->git_am_opts, \"--committer-date-is-author-date\");\n>   \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n>   \t\targv_array_push(&am.args, \"--resolved\");\n>   \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n> @@ -1419,9 +1430,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n>   \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n>   \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n> -\t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n> -\t\t\t\t  &options.git_am_opts, NULL,\n> -\t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n> +\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n> +\t\t\t &options.committer_date_is_author_date,\n> +\t\t\t N_(\"make committer date match author date\")),\n>   \t\tOPT_PASSTHRU_ARGV(0, \"ignore-date\", &options.git_am_opts, NULL,\n>   \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n>   \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n> @@ -1688,10 +1699,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\t    state_dir_base, cmd_live_rebase, buf.buf);\n>   \t}\n>   \n> +\tif (options.committer_date_is_author_date)\n> +\t\toptions.flags |= REBASE_FORCE;\n> +\n>   \tfor (i = 0; i < options.git_am_opts.argc; i++) {\n>   \t\tconst char *option = options.git_am_opts.argv[i], *p;\n> -\t\tif (!strcmp(option, \"--committer-date-is-author-date\") ||\n> -\t\t    !strcmp(option, \"--ignore-date\") ||\n> +\t\tif (!strcmp(option, \"--ignore-date\") ||\n>   \t\t    !strcmp(option, \"--whitespace=fix\") ||\n>   \t\t    !strcmp(option, \"--whitespace=strip\"))\n>   \t\t\toptions.flags |= REBASE_FORCE;\n> diff --git a/sequencer.c b/sequencer.c\n> index a2d7b0925e..a65f01a422 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -147,6 +147,7 @@ static GIT_PATH_FUNC(rebase_path_refs_to_delete, \"rebase-merge/refs-to-delete\")\n>    * command-line.\n>    */\n>   static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, \"rebase-merge/gpg_sign_opt\")\n> +static GIT_PATH_FUNC(rebase_path_cdate_is_adate, \"rebase-merge/cdate_is_adate\")\n>   static GIT_PATH_FUNC(rebase_path_orig_head, \"rebase-merge/orig-head\")\n>   static GIT_PATH_FUNC(rebase_path_verbose, \"rebase-merge/verbose\")\n>   static GIT_PATH_FUNC(rebase_path_quiet, \"rebase-merge/quiet\")\n> @@ -876,6 +877,18 @@ static char *get_author(const char *message)\n>   \treturn NULL;\n>   }\n>   \n> +/* Returns a \"date\" string that needs to be free()'d by the caller */\n> +static char *read_author_date_or_die(void)\n> +{\n> +\tchar *date;\n> +\n> +\tif (read_author_script(rebase_path_author_script(),\n> +\t\t\t       NULL, NULL, &date, 0))\n> +\t\tdie(_(\"failed to read author date\"));\n\nCan we have this return an error please - we try quite hard in the \nsequencer not to die in library code.\n\n> +\n> +\treturn date;\n> +}\n> +\n>   /* Read author-script and return an ident line (author <email> timestamp) */\n>   static const char *read_author_ident(struct strbuf *buf)\n>   {\n> @@ -986,10 +999,17 @@ static int run_git_commit(struct repository *r,\n>   \n>   \t\tif (res <= 0)\n>   \t\t\tres = error_errno(_(\"could not read '%s'\"), defmsg);\n> -\t\telse\n> +\t\telse {\n> +\t\t\tif (opts->committer_date_is_author_date) {\n> +\t\t\t\tchar *date = read_author_date_or_die();\n> +\t\t\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n> +\t\t\t\tfree(date);\n> +\t\t\t}\n> +\n>   \t\t\tres = commit_tree(msg.buf, msg.len, cache_tree_oid,\n>   \t\t\t\t\t  NULL, &root_commit, author,\n>   \t\t\t\t\t  opts->gpg_sign);\n> +\t\t}\n>   \n>   \t\tstrbuf_release(&msg);\n>   \t\tstrbuf_release(&script);\n> @@ -1019,6 +1039,11 @@ static int run_git_commit(struct repository *r,\n>   \t\targv_array_push(&cmd.args, \"--amend\");\n>   \tif (opts->gpg_sign)\n>   \t\targv_array_pushf(&cmd.args, \"-S%s\", opts->gpg_sign);\n> +\tif (opts->committer_date_is_author_date) {\n> +\t\tchar *date = read_author_date_or_die();\n> +\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n> +\t\tfree(date);\n> +\t}\n\nIt's a shame to be doing this twice is slightly different ways in the \nsame function (and again in try_to_commit() but I don't think that can \nbe avoided as not all callers of run_git_commit() go through \ntry_to_commit()). As I think the child inherits the current environment \nmodified by cmd.env_array we could just call setenv() at the top of the \nfunction. It would be worth looking to see if it would be simpler to do \nthe setenv() call in the loop that picks the commits, then we would \navoid having to do it in do_merge() and try_to_commit() separately.\n\n>   \tif (defmsg)\n>   \t\targv_array_pushl(&cmd.args, \"-F\", defmsg, NULL);\n>   \telse if (!(flags & EDIT_MSG))\n> @@ -1467,6 +1492,12 @@ static int try_to_commit(struct repository *r,\n>   \n>   \treset_ident_date();\n>   \n> +\tif (opts->committer_date_is_author_date) {\n> +\t\tchar *date = read_author_date_or_die();\n> +\t\tsetenv(\"GIT_COMMITTER_DATE\", date, 1);\n> +\t\tfree(date);\n> +\t}\n> +\n>   \tif (commit_tree_extended(msg->buf, msg->len, &tree, parents,\n>   \t\t\t\t oid, author, opts->gpg_sign, extra)) {\n>   \t\tres = error(_(\"failed to write commit object\"));\n> @@ -2538,6 +2569,11 @@ static int read_populate_opts(struct replay_opts *opts)\n>   \t\t\topts->signoff = 1;\n>   \t\t}\n>   \n> +\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n> +\t\t\topts->allow_ff = 0;\n\nThis is safe as we don't save the state of allow_ff for rebases so it \nwont be overridden later. It would be an idea to add to the checks in \nthe assert() at the beginning of pick_commits() no we have another \noption that implies --force-rebase.\n\nBest Wishes\n\nPhillip\n\n> +\t\t\topts->committer_date_is_author_date = 1;\n> +\t\t}\n> +\n>   \t\tif (file_exists(rebase_path_reschedule_failed_exec()))\n>   \t\t\topts->reschedule_failed_exec = 1;\n>   \n> @@ -2620,6 +2656,8 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n>   \t\twrite_file(rebase_path_gpg_sign_opt(), \"-S%s\\n\", opts->gpg_sign);\n>   \tif (opts->signoff)\n>   \t\twrite_file(rebase_path_signoff(), \"--signoff\\n\");\n> +\tif (opts->committer_date_is_author_date)\n> +\t\twrite_file(rebase_path_cdate_is_adate(), \"%s\", \"\");\n>   \tif (opts->reschedule_failed_exec)\n>   \t\twrite_file(rebase_path_reschedule_failed_exec(), \"%s\", \"\");\n>   \n> @@ -3437,6 +3475,12 @@ static int do_merge(struct repository *r,\n>   \t\targv_array_push(&cmd.args, git_path_merge_msg(r));\n>   \t\tif (opts->gpg_sign)\n>   \t\t\targv_array_push(&cmd.args, opts->gpg_sign);\n> +\t\tif (opts->committer_date_is_author_date) {\n> +\t\t\tchar *date = read_author_date_or_die();\n> +\t\t\targv_array_pushf(&cmd.env_array,\n> +\t\t\t\t\t \"GIT_COMMITTER_DATE=%s\", date);\n> +\t\t\tfree(date);\n> +\t\t}\n>   \n>   \t\t/* Add the tips to be merged */\n>   \t\tfor (j = to_merge; j; j = j->next)\n> diff --git a/sequencer.h b/sequencer.h\n> index 303047a133..0cfe184fc2 100644\n> --- a/sequencer.h\n> +++ b/sequencer.h\n> @@ -44,6 +44,7 @@ struct replay_opts {\n>   \tint quiet;\n>   \tint reschedule_failed_exec;\n>   \tint ignore_whitespace;\n> +\tint committer_date_is_author_date;\n>   \n>   \tint mainline;\n>   \n> diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\n> index 4342f79eea..7402f7e3da 100755\n> --- a/t/t3422-rebase-incompatible-options.sh\n> +++ b/t/t3422-rebase-incompatible-options.sh\n> @@ -61,7 +61,6 @@ test_rebase_am_only () {\n>   }\n>   \n>   test_rebase_am_only --whitespace=fix\n> -test_rebase_am_only --committer-date-is-author-date\n>   test_rebase_am_only -C4\n>   \n>   test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\n> diff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\n> index f38ae6f5fc..c3f7f6d5d0 100755\n> --- a/t/t3431-rebase-options-compatibility.sh\n> +++ b/t/t3431-rebase-options-compatibility.sh\n> @@ -7,6 +7,9 @@ test_description='tests to ensure compatibility between am and interactive backe\n>   \n>   . ./test-lib.sh\n>   \n> +GIT_AUTHOR_DATE=\"1999-04-02T08:03:20+05:30\"\n> +export GIT_AUTHOR_DATE\n> +\n>   # This is a special case in which both am and interactive backends\n>   # provide the same outputs. It was done intentionally because\n>   # --ignore-whitespace both the backends fall short of optimal\n> @@ -63,4 +66,22 @@ test_expect_success '--ignore-whitespace works with interactive backend' '\n>   \ttest_cmp expect file\n>   '\n>   \n> +test_expect_success '--committer-date-is-author-date works with am backend' '\n> +\tgit rebase -f HEAD^ &&\n> +\tgit rebase --committer-date-is-author-date HEAD^ &&\n> +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n> +\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n> +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n> +\ttest_cmp authortime committertime\n> +'\n> +\n> +test_expect_success '--committer-date-is-author-date works with interactive backend' '\n> +\tgit rebase -f HEAD^ &&\n> +\tgit rebase -i --committer-date-is-author-date HEAD^ &&\n> +\tgit cat-file commit HEAD | sed -e \"/^\\$/q\" >head &&\n> +\tsed -ne \"/^author /s/.*> //p\" head >authortime &&\n> +\tsed -ne \"/^committer /s/.*> //p\" head >committertime &&\n> +\ttest_cmp authortime committertime\n> +'\n> +\n>   test_done\n> \n"},{"id":"379142","messageId":"6e61e65e-53c2-eb49-2197-03fe9796ef1f@gmail.com","threadId":"51475","inReplyTo":"20190718185514.20108-2-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2019-07-22T10:00:40Z","receivedAt":"2019-07-22T10:00:47Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Rohit,\n\nIt's good to see another patch reducing the differences between the\nrebase back ends.\n\nOn 18/07/2019 19:55, Rohit Ashiwal wrote:\n> There are two backends available for rebasing, viz, the am and the\n> interactive. Naturally, there shall be some features that are\n> implemented in one but not in the other. One such flag is\n> --ignore-whitespace which indicates merge mechanism to treat lines\n> with only whitespace changes as unchanged. Wire the interactive\n> rebase to also understand the --ignore-whitespace flag by\n> translating it to -Xignore-space-change.\n> \n> Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n> ---\n>  Documentation/git-rebase.txt            |  9 +++-\n>  builtin/rebase.c                        | 26 ++++++++--\n>  sequencer.h                             |  1 +\n>  t/t3422-rebase-incompatible-options.sh  |  1 -\n>  t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n>  5 files changed, 97 insertions(+), 6 deletions(-)\n>  create mode 100755 t/t3431-rebase-options-compatibility.sh\n> \n> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\n> index 5e4e927647..eda52ed824 100644\n> --- a/Documentation/git-rebase.txt\n> +++ b/Documentation/git-rebase.txt\n> @@ -371,8 +371,13 @@ If either <upstream> or --root is given on the command line, then the\n>  default is `--no-fork-point`, otherwise the default is `--fork-point`.\n>  \n>  --ignore-whitespace::\n> +\tThis flag is either passed to the 'git apply' program\n> +\t(see linkgit:git-apply[1]), or to 'git merge' program\n> +\t(see linkgit:git-merge[1]) as `-Xignore-space-change`,\n> +\tdepending on which backend is selected by other options.\n> +\n>  --whitespace=<option>::\n> -\tThese flag are passed to the 'git apply' program\n> +\tThis flag is passed to the 'git apply' program\n>  \t(see linkgit:git-apply[1]) that applies the patch.\n>  +\n>  See also INCOMPATIBLE OPTIONS below.\n> @@ -520,7 +525,6 @@ The following options:\n>   * --committer-date-is-author-date\n>   * --ignore-date\n>   * --whitespace\n> - * --ignore-whitespace\n>   * -C\n>  \n>  are incompatible with the following options:\n> @@ -543,6 +547,7 @@ In addition, the following pairs of options are incompatible:\n>   * --preserve-merges and --interactive\n>   * --preserve-merges and --signoff\n>   * --preserve-merges and --rebase-merges\n> + * --rebase-merges and --ignore-whitespace\n>   * --rebase-merges and --strategy\n>   * --rebase-merges and --strategy-option\n>  \n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index db6ca9bd7d..afe376c3fe 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -79,6 +79,7 @@ struct rebase_options {\n>  \tint allow_rerere_autoupdate;\n>  \tint keep_empty;\n>  \tint autosquash;\n> +\tint ignore_whitespace;\n>  \tchar *gpg_sign_opt;\n>  \tint autostash;\n>  \tchar *cmd;\n> @@ -376,6 +377,17 @@ static int run_rebase_interactive(struct rebase_options *opts,\n>  \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n>  \tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n>  \n> +\tif (opts->ignore_whitespace) {\n> +\t\tstruct strbuf buf = STRBUF_INIT;\n> +\n> +\t\tif (opts->strategy_opts)\n> +\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n> +\n> +\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n> +\t\tfree(opts->strategy_opts);\n> +\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n> +\t}\n> +\n\nI think this would fit better in get_replay_opts()\n\n>  \tswitch (command) {\n>  \tcase ACTION_NONE: {\n>  \t\tif (!opts->onto && !opts->upstream)\n> @@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>  \t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n>  \t\t\tN_(\"GPG-sign commits\"),\n>  \t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n> +\t\tOPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n> +\t\t\t N_(\"ignore changes in whitespace\")),\n\nAs with the other patch is this actually going to be used by\nrebase--preserve-merges.sh?\n\n>  \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n>  \t\t\t   N_(\"rebase strategy\")),\n>  \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n> @@ -511,6 +525,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>  \targc = parse_options(argc, argv, NULL, options,\n>  \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n>  \n> +\topts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n> +\n>  \tif (!is_null_oid(&squash_onto))\n>  \t\topts.squash_onto = &squash_onto;\n>  \n> @@ -954,6 +970,8 @@ static int run_am(struct rebase_options *opts)\n>  \tam.git_cmd = 1;\n>  \targv_array_push(&am.args, \"am\");\n>  \n> +\tif (opts->ignore_whitespace)\n> +\t\targv_array_push(&am.args, \"--ignore-whitespace\");\n>  \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n>  \t\targv_array_push(&am.args, \"--resolved\");\n>  \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n> @@ -1401,9 +1419,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n>  \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n>  \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n> -\t\tOPT_PASSTHRU_ARGV(0, \"ignore-whitespace\", &options.git_am_opts,\n> -\t\t\t\t  NULL, N_(\"passed to 'git am'\"),\n> -\t\t\t\t  PARSE_OPT_NOARG),\n>  \t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n>  \t\t\t\t  &options.git_am_opts, NULL,\n>  \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n> @@ -1411,6 +1426,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n>  \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n>  \t\t\t\t  N_(\"passed to 'git apply'\"), 0),\n> +\t\tOPT_BOOL(0, \"ignore-whitespace\", &options.ignore_whitespace,\n> +\t\t\t N_(\"ignore changes in whitespace\")),\n>  \t\tOPT_PASSTHRU_ARGV(0, \"whitespace\", &options.git_am_opts,\n>  \t\t\t\t  N_(\"action\"), N_(\"passed to 'git apply'\"), 0),\n>  \t\tOPT_BIT('f', \"force-rebase\", &options.flags,\n> @@ -1821,6 +1838,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>  \t}\n>  \n>  \tif (options.rebase_merges) {\n> +\t\tif (options.ignore_whitespace)\n> +\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n> +\t\t\t      \"'--ignore-whitespace'\"));\n\nI was going to ask why we cannot just pass -Xignore-space-change when\nmaking the merge but the lines below seem to show we don't support merge\noptions yet.\n\n>  \t\tif (strategy_options.nr)\n>  \t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n>  \t\t\t      \"'--strategy-option'\"));\n> diff --git a/sequencer.h b/sequencer.h\n> index 0c494b83d4..303047a133 100644\n> --- a/sequencer.h\n> +++ b/sequencer.h\n> @@ -43,6 +43,7 @@ struct replay_opts {\n>  \tint verbose;\n>  \tint quiet;\n>  \tint reschedule_failed_exec;\n> +\tint ignore_whitespace;\n\nIs this new field used anywhere - we add -Xignore-space-change to\nreplay_opts.xopts so why do we need this as well?\n\nBest Wishes\n\nPhillip\n\n>  \n>  \tint mainline;\n>  \n> diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\n> index a5868ea152..4342f79eea 100755\n> --- a/t/t3422-rebase-incompatible-options.sh\n> +++ b/t/t3422-rebase-incompatible-options.sh\n> @@ -61,7 +61,6 @@ test_rebase_am_only () {\n>  }\n>  \n>  test_rebase_am_only --whitespace=fix\n> -test_rebase_am_only --ignore-whitespace\n>  test_rebase_am_only --committer-date-is-author-date\n>  test_rebase_am_only -C4\n>  \n> diff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\n> new file mode 100755\n> index 0000000000..f38ae6f5fc\n> --- /dev/null\n> +++ b/t/t3431-rebase-options-compatibility.sh\n> @@ -0,0 +1,66 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2019 Rohit Ashiwal\n> +#\n> +\n> +test_description='tests to ensure compatibility between am and interactive backends'\n> +\n> +. ./test-lib.sh\n> +\n> +# This is a special case in which both am and interactive backends\n> +# provide the same outputs. It was done intentionally because\n> +# --ignore-whitespace both the backends fall short of optimal\n> +# behaviour.\n> +test_expect_success 'setup' '\n> +\tgit checkout -b topic &&\n> +\tq_to_tab >file <<-EOF &&\n> +\tline 1\n> +\tQline 2\n> +\tline 3\n> +\tEOF\n> +\tgit add file &&\n> +\tgit commit -m \"add file\" &&\n> +\tq_to_tab >file <<-EOF &&\n> +\tline 1\n> +\tnew line 2\n> +\tline 3\n> +\tEOF\n> +\tgit commit -am \"update file\" &&\n> +\tgit tag side &&\n> +\n> +\tgit checkout --orphan master &&\n> +\tq_to_tab >file <<-EOF &&\n> +\tline 1\n> +\t        line 2\n> +\tline 3\n> +\tEOF\n> +\tgit add file &&\n> +\tgit commit -m \"add file\" &&\n> +\tgit tag main\n> +'\n> +\n> +test_expect_success '--ignore-whitespace works with am backend' '\n> +\tcat >expect <<-EOF &&\n> +\tline 1\n> +\tnew line 2\n> +\tline 3\n> +\tEOF\n> +\ttest_must_fail git rebase main side &&\n> +\tgit rebase --abort &&\n> +\tgit rebase --ignore-whitespace main side &&\n> +\ttest_cmp expect file\n> +'\n> +\n> +test_expect_success '--ignore-whitespace works with interactive backend' '\n> +\tcat >expect <<-EOF &&\n> +\tline 1\n> +\tnew line 2\n> +\tline 3\n> +\tEOF\n> +\ttest_must_fail git rebase --merge main side &&\n> +\tgit rebase --abort &&\n> +\tgit rebase --merge --ignore-whitespace main side &&\n> +\ttest_cmp expect file\n> +'\n> +\n> +test_done\n> \n\n"},{"id":"379181","messageId":"20190723195722.16745-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"7f53b294-57f7-77bf-ca0a-e9621227377c@gmail.com","subject":"Re: [GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-23T19:57:22Z","receivedAt":"2019-07-23T20:00:13Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Phillip\n\nOn Sat, 20 Jul 2019 15:56:50 +0100 Phillip Wood <phillip.wood123@gmail.com> wrote:\n> \n> [...]\n> \n> > @@ -467,6 +470,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n> >   \t\tOPT_BOOL(0, \"autosquash\", &opts.autosquash,\n> >   \t\t\t N_(\"move commits that begin with squash!/fixup!\")),\n> >   \t\tOPT_BOOL(0, \"signoff\", &opts.signoff, N_(\"sign commits\")),\n> > +\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n> > +\t\t\t &opts.committer_date_is_author_date,\n> > +\t\t\t N_(\"make committer date match author date\")),\n> \n> I guess it's good to do this for completeness but does\n> rebase--preserver-merges.sh support --committer-date-is-author-date? It\n> is the only caller of rebase--interactive I think so would be the only\n> user of this code.\n\nOh! Yes, I did it for the completeness. Let's add the flag while we\nstill have that _rebase--interactive_ command hanging out with us.\n\n> [...]\n> \n> > +\tif (read_author_script(rebase_path_author_script(),\n> > +\t\t\t       NULL, NULL, &date, 0))\n> > +\t\tdie(_(\"failed to read author date\"));\n> \n> Can we have this return an error please - we try quite hard in the\n> sequencer not to die in library code.\n\nYes, we can through an error and continue, but then the user will\nsee the unchanged author date which is against his / her will but\nit will not crash the program at least.\n\n> [...]\n> \n> > +\tif (opts->committer_date_is_author_date) {\n> > +\t\tchar *date = read_author_date_or_die();\n> > +\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n> > +\t\tfree(date);\n> > +\t}\n> \n> It's a shame to be doing this twice is slightly different ways in the\n> same function (and again in try_to_commit() but I don't think that can\n> be avoided as not all callers of run_git_commit() go through\n> try_to_commit()). As I think the child inherits the current environment\n> modified by cmd.env_array we could just call setenv() at the top of the\n> function. It would be worth looking to see if it would be simpler to do\n> the setenv() call in the loop that picks the commits, then we would\n> avoid having to do it in do_merge() and try_to_commit() separately.\n\nOk, I'll have to change the code according to what Junio suggested.\nLet's see how this area will look after that.\n\n> [...]\n> \n> > +\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n> > +\t\t\topts->allow_ff = 0;\n> \n> This is safe as we don't save the state of allow_ff for rebases so it\n> wont be overridden later. It would be an idea to add to the checks in\n> the assert() at the beginning of pick_commits() no we have another\n> option that implies --force-rebase.\n\nAre you suggesting to modify this assert() call (in pick_commits())?\n\n    if (opts->allow_ff)\n        assert(!(opts->signoff || opts->no_commit ||\n                opts->record_origin || opts->edit));\n\nThanks\nRohit\n\n"},{"id":"379182","messageId":"20190723195820.16856-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"6e61e65e-53c2-eb49-2197-03fe9796ef1f@gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-23T19:58:20Z","receivedAt":"2019-07-23T20:01:09Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Phillip\n\nOn Mon, 22 Jul 2019 11:00:40 +0100 Phillip Wood <phillip.wood123@gmail.com> wrote:\n> \n> [...]\n> >\n> > +\tif (opts->ignore_whitespace) {\n> > +\t\tstruct strbuf buf = STRBUF_INIT;\n> > +\n> > +\t\tif (opts->strategy_opts)\n> > +\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n> > +\n> > +\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n> > +\t\tfree(opts->strategy_opts);\n> > +\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n> > +\t}\n> > +\n> \n> I think this would fit better in get_replay_opts()\n\nAgreed, I'll move this to get_replay_opts().\n\n> [...]\n> \n> > @@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n> >  \t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n> >  \t\t\tN_(\"GPG-sign commits\"),\n> >  \t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n> > +\t\tOPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n> > +\t\t\t N_(\"ignore changes in whitespace\")),\n> \n> As with the other patch is this actually going to be used by\n> rebase--preserve-merges.sh?\n\nI added this just for the completness. Is there any discussion on\ndropping rebase--interactive as command and may be lib'fying it while\ndeprecating rebase--preserve-merges?\n\n> [...]\n> \n> > @@ -43,6 +43,7 @@ struct replay_opts {\n> >  \tint verbose;\n> >  \tint quiet;\n> >  \tint reschedule_failed_exec;\n> > +\tint ignore_whitespace;\n> \n> Is this new field used anywhere - we add -Xignore-space-change to\n> replay_opts.xopts so why do we need this as well?\n\nAh! I just realised cmd_rebase__interactive use rebase_options and\nnot replay_options. I too think this field is not required.\n\nThanks\nRohit\n\n"},{"id":"379183","messageId":"20190723195932.16951-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"xmqq5znxvhdu.fsf@gitster-ct.c.googlers.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-23T19:59:32Z","receivedAt":"2019-07-23T20:02:22Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Junio\n\nOn Fri, 19 Jul 2019 14:33:49 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n> \n> >  t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n> \n> Isn't 3431 already taken?\n\nIt is not in git/git[1].\n\n> >  5 files changed, 97 insertions(+), 6 deletions(-)\n> >  create mode 100755 t/t3431-rebase-options-compatibility.sh\n> > ...\n> > +\tgit checkout --orphan master &&\n> > +\tq_to_tab >file <<-EOF &&\n> > +\tline 1\n> > +\t        line 2\n> > +\tline 3\n> > +\tEOF\n> \n> This will trigger \"indent-with-space\".  Instead of using q-to-tab,\n> perhaps something like this would be more appropriate (not limited\n> to this piece, but also other ones in this script that actually do\n> use Q to visualize a tab)?\n> \n> \tsed -e \"s/^|//\" >file <<-EOF &&\n> \t|line 1\n> \t|        line 2\n> \t|line 3\n> \tEOF\n> \n\nOh! My mistake, I should have used cat instead.\n\nThanks\nRohit\n\n[1]: https://github.com/git/git/tree/master/t\n"},{"id":"379187","messageId":"xmqqmuh4sc4b.fsf@gitster-ct.c.googlers.com","threadId":"51475","inReplyTo":"20190723195932.16951-1-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-23T20:57:08Z","receivedAt":"2019-07-23T20:57:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rohit Ashiwal <rohit.ashiwal265@gmail.com> writes:\n\n> Hi Junio\n>\n> On Fri, 19 Jul 2019 14:33:49 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n>> \n>> >  t/t3431-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n>> \n>> Isn't 3431 already taken?\n>\n> It is not in git/git[1].\n\nThat's a very selfish attitude ;-)  Pay attention to what others are\ndoing while you are working on this topic (hint: do not limit your\ncheck to 'master', but make sure your changes also work well when\nmerged to 'next' and 'pu'---make a trial merge or two and run test\nsuite, for example).\n\n>> > +\tgit checkout --orphan master &&\n>> > +\tq_to_tab >file <<-EOF &&\n>> > +\tline 1\n>> > +\t        line 2\n>> > +\tline 3\n>> > +\tEOF\n>> \n>> This will trigger \"indent-with-space\".  Instead of using q-to-tab,\n>> perhaps something like this would be more appropriate (not limited\n>> to this piece, but also other ones in this script that actually do\n>> use Q to visualize a tab)?\n>> \n>> \tsed -e \"s/^|//\" >file <<-EOF &&\n>> \t|line 1\n>> \t|        line 2\n>> \t|line 3\n>> \tEOF\n>> \n>\n> Oh! My mistake, I should have used cat instead.\n\nI am not sure how you would avoid indent-with-space with \"cat\".\nWith the use of \"sed\" like I showed above to spell the left margin\nexplicitly out, we can---I am not saying it's the only way, but I do\nnot think of a clean way to do the same with \"cat\".\n"},{"id":"379188","messageId":"CABPp-BE1=FB3LXAZP+i0Mj2OZQ7kTx2s3S+fZR9Y7EAg8KhqRg@mail.gmail.com","threadId":"51475","inReplyTo":"20190723195820.16856-1-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2019-07-23T21:01:10Z","receivedAt":"2019-07-23T21:01:24Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Jul 23, 2019 at 1:01 PM Rohit Ashiwal\n<rohit.ashiwal265@gmail.com> wrote:\n> On Mon, 22 Jul 2019 11:00:40 +0100 Phillip Wood <phillip.wood123@gmail.com> wrote:\n> > [...]\n> >\n> > > @@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n> > >             { OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n> > >                     N_(\"GPG-sign commits\"),\n> > >                     PARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n> > > +           OPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n> > > +                    N_(\"ignore changes in whitespace\")),\n> >\n> > As with the other patch is this actually going to be used by\n> > rebase--preserve-merges.sh?\n>\n> I added this just for the completness. Is there any discussion on\n> dropping rebase--interactive as command and may be lib'fying it while\n> deprecating rebase--preserve-merges?\n\npreserve-merges is already deprecated, see\nhttps://public-inbox.org/git/pull.158.git.gitgitgadget@gmail.com/ and\nthe output of:\n   git grep deprecated -- '*rebase*'\n\nIt's also instructive to take a look at\nhttps://public-inbox.org/git/xmqqk1rrm8ic.fsf@gitster-ct.c.googlers.com/,\nwhich talks about how git-rebase--preserve-merges.sh came to be; from\nreading that, it looks like the whole point of making\nrebase--preserve-merges.sh a separate script was to avoid the effort\nneeded to libify it.  As such, you probably just want to avoid\nbreaking it or even changing it at all until it can be deleted.\nAnything that only the preserve-rebases backend uses (such as direct\ninvocations of rebase--interactive, according to what Phillip said\nelsewhere in this thread), are probably better left alone as much as\npossible, with us instead documenting that preserve-merges lacks any\nnew capabilities you are otherwise adding to rebase.\n\nNot sure if that answers all your questions, though.\n"},{"id":"379200","messageId":"nycvar.QRO.7.76.6.1907241308500.21907@tvgsbejvaqbjf.bet","threadId":"51475","inReplyTo":"CABPp-BE1=FB3LXAZP+i0Mj2OZQ7kTx2s3S+fZR9Y7EAg8KhqRg@mail.gmail.com","subject":"Re: [GSoC][PATCH v2 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-07-24T11:14:49Z","receivedAt":"2019-07-24T11:15:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Elijah & Rohit,\n\nOn Tue, 23 Jul 2019, Elijah Newren wrote:\n\n> On Tue, Jul 23, 2019 at 1:01 PM Rohit Ashiwal\n> <rohit.ashiwal265@gmail.com> wrote:\n> > On Mon, 22 Jul 2019 11:00:40 +0100 Phillip Wood <phillip.wood123@gmail.com> wrote:\n> > > [...]\n> > >\n> > > > @@ -489,6 +501,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n> > > >             { OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n> > > >                     N_(\"GPG-sign commits\"),\n> > > >                     PARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n> > > > +           OPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n> > > > +                    N_(\"ignore changes in whitespace\")),\n> > >\n> > > As with the other patch is this actually going to be used by\n> > > rebase--preserve-merges.sh?\n> >\n> > I added this just for the completness. Is there any discussion on\n> > dropping rebase--interactive as command and may be lib'fying it while\n> > deprecating rebase--preserve-merges?\n>\n> preserve-merges is already deprecated, see\n> https://public-inbox.org/git/pull.158.git.gitgitgadget@gmail.com/ and\n> the output of:\n>    git grep deprecated -- '*rebase*'\n>\n> It's also instructive to take a look at\n> https://public-inbox.org/git/xmqqk1rrm8ic.fsf@gitster-ct.c.googlers.com/,\n> which talks about how git-rebase--preserve-merges.sh came to be; from\n> reading that, it looks like the whole point of making\n> rebase--preserve-merges.sh a separate script was to avoid the effort\n> needed to libify it.  As such, you probably just want to avoid\n> breaking it or even changing it at all until it can be deleted.\n> Anything that only the preserve-rebases backend uses (such as direct\n> invocations of rebase--interactive, according to what Phillip said\n> elsewhere in this thread), are probably better left alone as much as\n> possible, with us instead documenting that preserve-merges lacks any\n> new capabilities you are otherwise adding to rebase.\n\nIndeed, libifying or even as much as enhancing it is a lot of love lost\nat this stage.\n\n> Not sure if that answers all your questions, though.\n\nI am sure that Rohit has a lot more questions that are not answered by\nthis email (maybe even \"What is the meaning of life?\"), but one\nparticular (not quite asked) question that I would like to answer here\nis: what does it take to actually drop `--preserve-merges`?\n\nTo answer that question, I prepared the `drop-rebase-p` branch at\nhttps://github.com/dscho/git/commits/drop-rebase-p, essentially dropping\n`git-rebase--preserve--merges.sh` and addressing the fall-out.\n\nThe biggest issue seems to be `--rebase-merges`' lack of support for\nmerge strategies other than the default, recursive merge one. To address\nthat, I implemented this patch:\nhttps://github.com/dscho/git/commit/afa39b4fbb3ef5a53ccb9ae1f4376be87f570110\n\nThere are a couple other patches that need to broken out into their own\npatch series, I just did not get to that yet.\n\nCiao,\nDscho\n"},{"id":"379202","messageId":"dbe0fe4d-9553-fd8e-5c5a-5457dc5e3eae@gmail.com","threadId":"51475","inReplyTo":"20190723195722.16745-1-rohit.ashiwal265@gmail.com","subject":"Re: [GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2019-07-24T13:33:05Z","receivedAt":"2019-07-24T13:33:10Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Rohit\n\nOn 23/07/2019 20:57, Rohit Ashiwal wrote:\n> Hi Phillip\n> \n> On Sat, 20 Jul 2019 15:56:50 +0100 Phillip Wood <phillip.wood123@gmail.com> wrote:\n>>\n>> [...]\n>>\n>>> @@ -467,6 +470,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>>>    \t\tOPT_BOOL(0, \"autosquash\", &opts.autosquash,\n>>>    \t\t\t N_(\"move commits that begin with squash!/fixup!\")),\n>>>    \t\tOPT_BOOL(0, \"signoff\", &opts.signoff, N_(\"sign commits\")),\n>>> +\t\tOPT_BOOL(0, \"committer-date-is-author-date\",\n>>> +\t\t\t &opts.committer_date_is_author_date,\n>>> +\t\t\t N_(\"make committer date match author date\")),\n>>\n>> I guess it's good to do this for completeness but does\n>> rebase--preserver-merges.sh support --committer-date-is-author-date? It\n>> is the only caller of rebase--interactive I think so would be the only\n>> user of this code.\n> \n> Oh! Yes, I did it for the completeness. Let's add the flag while we\n> still have that _rebase--interactive_ command hanging out with us.\n> \n>> [...]\n>>\n>>> +\tif (read_author_script(rebase_path_author_script(),\n>>> +\t\t\t       NULL, NULL, &date, 0))\n>>> +\t\tdie(_(\"failed to read author date\"));\n>>\n>> Can we have this return an error please - we try quite hard in the\n>> sequencer not to die in library code.\n> \n> Yes, we can through an error and continue, but then the user will\n> see the unchanged author date which is against his / her will but\n> it will not crash the program at least.\n\nI dont think it should continue, the error should be propagated up to \ncmd_rebase() (In your patch I think one of the context lines in \nrun_git_commit() shows this happening)\n\n> \n>> [...]\n>>\n>>> +\tif (opts->committer_date_is_author_date) {\n>>> +\t\tchar *date = read_author_date_or_die();\n>>> +\t\targv_array_pushf(&cmd.env_array, \"GIT_COMMITTER_DATE=%s\", date);\n>>> +\t\tfree(date);\n>>> +\t}\n>>\n>> It's a shame to be doing this twice is slightly different ways in the\n>> same function (and again in try_to_commit() but I don't think that can\n>> be avoided as not all callers of run_git_commit() go through\n>> try_to_commit()). As I think the child inherits the current environment\n>> modified by cmd.env_array we could just call setenv() at the top of the\n>> function. It would be worth looking to see if it would be simpler to do\n>> the setenv() call in the loop that picks the commits, then we would\n>> avoid having to do it in do_merge() and try_to_commit() separately.\n> \n> Ok, I'll have to change the code according to what Junio suggested.\n> Let's see how this area will look after that.\n> \n>> [...]\n>>\n>>> +\t\tif (file_exists(rebase_path_cdate_is_adate())) {\n>>> +\t\t\topts->allow_ff = 0;\n>>\n>> This is safe as we don't save the state of allow_ff for rebases so it\n>> wont be overridden later. It would be an idea to add to the checks in\n>> the assert() at the beginning of pick_commits() no we have another\n>> option that implies --force-rebase.\n> \n> Are you suggesting to modify this assert() call (in pick_commits())?\n> \n>      if (opts->allow_ff)\n>          assert(!(opts->signoff || opts->no_commit ||\n>                  opts->record_origin || opts->edit));\n\nYes I think it should check for opts->committer_date_is_author_date here\n\nBest Wishes\n\nPhillip\n\n> Thanks\n> Rohit\n> \n"},{"id":"379221","messageId":"20190724211846.18131-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190712185015.20585-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v3 0/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-24T21:18:45Z","receivedAt":"2019-07-24T21:21:43Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"This revision removes --ignore-whitespace from rebase--interactive since its\nonly caller preserve-merges is now deprecated. Also rename t3431 to t3433.\n\nRohit Ashiwal (1):\n  rebase -i: add --ignore-whitespace flag\n\n Documentation/git-rebase.txt            | 10 +++-\n builtin/rebase.c                        | 26 ++++++++--\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3433-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 4 files changed, 96 insertions(+), 7 deletions(-)\n create mode 100755 t/t3433-rebase-options-compatibility.sh\n\nRange-diff:\n1:  a1bb91fe43 ! 1:  eef6f6fa25 rebase -i: add --ignore-whitespace flag\n    @@ -42,6 +42,7 @@\n       * --preserve-merges and --interactive\n       * --preserve-merges and --signoff\n       * --preserve-merges and --rebase-merges\n    ++ * --preserve-merges and --ignore-whitespace\n     + * --rebase-merges and --ignore-whitespace\n       * --rebase-merges and --strategy\n       * --rebase-merges and --strategy-option\n    @@ -59,9 +60,19 @@\n      \tint autostash;\n      \tchar *cmd;\n     @@\n    - \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n    - \tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n    + \t\t.git_format_patch_opt = STRBUF_INIT\t\\\n    + \t}\n    + \n    +-static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n    ++static struct replay_opts get_replay_opts(struct rebase_options *opts)\n    + {\n    + \tstruct replay_opts replay = REPLAY_OPTS_INIT;\n      \n    +@@\n    + \treplay.reschedule_failed_exec = opts->reschedule_failed_exec;\n    + \treplay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);\n    + \treplay.strategy = opts->strategy;\n    ++\n     +\tif (opts->ignore_whitespace) {\n     +\t\tstruct strbuf buf = STRBUF_INIT;\n     +\n    @@ -72,19 +83,9 @@\n     +\t\tfree(opts->strategy_opts);\n     +\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n     +\t}\n    -+\n    - \tswitch (command) {\n    - \tcase ACTION_NONE: {\n    - \t\tif (!opts->onto && !opts->upstream)\n    -@@\n    - \t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt, N_(\"key-id\"),\n    - \t\t\tN_(\"GPG-sign commits\"),\n    - \t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\n    -+\t\tOPT_BOOL(0, \"ignore-whitespace\", &opts.ignore_whitespace,\n    -+\t\t\t N_(\"ignore changes in whitespace\")),\n    - \t\tOPT_STRING(0, \"strategy\", &opts.strategy, N_(\"strategy\"),\n    - \t\t\t   N_(\"rebase strategy\")),\n    - \t\tOPT_STRING(0, \"strategy-opts\", &opts.strategy_opts, N_(\"strategy-opts\"),\n    + \tif (opts->strategy_opts)\n    + \t\tparse_strategy_opts(&replay, opts->strategy_opts);\n    + \n     @@\n      \targc = parse_options(argc, argv, NULL, options,\n      \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n    @@ -133,18 +134,6 @@\n      \t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n      \t\t\t      \"'--strategy-option'\"));\n     \n    - diff --git a/sequencer.h b/sequencer.h\n    - --- a/sequencer.h\n    - +++ b/sequencer.h\n    -@@\n    - \tint verbose;\n    - \tint quiet;\n    - \tint reschedule_failed_exec;\n    -+\tint ignore_whitespace;\n    - \n    - \tint mainline;\n    - \n    -\n      diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\n      --- a/t/t3422-rebase-incompatible-options.sh\n      +++ b/t/t3422-rebase-incompatible-options.sh\n    @@ -157,10 +146,10 @@\n      test_rebase_am_only -C4\n      \n     \n    - diff --git a/t/t3431-rebase-options-compatibility.sh b/t/t3431-rebase-options-compatibility.sh\n    + diff --git a/t/t3433-rebase-options-compatibility.sh b/t/t3433-rebase-options-compatibility.sh\n      new file mode 100755\n      --- /dev/null\n    - +++ b/t/t3431-rebase-options-compatibility.sh\n    + +++ b/t/t3433-rebase-options-compatibility.sh\n     @@\n     +#!/bin/sh\n     +#\n    @@ -184,7 +173,7 @@\n     +\tEOF\n     +\tgit add file &&\n     +\tgit commit -m \"add file\" &&\n    -+\tq_to_tab >file <<-EOF &&\n    ++\tcat >file <<-EOF &&\n     +\tline 1\n     +\tnew line 2\n     +\tline 3\n    @@ -193,7 +182,7 @@\n     +\tgit tag side &&\n     +\n     +\tgit checkout --orphan master &&\n    -+\tq_to_tab >file <<-EOF &&\n    ++\tcat >file <<-EOF &&\n     +\tline 1\n     +\t        line 2\n     +\tline 3\n-- \n2.21.0\n\n"},{"id":"379222","messageId":"20190724211846.18131-2-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"20190724211846.18131-1-rohit.ashiwal265@gmail.com","subject":"[GSoC][PATCH v3 1/1] rebase -i: add --ignore-whitespace flag","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-07-24T21:18:46Z","receivedAt":"2019-07-24T21:21:47Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"There are two backends available for rebasing, viz, the am and the\ninteractive. Naturally, there shall be some features that are\nimplemented in one but not in the other. One such flag is\n--ignore-whitespace which indicates merge mechanism to treat lines\nwith only whitespace changes as unchanged. Wire the interactive\nrebase to also understand the --ignore-whitespace flag by\ntranslating it to -Xignore-space-change.\n\nSigned-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>\n---\n Documentation/git-rebase.txt            | 10 +++-\n builtin/rebase.c                        | 26 ++++++++--\n t/t3422-rebase-incompatible-options.sh  |  1 -\n t/t3433-rebase-options-compatibility.sh | 66 +++++++++++++++++++++++++\n 4 files changed, 96 insertions(+), 7 deletions(-)\n create mode 100755 t/t3433-rebase-options-compatibility.sh\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 5e4e927647..85404fea52 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -371,8 +371,13 @@ If either <upstream> or --root is given on the command line, then the\n default is `--no-fork-point`, otherwise the default is `--fork-point`.\n \n --ignore-whitespace::\n+\tThis flag is either passed to the 'git apply' program\n+\t(see linkgit:git-apply[1]), or to 'git merge' program\n+\t(see linkgit:git-merge[1]) as `-Xignore-space-change`,\n+\tdepending on which backend is selected by other options.\n+\n --whitespace=<option>::\n-\tThese flag are passed to the 'git apply' program\n+\tThis flag is passed to the 'git apply' program\n \t(see linkgit:git-apply[1]) that applies the patch.\n +\n See also INCOMPATIBLE OPTIONS below.\n@@ -520,7 +525,6 @@ The following options:\n  * --committer-date-is-author-date\n  * --ignore-date\n  * --whitespace\n- * --ignore-whitespace\n  * -C\n \n are incompatible with the following options:\n@@ -543,6 +547,8 @@ In addition, the following pairs of options are incompatible:\n  * --preserve-merges and --interactive\n  * --preserve-merges and --signoff\n  * --preserve-merges and --rebase-merges\n+ * --preserve-merges and --ignore-whitespace\n+ * --rebase-merges and --ignore-whitespace\n  * --rebase-merges and --strategy\n  * --rebase-merges and --strategy-option\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex db6ca9bd7d..3c195ddc73 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -79,6 +79,7 @@ struct rebase_options {\n \tint allow_rerere_autoupdate;\n \tint keep_empty;\n \tint autosquash;\n+\tint ignore_whitespace;\n \tchar *gpg_sign_opt;\n \tint autostash;\n \tchar *cmd;\n@@ -97,7 +98,7 @@ struct rebase_options {\n \t\t.git_format_patch_opt = STRBUF_INIT\t\\\n \t}\n \n-static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n+static struct replay_opts get_replay_opts(struct rebase_options *opts)\n {\n \tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \n@@ -114,6 +115,17 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)\n \treplay.reschedule_failed_exec = opts->reschedule_failed_exec;\n \treplay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);\n \treplay.strategy = opts->strategy;\n+\n+\tif (opts->ignore_whitespace) {\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tif (opts->strategy_opts)\n+\t\t\tstrbuf_addstr(&buf, opts->strategy_opts);\n+\n+\t\tstrbuf_addstr(&buf, \" --ignore-space-change\");\n+\t\tfree(opts->strategy_opts);\n+\t\topts->strategy_opts = strbuf_detach(&buf, NULL);\n+\t}\n \tif (opts->strategy_opts)\n \t\tparse_strategy_opts(&replay, opts->strategy_opts);\n \n@@ -511,6 +523,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, NULL, options,\n \t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n \n+\topts.strategy_opts = xstrdup_or_null(opts.strategy_opts);\n+\n \tif (!is_null_oid(&squash_onto))\n \t\topts.squash_onto = &squash_onto;\n \n@@ -954,6 +968,8 @@ static int run_am(struct rebase_options *opts)\n \tam.git_cmd = 1;\n \targv_array_push(&am.args, \"am\");\n \n+\tif (opts->ignore_whitespace)\n+\t\targv_array_push(&am.args, \"--ignore-whitespace\");\n \tif (opts->action && !strcmp(\"continue\", opts->action)) {\n \t\targv_array_push(&am.args, \"--resolved\");\n \t\targv_array_pushf(&am.args, \"--resolvemsg=%s\", resolvemsg);\n@@ -1401,9 +1417,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tPARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },\n \t\tOPT_BOOL(0, \"signoff\", &options.signoff,\n \t\t\t N_(\"add a Signed-off-by: line to each commit\")),\n-\t\tOPT_PASSTHRU_ARGV(0, \"ignore-whitespace\", &options.git_am_opts,\n-\t\t\t\t  NULL, N_(\"passed to 'git am'\"),\n-\t\t\t\t  PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV(0, \"committer-date-is-author-date\",\n \t\t\t\t  &options.git_am_opts, NULL,\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n@@ -1411,6 +1424,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\t  N_(\"passed to 'git am'\"), PARSE_OPT_NOARG),\n \t\tOPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_(\"n\"),\n \t\t\t\t  N_(\"passed to 'git apply'\"), 0),\n+\t\tOPT_BOOL(0, \"ignore-whitespace\", &options.ignore_whitespace,\n+\t\t\t N_(\"ignore changes in whitespace\")),\n \t\tOPT_PASSTHRU_ARGV(0, \"whitespace\", &options.git_am_opts,\n \t\t\t\t  N_(\"action\"), N_(\"passed to 'git apply'\"), 0),\n \t\tOPT_BIT('f', \"force-rebase\", &options.flags,\n@@ -1821,6 +1836,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (options.rebase_merges) {\n+\t\tif (options.ignore_whitespace)\n+\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n+\t\t\t      \"'--ignore-whitespace'\"));\n \t\tif (strategy_options.nr)\n \t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n \t\t\t      \"'--strategy-option'\"));\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex a5868ea152..4342f79eea 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -61,7 +61,6 @@ test_rebase_am_only () {\n }\n \n test_rebase_am_only --whitespace=fix\n-test_rebase_am_only --ignore-whitespace\n test_rebase_am_only --committer-date-is-author-date\n test_rebase_am_only -C4\n \ndiff --git a/t/t3433-rebase-options-compatibility.sh b/t/t3433-rebase-options-compatibility.sh\nnew file mode 100755\nindex 0000000000..24bb8f3dd0\n--- /dev/null\n+++ b/t/t3433-rebase-options-compatibility.sh\n@@ -0,0 +1,66 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2019 Rohit Ashiwal\n+#\n+\n+test_description='tests to ensure compatibility between am and interactive backends'\n+\n+. ./test-lib.sh\n+\n+# This is a special case in which both am and interactive backends\n+# provide the same outputs. It was done intentionally because\n+# --ignore-whitespace both the backends fall short of optimal\n+# behaviour.\n+test_expect_success 'setup' '\n+\tgit checkout -b topic &&\n+\tq_to_tab >file <<-EOF &&\n+\tline 1\n+\tQline 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tcat >file <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\tgit commit -am \"update file\" &&\n+\tgit tag side &&\n+\n+\tgit checkout --orphan master &&\n+\tcat >file <<-EOF &&\n+\tline 1\n+\t        line 2\n+\tline 3\n+\tEOF\n+\tgit add file &&\n+\tgit commit -m \"add file\" &&\n+\tgit tag main\n+'\n+\n+test_expect_success '--ignore-whitespace works with am backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_expect_success '--ignore-whitespace works with interactive backend' '\n+\tcat >expect <<-EOF &&\n+\tline 1\n+\tnew line 2\n+\tline 3\n+\tEOF\n+\ttest_must_fail git rebase --merge main side &&\n+\tgit rebase --abort &&\n+\tgit rebase --merge --ignore-whitespace main side &&\n+\ttest_cmp expect file\n+'\n+\n+test_done\n-- \n2.21.0\n\n"},{"id":"379854","messageId":"20190802205731.13794-1-rohit.ashiwal265@gmail.com","threadId":"51475","inReplyTo":"xmqqwogdtzxc.fsf@gitster-ct.c.googlers.com","subject":"Re: [GSoC][PATCH v2 2/2] rebase -i: support --committer-date-is-author-date","fromName":"Rohit Ashiwal","fromEmail":"rohit.ashiwal265@gmail.com","sentAt":"2019-08-02T20:57:31Z","receivedAt":"2019-08-02T21:00:32Z","isPatch":true,"sender":{"key":"rohit.ashiwal265@gmail.com","avatar":"https://avatars.githubusercontent.com/u/31043830?v=4"},"body":"Hi Junio\n\nOn Fri, 19 Jul 2019 15:36:15 -0700 Junio C Hamano <gitster@pobox.com> wrote:\n>\n> [...]\n> Hmph, are we sure that author-script is always available at this\n> point so that a call to read_author_date_or_die() is safe?  There\n> are three callers to the run_git_commit() function and I am not sure\n> if codepaths that reach all of them prepared the input to the\n> read_author_script() helper.\n\nFunctions do_pick_commit() and do_merge() always write author_script\nbefore calling run_git_commit(), so,  we are sure to find it on disk.\nFurthermore, commit_staged_changes() only calls run_git_commit() when\nrebase is stopped (by merge conflicts or 'edit' commands), so we are\nsure that the previous invocation of git must have saved author_script.\nIn all other cases, we fail as we should.\n\n> [...]\n>\n> In the same function, we seem to be grabbing the author ident by\n> calling get_author(message), where the message is an in-core copy of\n> a commit object, which suggests me that we may not necessarily be\n> working with the on-disk information read_author_date_or_die() is\n> prepared to deal with.  Are we sure we have the needed information\n> on disk so that read_author_date_or_die() will read the correct\n> information from the disk?\n\nYes, in that case, we can re-parse the author date and re-set the\nenv variable while we are in this if branch. I believe that the\ninformation stored on the disk is same as the information retrieved\nthrough get_author(), please confirm or disprove this.\n\n> [...]\n\nWith all this knowledge, I'll polish the patch and re-send it.\n\nThanks\nRohit\n\n"}]}