{"thread":{"id":"52325","subject":"[PATCH 0/8] Drop support for git rebase --preserve-merges","startedAt":"2019-11-23T20:50:47Z","lastAt":"2022-07-29T13:25:13Z","messageCount":78,"participants":["Johannes Schindelin via GitGitGadget","Eric Wong","Johannes Schindelin","Ævar Arnfjörð Bjarmason","Junio C Hamano","Johannes Sixt","Alban Gruin","Phillip Wood","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"386915","messageId":"pull.195.git.1574542242.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":null,"subject":"[PATCH 0/8] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:34Z","receivedAt":"2019-11-23T20:50:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\nincluded in v2.22.0), we officially deprecated the --preserve-merges \nbackend. This patch series drops that deprecated backend. Maybe we want to\nmake that happen around v2.26.0?\n\nNote: this patch series is based on js/git-svn-use-rebase-merges\n\nJohannes Schindelin (8):\n  t5520: do not use `pull.rebase=preserve`\n  remote: warn about unhandled branch.<name>.rebase values\n  tests: stop testing `git rebase --preserve-merges`\n  pull: remove support for `--rebase=preserve`\n  rebase: drop support for `--preserve-merges`\n  git-svn: drop support for `--preserve-merges`\n  rebase: drop the internal `rebase--interactive` command\n  remote: no longer claim that branch.*.rebase=preserve is a thing\n\n .gitignore                                |    1 -\n Documentation/config/branch.txt           |    4 -\n Documentation/config/pull.txt             |    4 -\n Documentation/git-pull.txt                |    6 +-\n Documentation/git-rebase.txt              |   47 -\n Documentation/git-svn.txt                 |    1 -\n Makefile                                  |    2 -\n azure-pipelines.yml                       |    2 -\n builtin/pull.c                            |   12 +-\n builtin/rebase.c                          |  316 +-----\n builtin/remote.c                          |    5 +-\n contrib/completion/git-completion.bash    |    2 +-\n git-rebase--preserve-merges.sh            | 1067 ---------------------\n git-svn.perl                              |    1 -\n git.c                                     |    1 -\n t/t3404-rebase-interactive.sh             |   76 --\n t/t3408-rebase-multi-line.sh              |   10 -\n t/t3409-rebase-preserve-merges.sh         |  127 ---\n t/t3410-rebase-preserve-dropped-merges.sh |   90 --\n t/t3411-rebase-preserve-around-merges.sh  |   80 --\n t/t3412-rebase-root.sh                    |   37 -\n t/t3414-rebase-preserve-onto.sh           |   85 --\n t/t3418-rebase-continue.sh                |   15 -\n t/t3421-rebase-topology-linear.sh         |   19 -\n t/t3422-rebase-incompatible-options.sh    |   11 -\n t/t3425-rebase-topology-merges.sh         |  151 ---\n t/t3427-rebase-subtree.sh                 |   19 -\n t/t5520-pull.sh                           |   24 +-\n t/t7505-prepare-commit-msg-hook.sh        |    1 -\n t/t7517-per-repo-email.sh                 |   13 -\n t/test-lib.sh                             |    4 -\n 31 files changed, 17 insertions(+), 2216 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\n\nbase-commit: ea8b7be1476a2301e3658a8e626b69c9d7f540bd\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-195%2Fdscho%2Fdrop-rebase-p-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-195/dscho/drop-rebase-p-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/195\n-- \ngitgitgadget\n"},{"id":"386916","messageId":"662e16dbc1246ac5737723134471f47e4f582fc1.1574542242.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 1/8] t5520: do not use `pull.rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:35Z","receivedAt":"2019-11-23T20:50:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nEven if those tests try to override that setting, let's not use it\nbecause it is deprecated: let's use `merges` instead.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t5520-pull.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex cf4cc32fd0..41b799e336 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -509,7 +509,7 @@ test_expect_success '--rebase=false create a new merge commit' '\n \n test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase=true . copy &&\n \ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n \ttest file3 = \"$(git show HEAD:file3.t)\"\n@@ -529,9 +529,9 @@ test_expect_success '--rebase=invalid fails' '\n \t! git pull --rebase=invalid . copy\n '\n \n-test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '\n+test_expect_success '--rebase overrides pull.rebase=merges and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase . copy &&\n \ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n \ttest file3 = \"$(git show HEAD:file3.t)\"\n-- \ngitgitgadget\n\n"},{"id":"386917","messageId":"fb531064b35814e5f8f87baa2996522d7ca57148.1574542242.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 2/8] remote: warn about unhandled branch.<name>.rebase values","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:36Z","receivedAt":"2019-11-23T20:50:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe ignore them silently, but it actually makes sense to warn the users\nthat their config setting has no effect.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/remote.c | 3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 5591cef775..3410ea19c7 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -315,6 +315,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t\t\tinfo->rebase = REBASE_MERGES;\n \t\t\telse if (!strcmp(value, \"interactive\"))\n \t\t\t\tinfo->rebase = INTERACTIVE_REBASE;\n+\t\t\telse\n+\t\t\t\twarning(_(\"unhandled branch.%s.rebase=%s\"),\n+\t\t\t\t\tname, value);\n \t\t}\n \t}\n \treturn 0;\n-- \ngitgitgadget\n\n"},{"id":"386918","messageId":"0c8bfe5d18da5c8c5b3d63270aac3f93e793c69c.1574542243.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 4/8] pull: remove support for `--rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:38Z","receivedAt":"2019-11-23T20:50:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn preparation for `git-rebase--preserve-merges.sh` entering its after\nlife, we remove this (deprecated) option that would still rely on it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config/branch.txt        |  4 ----\n Documentation/config/pull.txt          |  4 ----\n Documentation/git-pull.txt             |  6 +-----\n builtin/pull.c                         | 12 +++---------\n contrib/completion/git-completion.bash |  2 +-\n 5 files changed, 5 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt\nindex a592d522a7..e9986ddd09 100644\n--- a/Documentation/config/branch.txt\n+++ b/Documentation/config/branch.txt\n@@ -85,10 +85,6 @@ When `merges`, pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive`, the rebase is run in interactive mode.\n +\n *NOTE*: this is a possibly dangerous operation; do *not* use\ndiff --git a/Documentation/config/pull.txt b/Documentation/config/pull.txt\nindex b87cab31b3..9f2dea0b34 100644\n--- a/Documentation/config/pull.txt\n+++ b/Documentation/config/pull.txt\n@@ -18,10 +18,6 @@ When `merges`, pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive`, the rebase is run in interactive mode.\n +\n *NOTE*: this is a possibly dangerous operation; do *not* use\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex dfb901f8b8..edda860a9a 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -101,7 +101,7 @@ Options related to merging\n include::merge-options.txt[]\n \n -r::\n---rebase[=false|true|merges|preserve|interactive]::\n+--rebase[=false|true|merges|interactive]::\n \tWhen true, rebase the current branch on top of the upstream\n \tbranch after fetching. If there is a remote-tracking branch\n \tcorresponding to the upstream branch and the upstream branch\n@@ -112,10 +112,6 @@ When set to `merges`, rebase using `git rebase --rebase-merges` so that\n the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When set to `preserve` (deprecated in favor of `merges`), rebase with the\n-`--preserve-merges` option passed to `git rebase` so that locally created\n-merge commits will not be flattened.\n-+\n When false, merge the current branch into the upstream branch.\n +\n When `interactive`, enable the interactive mode of rebase.\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex d25ff13a60..6c4d91d580 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -30,7 +30,6 @@ enum rebase_type {\n \tREBASE_INVALID = -1,\n \tREBASE_FALSE = 0,\n \tREBASE_TRUE,\n-\tREBASE_PRESERVE,\n \tREBASE_MERGES,\n \tREBASE_INTERACTIVE\n };\n@@ -38,9 +37,8 @@ enum rebase_type {\n /**\n  * Parses the value of --rebase. If value is a false value, returns\n  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n- * \"merges\", returns REBASE_MERGES. If value is \"preserve\", returns\n- * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if\n- * fatal is true, otherwise returns REBASE_INVALID.\n+ * \"merges\", returns REBASE_MERGES. If value is a invalid value, dies with\n+ * a fatal error if fatal is true, otherwise returns REBASE_INVALID.\n  */\n static enum rebase_type parse_config_rebase(const char *key, const char *value,\n \t\tint fatal)\n@@ -51,8 +49,6 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value,\n \t\treturn REBASE_FALSE;\n \telse if (v > 0)\n \t\treturn REBASE_TRUE;\n-\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n-\t\treturn REBASE_PRESERVE;\n \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n \t\treturn REBASE_MERGES;\n \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\n@@ -145,7 +141,7 @@ static struct option pull_options[] = {\n \t/* Options passed to git-merge or git-rebase */\n \tOPT_GROUP(N_(\"Options related to merging\")),\n \t{ OPTION_CALLBACK, 'r', \"rebase\", &opt_rebase,\n-\t  \"(false|true|merges|preserve|interactive)\",\n+\t  \"(false|true|merges|interactive)\",\n \t  N_(\"incorporate changes by rebasing rather than merging\"),\n \t  PARSE_OPT_OPTARG, parse_opt_rebase },\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n@@ -848,8 +844,6 @@ static int run_rebase(const struct object_id *curr_head,\n \t/* Options passed to git-rebase */\n \tif (opt_rebase == REBASE_MERGES)\n \t\targv_array_push(&args, \"--rebase-merges\");\n-\telse if (opt_rebase == REBASE_PRESERVE)\n-\t\targv_array_push(&args, \"--preserve-merges\");\n \telse if (opt_rebase == REBASE_INTERACTIVE)\n \t\targv_array_push(&args, \"--interactive\");\n \tif (opt_diffstat)\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 00fbe6c03d..5b37734ef1 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2276,7 +2276,7 @@ __git_complete_config_variable_value ()\n \t\treturn\n \t\t;;\n \tbranch.*.rebase)\n-\t\t__gitcomp \"false true merges preserve interactive\" \"\" \"$cur_\"\n+\t\t__gitcomp \"false true merges interactive\" \"\" \"$cur_\"\n \t\treturn\n \t\t;;\n \tremote.pushdefault)\n-- \ngitgitgadget\n\n"},{"id":"386919","messageId":"b7ba83969da8fd2db4e6074d5044938c05b992fd.1574542243.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 6/8] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:40Z","receivedAt":"2019-11-23T20:50:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe already passed the `--rebase-merges` option to `git rebase` instead,\nnow we make this move permanent.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-svn.txt | 1 -\n git-svn.perl              | 1 -\n 2 files changed, 2 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 6624a14fbd..6cfd48c9d3 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -678,7 +678,6 @@ config key: svn.authorsProg\n --strategy=<strategy>::\n -p::\n --rebase-merges::\n---preserve-merges (DEPRECATED)::\n \tThese are only used with the 'dcommit' and 'rebase' commands.\n +\n Passed directly to 'git rebase' when using 'dcommit' if a\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 4aa208ff5f..f1fa1bc7f7 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -271,7 +271,6 @@ sub _req_svn {\n \t\t\t  'fetch-all|all' => \\$_fetch_all,\n \t\t\t  'dry-run|n' => \\$_dry_run,\n \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n-\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n \t\t\t  %fc_opts } ],\n \t'commit-diff' => [ \\&cmd_commit_diff,\n \t                   'Commit a diff between two trees',\n-- \ngitgitgadget\n\n"},{"id":"386921","messageId":"b614336f3df5f433478eb1c1bdaa443919196347.1574542242.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 3/8] tests: stop testing `git rebase --preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:37Z","receivedAt":"2019-11-23T20:50:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis backend has been deprecated in favor of `git rebase\n--rebase-merges`.\n\nIn preparation for dropping it, let's remove all the regression tests\nthat would need it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n azure-pipelines.yml                       |   2 -\n t/t3404-rebase-interactive.sh             |  76 -----------\n t/t3408-rebase-multi-line.sh              |  10 --\n t/t3409-rebase-preserve-merges.sh         | 127 ------------------\n t/t3410-rebase-preserve-dropped-merges.sh |  90 -------------\n t/t3411-rebase-preserve-around-merges.sh  |  80 ------------\n t/t3412-rebase-root.sh                    |  37 ------\n t/t3414-rebase-preserve-onto.sh           |  85 ------------\n t/t3418-rebase-continue.sh                |  15 ---\n t/t3421-rebase-topology-linear.sh         |  19 ---\n t/t3422-rebase-incompatible-options.sh    |  11 --\n t/t3425-rebase-topology-merges.sh         | 151 ----------------------\n t/t3427-rebase-subtree.sh                 |  19 ---\n t/t5520-pull.sh                           |  18 ---\n t/t7505-prepare-commit-msg-hook.sh        |   1 -\n t/t7517-per-repo-email.sh                 |  13 --\n t/test-lib.sh                             |   4 -\n 17 files changed, 758 deletions(-)\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\ndiff --git a/azure-pipelines.yml b/azure-pipelines.yml\nindex af2a5ea484..c75f27a7fa 100644\n--- a/azure-pipelines.yml\n+++ b/azure-pipelines.yml\n@@ -106,7 +106,6 @@ jobs:\n       HOME: $(Build.SourcesDirectory)\n       MSYSTEM: MINGW64\n       NO_SVN_TESTS: 1\n-      GIT_TEST_SKIP_REBASE_P: 1\n   - powershell: |\n       if (\"$GITFILESHAREPWD\" -ne \"\" -and \"$GITFILESHAREPWD\" -ne \"`$`(gitfileshare.pwd)\") {\n         cmd /c rmdir \"$(Build.SourcesDirectory)\\test-cache\"\n@@ -265,7 +264,6 @@ jobs:\n       HOME: $(Build.SourcesDirectory)\n       MSYSTEM: MINGW64\n       NO_SVN_TESTS: 1\n-      GIT_TEST_SKIP_REBASE_P: 1\n   - powershell: |\n       if (\"$GITFILESHAREPWD\" -ne \"\" -and \"$GITFILESHAREPWD\" -ne \"`$`(gitfileshare.pwd)\") {\n         cmd /c rmdir \"$(Build.SourcesDirectory)\\test-cache\"\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex bf0dc756d2..c14a664604 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -345,82 +345,6 @@ test_expect_success 'retain authorship when squashing' '\n \tgit show HEAD | grep \"^Author: Twerp Snog\"\n '\n \n-test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n-\tHEAD=$(git rev-parse HEAD) &&\n-\tgit rebase -i -p HEAD^ &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $HEAD = $(git rev-parse HEAD)\n-'\n-\n-test_expect_failure REBASE_P 'exchange two commits with -p' '\n-\tgit checkout H &&\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2\n-\t) &&\n-\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n-\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n-'\n-\n-test_expect_success REBASE_P 'preserve merges with -p' '\n-\tgit checkout -b to-be-preserved master^ &&\n-\t: > unrelated-file &&\n-\tgit add unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m \"unrelated\" &&\n-\tgit checkout -b another-branch master &&\n-\techo B > file1 &&\n-\ttest_tick &&\n-\tgit commit -m J file1 &&\n-\ttest_tick &&\n-\tgit merge to-be-preserved &&\n-\techo C > file1 &&\n-\ttest_tick &&\n-\tgit commit -m K file1 &&\n-\techo D > file1 &&\n-\ttest_tick &&\n-\tgit commit -m L1 file1 &&\n-\tgit checkout HEAD^ &&\n-\techo 1 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2 unrelated-file &&\n-\ttest_tick &&\n-\tgit merge another-branch &&\n-\techo E > file1 &&\n-\ttest_tick &&\n-\tgit commit -m M file1 &&\n-\tgit checkout -b to-be-rebased &&\n-\ttest_tick &&\n-\tgit rebase -i -p --onto branch1 master &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&\n-\ttest $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&\n-\ttest $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&\n-\ttest $(git show HEAD~5:file1) = B &&\n-\ttest $(git show HEAD~3:file1) = C &&\n-\ttest $(git show HEAD:file1) = E &&\n-\ttest $(git show HEAD:unrelated-file) = 1\n-'\n-\n-test_expect_success REBASE_P 'edit ancestor with -p' '\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3\n-\t) &&\n-\techo 2 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2-modified --amend unrelated-file &&\n-\tgit rebase --continue &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $(git show HEAD:unrelated-file) = 2\n-'\n-\n test_expect_success '--continue tries to commit' '\n \tgit reset --hard D &&\n \ttest_tick &&\ndiff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh\nindex d2bd7c17b0..126845a97c 100755\n--- a/t/t3408-rebase-multi-line.sh\n+++ b/t/t3408-rebase-multi-line.sh\n@@ -52,14 +52,4 @@ test_expect_success rebase '\n \ttest_cmp expect actual\n \n '\n-test_expect_success REBASE_P rebasep '\n-\n-\tgit checkout side-merge &&\n-\tgit rebase -p side &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual &&\n-\tgit cat-file commit side-merge-original | sed -e \"1,/^\\$/d\" >expect &&\n-\ttest_cmp expect actual\n-\n-'\n-\n test_done\ndiff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh\ndeleted file mode 100755\nindex 3b340f1ece..0000000000\n--- a/t/t3409-rebase-preserve-merges.sh\n+++ /dev/null\n@@ -1,127 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright(C) 2008 Stephen Habermann & Andreas Ericsson\n-#\n-test_description='git rebase -p should preserve merges\n-\n-Run \"git rebase -p\" and check that merges are properly carried along\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-GIT_AUTHOR_EMAIL=bogus_email_address\n-export GIT_AUTHOR_EMAIL\n-\n-# Clone 2 (conflicting merge):\n-#\n-# A1--A2--B3   <-- origin/master\n-#  \\       \\\n-#   B1------M  <-- topic\n-#    \\\n-#     B2       <-- origin/topic\n-#\n-# Clone 3 (no-ff merge):\n-#\n-# A1--A2--B3   <-- origin/master\n-#  \\\n-#   B1------M  <-- topic\n-#    \\     /\n-#     \\--A3    <-- topic2\n-#      \\\n-#       B2     <-- origin/topic\n-#\n-# Clone 4 (same as Clone 3)\n-\n-test_expect_success 'setup for merge-preserving rebase' \\\n-\t'echo First > A &&\n-\tgit add A &&\n-\tgit commit -m \"Add A1\" &&\n-\tgit checkout -b topic &&\n-\techo Second > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add B1\" &&\n-\tgit checkout -f master &&\n-\techo Third >> A &&\n-\tgit commit -a -m \"Modify A2\" &&\n-\techo Fifth > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add different B\" &&\n-\n-\tgit clone ./. clone2 &&\n-\t(\n-\t\tcd clone2 &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\ttest_must_fail git merge origin/master &&\n-\t\techo Resolved >B &&\n-\t\tgit add B &&\n-\t\tgit commit -m \"Merge origin/master into topic\"\n-\t) &&\n-\n-\tgit clone ./. clone3 &&\n-\t(\n-\t\tcd clone3 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit clone ./. clone4 &&\n-\t(\n-\t\tcd clone4 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit checkout topic &&\n-\techo Fourth >> B &&\n-\tgit commit -a -m \"Modify B2\"\n-'\n-\n-test_expect_success '--continue works after a conflict' '\n-\t(\n-\tcd clone2 &&\n-\tgit fetch &&\n-\ttest_must_fail git rebase -p origin/topic &&\n-\ttest 2 = $(git ls-files B | wc -l) &&\n-\techo Resolved again > B &&\n-\ttest_must_fail git rebase --continue &&\n-\tgrep \"^@@@ \" .git/rebase-merge/patch &&\n-\tgit add B &&\n-\tgit rebase --continue &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Add different\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge origin\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p preserves no-ff merges' '\n-\t(\n-\tcd clone3 &&\n-\tgit fetch &&\n-\tgit rebase -p origin/topic &&\n-\ttest 3 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge branch\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p ignores merge.log config' '\n-\t(\n-\tcd clone4 &&\n-\tgit fetch &&\n-\tgit -c merge.log=1 rebase -p origin/topic &&\n-\techo >expected &&\n-\tgit log --format=\"%b\" -1 >current &&\n-\ttest_cmp expected current\n-\t)\n-'\n-\n-test_done\ndiff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh\ndeleted file mode 100755\nindex 2e29866993..0000000000\n--- a/t/t3410-rebase-preserve-dropped-merges.sh\n+++ /dev/null\n@@ -1,90 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with preserve merges and ensures commits\n-dropped by the --cherry-pick flag have their childrens parents\n-rewritten.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-# set up two branches like this:\n-#\n-# A - B - C - D - E\n-#   \\\n-#     F - G - H\n-#       \\\n-#         I\n-#\n-# where B, D and G touch the same file.\n-\n-test_expect_success 'setup' '\n-\ttest_commit A file1 &&\n-\ttest_commit B file1 1 &&\n-\ttest_commit C file2 &&\n-\ttest_commit D file1 2 &&\n-\ttest_commit E file3 &&\n-\tgit checkout A &&\n-\ttest_commit F file4 &&\n-\ttest_commit G file1 3 &&\n-\ttest_commit H file5 &&\n-\tgit checkout F &&\n-\ttest_commit I file6\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L \\        -->   L\n-#       \\            |               \\\n-#         I -- G2 -- J -- K           I -- K\n-# G2 = same changes as G\n-test_expect_success 'skip same-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G2 file1 3 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J file1 23 &&\n-\ttest_commit K file7 file7 &&\n-\tgit rebase -i -p L &&\n-\ttest $(git rev-parse HEAD^^) = $(git rev-parse L) &&\n-\ttest \"23\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L2 \\        -->   L2\n-#       \\             |                \\\n-#         I -- G3 --- J2 -- K2           I -- G3 -- K2\n-# G2 = different changes as G\n-test_expect_success 'keep different-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L2 file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G3 file1 4 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J2 file1 24 &&\n-\ttest_commit K2 file7 file7 &&\n-\ttest_must_fail git rebase -i -p L2 &&\n-\techo 234 > file1 &&\n-\tgit add file1 &&\n-\tgit rebase --continue &&\n-\ttest $(git rev-parse HEAD^^^) = $(git rev-parse L2) &&\n-\ttest \"234\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-test_done\ndiff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh\ndeleted file mode 100755\nindex fb45e7bf7b..0000000000\n--- a/t/t3411-rebase-preserve-around-merges.sh\n+++ /dev/null\n@@ -1,80 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with -p and tries to squash a commit from after\n-a merge to before the merge.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-set_fake_editor\n-\n-# set up two branches like this:\n-#\n-# A1 - B1 - D1 - E1 - F1\n-#       \\        /\n-#        -- C1 --\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit D1 &&\n-\ttest_merge E1 C1 &&\n-\ttest_commit F1\n-'\n-\n-# Should result in:\n-#\n-# A1 - B1 - D2 - E2\n-#       \\        /\n-#        -- C1 --\n-#\n-test_expect_success 'squash F1 into D1' '\n-\tFAKE_LINES=\"1 squash 4 2 3\" git rebase -i -p B1 &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse C1)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse B1)\" &&\n-\tgit tag E2\n-'\n-\n-# Start with:\n-#\n-# A1 - B1 - D2 - E2\n-#  \\\n-#   G1 ---- L1 ---- M1\n-#    \\             /\n-#     H1 -- J1 -- K1\n-#      \\         /\n-#        -- I1 --\n-#\n-# And rebase G1..M1 onto E2\n-\n-test_expect_success 'rebase two levels of merge' '\n-\tgit checkout A1 &&\n-\ttest_commit G1 &&\n-\ttest_commit H1 &&\n-\ttest_commit I1 &&\n-\tgit checkout -b branch3 H1 &&\n-\ttest_commit J1 &&\n-\ttest_merge K1 I1 &&\n-\tgit checkout -b branch2 G1 &&\n-\ttest_commit L1 &&\n-\ttest_merge M1 K1 &&\n-\tGIT_EDITOR=: git rebase -i -p E2 &&\n-\ttest \"$(git rev-parse HEAD~3)\" = \"$(git rev-parse E2)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse HEAD^2^2~2)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse HEAD^2^2^1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh\nindex 21632a984e..7ba343198a 100755\n--- a/t/t3412-rebase-root.sh\n+++ b/t/t3412-rebase-root.sh\n@@ -86,17 +86,6 @@ test_expect_success 'pre-rebase got correct input (4)' '\n \ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,work4\n '\n \n-test_expect_success REBASE_P 'rebase -i -p with linear history' '\n-\tgit checkout -b work5 other &&\n-\tgit rebase -i -p --root --onto master &&\n-\tgit log --pretty=tformat:\"%s\" > rebased5 &&\n-\ttest_cmp expect rebased5\n-'\n-\n-test_expect_success REBASE_P 'pre-rebase got correct input (5)' '\n-\ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,\n-'\n-\n test_expect_success 'set up merge history' '\n \tgit checkout other^ &&\n \tgit checkout -b side &&\n@@ -120,13 +109,6 @@ commit work6~4\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with merge' '\n-\tgit checkout -b work6 other &&\n-\tgit rebase -i -p --root --onto master &&\n-\tlog_with_names work6 > rebased6 &&\n-\ttest_cmp expect-side rebased6\n-'\n-\n test_expect_success 'set up second root and merge' '\n \tgit symbolic-ref HEAD refs/heads/third &&\n \trm .git/index &&\n@@ -155,13 +137,6 @@ commit work7~5\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with two roots' '\n-\tgit checkout -b work7 other &&\n-\tgit rebase -i -p --root --onto master &&\n-\tlog_with_names work7 > rebased7 &&\n-\ttest_cmp expect-third rebased7\n-'\n-\n test_expect_success 'setup pre-rebase hook that fails' '\n \tmkdir -p .git/hooks &&\n \tcat >.git/hooks/pre-rebase <<EOF &&\n@@ -261,21 +236,9 @@ commit conflict3~6\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' '\n-\tgit checkout -b conflict3 other &&\n-\ttest_must_fail git rebase -i -p --root --onto master &&\n-\tgit ls-files -u | grep \"B$\"\n-'\n-\n test_expect_success 'fix the conflict' '\n \techo 3 > B &&\n \tgit add B\n '\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (second part)' '\n-\tgit rebase --continue &&\n-\tlog_with_names conflict3 >out &&\n-\ttest_cmp expect-conflict-p out\n-'\n-\n test_done\ndiff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh\ndeleted file mode 100755\nindex 72e04b5386..0000000000\n--- a/t/t3414-rebase-preserve-onto.sh\n+++ /dev/null\n@@ -1,85 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2009 Greg Price\n-#\n-\n-test_description='git rebase -p should respect --onto\n-\n-In a rebase with --onto, we should rewrite all the commits that\n-aren'\"'\"'t on top of $ONTO, even if they are on top of $UPSTREAM.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-# Set up branches like this:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    H1\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\ttest_commit D1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit E1 &&\n-\ttest_commit F1 &&\n-\ttest_merge G1 D1 &&\n-\tgit reset --hard A1 &&\n-\ttest_commit H1\n-'\n-\n-# Now rebase merge G1 from both branches' base B1, both should move:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\\n-#     H1---E2---F2---G2\n-#      \\             /\n-#       \\--C2---D2--/\n-\n-test_expect_success 'rebase from B1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 B1 &&\n-\ttest \"$(git rev-parse HEAD^1^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse H1)\"\n-'\n-\n-# On the other hand if rebase from E1 which is within one branch,\n-# then the other branch stays:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\             \\\n-#     H1-----F3-----G3\n-\n-test_expect_success 'rebase from E1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 E1 &&\n-\ttest \"$(git rev-parse HEAD^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse D1)\"\n-'\n-\n-# And the same if we rebase from a commit in the second-parent branch.\n-# A1---B1---E1---F1----G1\n-#  \\    \\          \\   /\n-#   \\    \\--C1---D1-\\-/\n-#    \\               \\\n-#     H1------D3------G4\n-\n-test_expect_success 'rebase from C1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rev-list --first-parent --pretty=oneline C1..G1 &&\n-\tgit rebase -p --onto H1 C1 &&\n-\ttest \"$(git rev-parse HEAD^2^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^1)\" = \"$(git rev-parse F1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex 7a2da972fd..ce78b6b97b 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -106,20 +106,6 @@ test_expect_success 'rebase -i --continue handles merge strategy and options' '\n \ttest -f funny.was.run\n '\n \n-test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '\n-\trm -fr .git/rebase-* &&\n-\tgit reset --hard commit-new-file-F3-on-topic-branch &&\n-\ttest_commit theirs-to-merge &&\n-\tgit reset --hard HEAD^ &&\n-\ttest_commit some-commit &&\n-\ttest_tick &&\n-\tgit merge --no-ff theirs-to-merge &&\n-\tFAKE_LINES=\"1 edit 2 3\" git rebase -i -f -p -m \\\n-\t\t-s recursive --strategy-option=theirs HEAD~2 &&\n-\ttest_commit force-change &&\n-\tgit rebase --continue\n-'\n-\n test_expect_success 'rebase -r passes merge strategy options correctly' '\n \trm -fr .git/rebase-* &&\n \tgit reset --hard commit-new-file-F3-on-topic-branch &&\n@@ -255,7 +241,6 @@ test_rerere_autoupdate\n test_rerere_autoupdate -m\n GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR\n test_rerere_autoupdate -i\n-test_have_prereq !REBASE_P || test_rerere_autoupdate --preserve-merges\n unset GIT_SEQUENCE_EDITOR\n \n test_expect_success 'the todo command \"break\" works' '\ndiff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh\nindex b847064f91..40375aff58 100755\n--- a/t/t3421-rebase-topology-linear.sh\n+++ b/t/t3421-rebase-topology-linear.sh\n@@ -29,7 +29,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_expect_success 'setup branches and remote tracking' '\n \tgit tag -l >tags &&\n@@ -53,7 +52,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -70,7 +68,6 @@ test_run_rebase success ''\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -87,7 +84,6 @@ test_run_rebase success ''\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -102,7 +98,6 @@ test_run_rebase success ''\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n #       f\n #      /\n@@ -142,7 +137,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -157,7 +151,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -172,7 +165,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -187,7 +179,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n # a---b---c---j!\n #      \\\n@@ -215,7 +206,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -230,7 +220,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -245,7 +234,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n test_run_rebase success --rebase-merges\n \n #       m\n@@ -285,7 +273,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -300,7 +287,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -315,7 +301,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -331,7 +316,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -346,7 +330,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -360,7 +343,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -375,6 +357,5 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_done\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex 50e7960702..c1c9772ac2 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -65,15 +65,4 @@ test_rebase_am_only --ignore-whitespace\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-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --signoff A\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'--preserve-merges incompatible with --rebase-merges' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --rebase-merges A\n-'\n-\n test_done\ndiff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh\nindex fd8efe84fe..88874c1e50 100755\n--- a/t/t3425-rebase-topology-merges.sh\n+++ b/t/t3425-rebase-topology-merges.sh\n@@ -106,155 +106,4 @@ test_run_rebase success 'd n o e' ''\n test_run_rebase success 'd n o e' -m\n test_run_rebase success 'd n o e' -i\n \n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-test_expect_success \"rebase -p is no-op in non-linear history\" \"\n-\treset_rebase &&\n-\tgit rebase -p d w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p is no-op when base inside second parent\" \"\n-\treset_rebase &&\n-\tgit rebase -p e w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_failure \"rebase -p --root on non-linear history is a no-op\" \"\n-\treset_rebase &&\n-\tgit rebase -p --root w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates merge from side branch\" \"\n-\treset_rebase &&\n-\tgit rebase -p z w &&\n-\ttest_cmp_rev z HEAD^ &&\n-\ttest_cmp_rev w^2 HEAD^2\n-\"\n-\n-test_expect_success \"rebase -p re-creates internal merge\" \"\n-\treset_rebase &&\n-\tgit rebase -p c w &&\n-\ttest_cmp_rev c HEAD~4 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~3 &&\n-\ttest_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p can re-create two branches on onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto c d w &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev c HEAD^2^ &&\n-\ttest_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-#       f\n-#      /\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--i\n-#        \\       \\\n-#         e-------u\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for patch-equivalence tests' '\n-\tgit checkout e &&\n-\ttest_merge u i\n-'\n-\n-test_expect_success \"rebase -p re-creates history around dropped commit matching upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p h u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history drops patches in upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto f h u &&\n-\ttest_cmp_rev f HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history does not drop patches in onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto h f u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2~2 HEAD~2 &&\n-\ttest_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD\n-\"\n-\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--s\n-#        \\   \\ /\n-#         \\   X\n-#          \\ / \\\n-#           e---t\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for dropping whole side' '\n-\tgit checkout gp &&\n-\ttest_merge s e &&\n-\tgit checkout e &&\n-\ttest_merge t gp\n-'\n-\n-test_expect_failure \"rebase -p drops merge commit when entire first-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h s &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-test_expect_success \"rebase -p drops merge commit when entire second-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h t &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-# a---b---c\n-#      \\\n-#       d---e\n-#        \\   \\\n-#         n---r\n-#          \\\n-#           o\n-#\n-# r = tree-same with n\n-test_expect_success 'setup of non-linear-history for empty commits' '\n-\tgit checkout n &&\n-\tgit merge --no-commit e &&\n-\tgit reset n . &&\n-\tgit commit -m r &&\n-\tgit reset --hard &&\n-\tgit clean -f &&\n-\tgit tag r\n-'\n-\n-test_expect_success \"rebase -p re-creates empty internal merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p c r &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates empty merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p o r &&\n-\ttest_cmp_rev e HEAD^2 &&\n-\ttest_cmp_rev o HEAD^ &&\n-\ttest_revision_subjects 'r' HEAD\n-\"\n-\n test_done\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex bec48e6a1f..ffe385e493 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -66,25 +66,6 @@ test_expect_success 'setup' '\n \tgit commit -m \"Empty commit\" --allow-empty\n '\n \n-# FAILURE: Does not preserve master4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"master4\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n-'\n-\n-# FAILURE: Does not preserve master4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"master4\" &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n-'\n-\n test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex 41b799e336..e5f679af33 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -461,15 +461,6 @@ test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '\n \ttest file3 = \"$(git show HEAD:file3.t)\"\n '\n \n-test_expect_success REBASE_P \\\n-\t'pull.rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n-\tgit pull . copy &&\n-\ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse keep-merge)\"\n-'\n-\n test_expect_success 'pull.rebase=interactive' '\n \twrite_script \"$TRASH_DIRECTORY/fake-editor\" <<-\\EOF &&\n \techo I was here >fake.out &&\n@@ -515,15 +506,6 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \ttest file3 = \"$(git show HEAD:file3.t)\"\n '\n \n-test_expect_success REBASE_P \\\n-\t'--rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n-\tgit pull --rebase=preserve . copy &&\n-\ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse keep-merge)\"\n-'\n-\n test_expect_success '--rebase=invalid fails' '\n \tgit reset --hard before-preserve-rebase &&\n \t! git pull --rebase=invalid . copy\ndiff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh\nindex 94f85cdf83..1b4a7725fb 100755\n--- a/t/t7505-prepare-commit-msg-hook.sh\n+++ b/t/t7505-prepare-commit-msg-hook.sh\n@@ -247,7 +247,6 @@ test_rebase () {\n }\n \n test_rebase success\n-test_have_prereq !REBASE_P || test_rebase success -p\n \n test_expect_success 'with hook (cherry-pick)' '\n \ttest_when_finished \"git checkout -f master\" &&\ndiff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\nindex b2401cec3e..0dec7f756b 100755\n--- a/t/t7517-per-repo-email.sh\n+++ b/t/t7517-per-repo-email.sh\n@@ -72,19 +72,6 @@ test_expect_success 'noop interactive rebase does not care about ident' '\n \tgit rebase -i HEAD^\n '\n \n-test_expect_success REBASE_P \\\n-\t'fast-forward rebase does not care about ident (preserve)' '\n-\tgit checkout -B tmp side-without-commit &&\n-\tgit rebase -p master\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'non-fast-forward rebase refuses to write commits (preserve)' '\n-\ttest_when_finished \"git rebase --abort || true\" &&\n-\tgit checkout -B tmp side-with-commit &&\n-\ttest_must_fail git rebase -p master\n-'\n-\n test_expect_success 'author.name overrides user.name' '\n \ttest_config user.name user &&\n \ttest_config user.email user@example.com &&\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex 46c4440843..0ef620f975 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -1634,7 +1634,3 @@ test_lazy_prereq CURL '\n test_lazy_prereq SHA1 '\n \ttest $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n '\n-\n-test_lazy_prereq REBASE_P '\n-\ttest -z \"$GIT_TEST_SKIP_REBASE_P\"\n-'\n-- \ngitgitgadget\n\n"},{"id":"386920","messageId":"45fee72059d04d7770deb22ef605d6e26bbe762d.1574542243.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 8/8] remote: no longer claim that branch.*.rebase=preserve is a thing","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:42Z","receivedAt":"2019-11-23T20:50:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/remote.c | 2 --\n 1 file changed, 2 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 3410ea19c7..afe9af09e9 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -309,8 +309,6 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t\tint v = git_parse_maybe_bool(value);\n \t\t\tif (v >= 0)\n \t\t\t\tinfo->rebase = v;\n-\t\t\telse if (!strcmp(value, \"preserve\"))\n-\t\t\t\tinfo->rebase = NORMAL_REBASE;\n \t\t\telse if (!strcmp(value, \"merges\"))\n \t\t\t\tinfo->rebase = REBASE_MERGES;\n \t\t\telse if (!strcmp(value, \"interactive\"))\n-- \ngitgitgadget\n"},{"id":"386922","messageId":"634e4141e9737835f758c28784d8cd452b0d12f9.1574542243.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 7/8] rebase: drop the internal `rebase--interactive` command","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:41Z","receivedAt":"2019-11-23T20:50:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIt was only used by the `--preserve-merges` backend, which we just\nremoved.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c | 181 -----------------------------------------------\n git.c            |   1 -\n 2 files changed, 182 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 2970a9ae47..69ec2da624 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -142,81 +142,6 @@ static const char *action_names[] = { \"undefined\",\n \t\t\t\t      \"edit_todo\",\n \t\t\t\t      \"show_current_patch\" };\n \n-static int add_exec_commands(struct string_list *commands)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\ttodo_list_add_exec_commands(&todo_list, commands);\n-\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int rearrange_squash_in_todo_file(void)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res = 0;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_rearrange_squash(&todo_list);\n-\tif (!res)\n-\t\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int transform_todo_file(unsigned flags)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_write_to_file(the_repository, &todo_list, todo_file,\n-\t\t\t\t      NULL, NULL, -1, flags);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -408,24 +333,6 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \n \t\tbreak;\n \t}\n-\tcase ACTION_SHORTEN_OIDS:\n-\tcase ACTION_EXPAND_OIDS:\n-\t\tret = transform_todo_file(flags);\n-\t\tbreak;\n-\tcase ACTION_CHECK_TODO_LIST:\n-\t\tret = check_todo_list_from_file(the_repository);\n-\t\tbreak;\n-\tcase ACTION_REARRANGE_SQUASH:\n-\t\tret = rearrange_squash_in_todo_file();\n-\t\tbreak;\n-\tcase ACTION_ADD_EXEC: {\n-\t\tstruct string_list commands = STRING_LIST_INIT_DUP;\n-\n-\t\tsplit_exec_commands(opts->cmd, &commands);\n-\t\tret = add_exec_commands(&commands);\n-\t\tstring_list_clear(&commands, 0);\n-\t\tbreak;\n-\t}\n \tdefault:\n \t\tBUG(\"invalid command '%d'\", command);\n \t}\n@@ -433,94 +340,6 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \treturn ret;\n }\n \n-static const char * const builtin_rebase_interactive_usage[] = {\n-\tN_(\"git rebase--interactive [<options>]\"),\n-\tNULL\n-};\n-\n-int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n-{\n-\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n-\tstruct object_id squash_onto = null_oid;\n-\tenum action command = ACTION_NONE;\n-\tstruct option options[] = {\n-\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n-\t\t\t   REBASE_FORCE),\n-\t\tOPT_BOOL(0, \"keep-empty\", &opts.keep_empty, N_(\"keep empty commits\")),\n-\t\tOPT_BOOL(0, \"allow-empty-message\", &opts.allow_empty_message,\n-\t\t\t N_(\"allow commits with empty messages\")),\n-\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase merge commits\")),\n-\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n-\t\t\t N_(\"keep original branch points of cousins\")),\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_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-\t\tOPT_CMDMODE(0, \"continue\", &command, N_(\"continue rebase\"),\n-\t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &command, N_(\"skip commit\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &command, N_(\"edit the todo list\"),\n-\t\t\t    ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &command, N_(\"show the current patch\"),\n-\t\t\t    ACTION_SHOW_CURRENT_PATCH),\n-\t\tOPT_CMDMODE(0, \"shorten-ids\", &command,\n-\t\t\tN_(\"shorten commit ids in the todo list\"), ACTION_SHORTEN_OIDS),\n-\t\tOPT_CMDMODE(0, \"expand-ids\", &command,\n-\t\t\tN_(\"expand commit ids in the todo list\"), ACTION_EXPAND_OIDS),\n-\t\tOPT_CMDMODE(0, \"check-todo-list\", &command,\n-\t\t\tN_(\"check the todo list\"), ACTION_CHECK_TODO_LIST),\n-\t\tOPT_CMDMODE(0, \"rearrange-squash\", &command,\n-\t\t\tN_(\"rearrange fixup/squash lines\"), ACTION_REARRANGE_SQUASH),\n-\t\tOPT_CMDMODE(0, \"add-exec-commands\", &command,\n-\t\t\tN_(\"insert exec commands in todo list\"), ACTION_ADD_EXEC),\n-\t\t{ OPTION_CALLBACK, 0, \"onto\", &opts.onto, N_(\"onto\"), N_(\"onto\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"restrict-revision\", &opts.restrict_revision,\n-\t\t  N_(\"restrict-revision\"), N_(\"restrict revision\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"squash-onto\", &squash_onto, N_(\"squash-onto\"),\n-\t\t  N_(\"squash onto\"), PARSE_OPT_NONEG, parse_opt_object_id, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"upstream\", &opts.upstream, N_(\"upstream\"),\n-\t\t  N_(\"the upstream commit\"), PARSE_OPT_NONEG, parse_opt_commit,\n-\t\t  0 },\n-\t\tOPT_STRING(0, \"head-name\", &opts.head_name, N_(\"head-name\"), N_(\"head name\")),\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_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-\t\t\t   N_(\"strategy options\")),\n-\t\tOPT_STRING(0, \"switch-to\", &opts.switch_to, N_(\"switch-to\"),\n-\t\t\t   N_(\"the branch or commit to checkout\")),\n-\t\tOPT_STRING(0, \"onto-name\", &opts.onto_name, N_(\"onto-name\"), N_(\"onto name\")),\n-\t\tOPT_STRING(0, \"cmd\", &opts.cmd, N_(\"cmd\"), N_(\"the command to run\")),\n-\t\tOPT_RERERE_AUTOUPDATE(&opts.allow_rerere_autoupdate),\n-\t\tOPT_BOOL(0, \"reschedule-failed-exec\", &opts.reschedule_failed_exec,\n-\t\t\t N_(\"automatically re-schedule any `exec` that fails\")),\n-\t\tOPT_END()\n-\t};\n-\n-\topts.rebase_cousins = -1;\n-\n-\tif (argc == 1)\n-\t\tusage_with_options(builtin_rebase_interactive_usage, options);\n-\n-\targc = parse_options(argc, argv, prefix, options,\n-\t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n-\n-\tif (!is_null_oid(&squash_onto))\n-\t\topts.squash_onto = &squash_onto;\n-\n-\tif (opts.rebase_cousins >= 0 && !opts.rebase_merges)\n-\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n-\t\t\t  \"--rebase-merges\"));\n-\n-\treturn !!run_rebase_interactive(&opts, command);\n-}\n-\n static int is_interactive(struct rebase_options *opts)\n {\n \treturn opts->type == REBASE_INTERACTIVE;\ndiff --git a/git.c b/git.c\nindex ce6ab0ece2..015e155dcd 100644\n--- a/git.c\n+++ b/git.c\n@@ -551,7 +551,6 @@ static struct cmd_struct commands[] = {\n \t{ \"range-diff\", cmd_range_diff, RUN_SETUP | USE_PAGER },\n \t{ \"read-tree\", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},\n \t{ \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n-\t{ \"rebase--interactive\", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"receive-pack\", cmd_receive_pack },\n \t{ \"reflog\", cmd_reflog, RUN_SETUP },\n \t{ \"remote\", cmd_remote, RUN_SETUP },\n-- \ngitgitgadget\n\n"},{"id":"386923","messageId":"14e242b3cf994159382045fd3623ddb80cbe96ab.1574542243.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH 5/8] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-11-23T20:50:39Z","receivedAt":"2019-11-23T20:50:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis option was deprecated in favor of `--rebase-merges` some time ago,\nand now we retire it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .gitignore                     |    1 -\n Documentation/git-rebase.txt   |   47 --\n Makefile                       |    2 -\n builtin/rebase.c               |  135 +---\n git-rebase--preserve-merges.sh | 1067 --------------------------------\n 5 files changed, 6 insertions(+), 1246 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 89b3b79c1a..9989dce1d2 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -123,7 +123,6 @@\n /git-range-diff\n /git-read-tree\n /git-rebase\n-/git-rebase--preserve-merges\n /git-receive-pack\n /git-reflog\n /git-remote\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 639a4179d1..7cced2f272 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -442,29 +442,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s\n the `rebase-cousins` mode is turned on, such commits are instead rebased\n onto `<upstream>` (or `<onto>`, if specified).\n +\n-The `--rebase-merges` mode is similar in spirit to the deprecated\n-`--preserve-merges`, but in contrast to that option works well in interactive\n-rebases: commits can be reordered, inserted and dropped at will.\n-+\n It is currently only possible to recreate the merge commits using the\n `recursive` merge strategy; Different merge strategies can be used only via\n explicit `exec git merge -s <strategy> [...]` commands.\n +\n See also REBASING MERGES and INCOMPATIBLE OPTIONS below.\n \n--p::\n---preserve-merges::\n-\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n-\tinstead of flattening the history by replaying commits a merge commit\n-\tintroduces. Merge conflict resolutions or manual amendments to merge\n-\tcommits are not preserved.\n-+\n-This uses the `--interactive` machinery internally, but combining it\n-with the `--interactive` option explicitly is generally not a good\n-idea unless you know what you are doing (see BUGS below).\n-+\n-See also INCOMPATIBLE OPTIONS below.\n-\n -x <cmd>::\n --exec <cmd>::\n \tAppend \"exec <cmd>\" after each line creating a commit in the\n@@ -496,9 +479,6 @@ See also INCOMPATIBLE OPTIONS below.\n \tthe root commit(s) on a branch.  When used with --onto, it\n \twill skip changes already contained in <newbase> (instead of\n \t<upstream>) whereas without --onto it will operate on every change.\n-\tWhen used together with both --onto and --preserve-merges,\n-\t'all' root commits will be rewritten to have <newbase> as parent\n-\tinstead.\n +\n See also INCOMPATIBLE OPTIONS below.\n \n@@ -553,7 +533,6 @@ are incompatible with the following options:\n  * --allow-empty-message\n  * --[no-]autosquash\n  * --rebase-merges\n- * --preserve-merges\n  * --interactive\n  * --exec\n  * --keep-empty\n@@ -562,9 +541,6 @@ are incompatible with the following options:\n \n In addition, the following pairs of options are incompatible:\n \n- * --preserve-merges and --interactive\n- * --preserve-merges and --signoff\n- * --preserve-merges and --rebase-merges\n  * --keep-base and --onto\n  * --keep-base and --root\n \n@@ -1048,29 +1024,6 @@ merge tlsv1.3\n merge cmake\n ------------\n \n-BUGS\n-----\n-The todo list presented by the deprecated `--preserve-merges --interactive`\n-does not represent the topology of the revision graph (use `--rebase-merges`\n-instead).  Editing commits and rewording their commit messages should work\n-fine, but attempts to reorder commits tend to produce counterintuitive results.\n-Use `--rebase-merges` in such scenarios instead.\n-\n-For example, an attempt to rearrange\n-------------\n-1 --- 2 --- 3 --- 4 --- 5\n-------------\n-to\n-------------\n-1 --- 2 --- 4 --- 3 --- 5\n-------------\n-by moving the \"pick 4\" line will result in the following history:\n-------------\n-\t3\n-       /\n-1 --- 2 --- 4 --- 5\n-------------\n-\n GIT\n ---\n Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex 58b92af54b..e2c26843e2 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -616,7 +616,6 @@ SCRIPT_SH += git-web--browse.sh\n \n SCRIPT_LIB += git-mergetool--lib\n SCRIPT_LIB += git-parse-remote\n-SCRIPT_LIB += git-rebase--preserve-merges\n SCRIPT_LIB += git-sh-setup\n SCRIPT_LIB += git-sh-i18n\n \n@@ -2522,7 +2521,6 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \\\n LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)\n LOCALIZED_SH = $(SCRIPT_SH)\n LOCALIZED_SH += git-parse-remote.sh\n-LOCALIZED_SH += git-rebase--preserve-merges.sh\n LOCALIZED_SH += git-sh-setup.sh\n LOCALIZED_PERL = $(SCRIPT_PERL)\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex e755087b0f..2970a9ae47 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -46,8 +46,7 @@ enum rebase_type {\n \tREBASE_UNSPECIFIED = -1,\n \tREBASE_AM,\n \tREBASE_MERGE,\n-\tREBASE_INTERACTIVE,\n-\tREBASE_PRESERVE_MERGES\n+\tREBASE_INTERACTIVE\n };\n \n struct rebase_options {\n@@ -524,8 +523,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \n static int is_interactive(struct rebase_options *opts)\n {\n-\treturn opts->type == REBASE_INTERACTIVE ||\n-\t\topts->type == REBASE_PRESERVE_MERGES;\n+\treturn opts->type == REBASE_INTERACTIVE;\n }\n \n static void imply_interactive(struct rebase_options *opts, const char *option)\n@@ -535,7 +533,6 @@ static void imply_interactive(struct rebase_options *opts, const char *option)\n \t\tdie(_(\"%s requires an interactive rebase\"), option);\n \t\tbreak;\n \tcase REBASE_INTERACTIVE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\tbreak;\n \tcase REBASE_MERGE:\n \t\t/* we now implement --merge via --interactive */\n@@ -776,17 +773,6 @@ static struct commit *peel_committish(const char *name)\n \treturn (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);\n }\n \n-static void add_var(struct strbuf *buf, const char *name, const char *value)\n-{\n-\tif (!value)\n-\t\tstrbuf_addf(buf, \"unset %s; \", name);\n-\telse {\n-\t\tstrbuf_addf(buf, \"%s=\", name);\n-\t\tsq_quote_buf(buf, value);\n-\t\tstrbuf_addstr(buf, \"; \");\n-\t}\n-}\n-\n #define GIT_REFLOG_ACTION_ENVIRONMENT \"GIT_REFLOG_ACTION\"\n \n #define RESET_HEAD_DETACH (1<<0)\n@@ -1076,10 +1062,8 @@ static int run_am(struct rebase_options *opts)\n \n static int run_specific_rebase(struct rebase_options *opts, enum action action)\n {\n-\tconst char *argv[] = { NULL, NULL };\n-\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n+\tstruct strbuf script_snippet = STRBUF_INIT;\n \tint status;\n-\tconst char *backend, *backend_func;\n \n \tif (opts->type == REBASE_INTERACTIVE) {\n \t\t/* Run builtin interactive rebase */\n@@ -1096,89 +1080,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t}\n \n \t\tstatus = run_rebase_interactive(opts, action);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tif (opts->type == REBASE_AM) {\n+\t} else if (opts->type == REBASE_AM)\n \t\tstatus = run_am(opts);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tadd_var(&script_snippet, \"GIT_DIR\", absolute_path(get_git_dir()));\n-\tadd_var(&script_snippet, \"state_dir\", opts->state_dir);\n-\n-\tadd_var(&script_snippet, \"upstream_name\", opts->upstream_name);\n-\tadd_var(&script_snippet, \"upstream\", opts->upstream ?\n-\t\toid_to_hex(&opts->upstream->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"head_name\",\n-\t\topts->head_name ? opts->head_name : \"detached HEAD\");\n-\tadd_var(&script_snippet, \"orig_head\", oid_to_hex(&opts->orig_head));\n-\tadd_var(&script_snippet, \"onto\", opts->onto ?\n-\t\toid_to_hex(&opts->onto->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"onto_name\", opts->onto_name);\n-\tadd_var(&script_snippet, \"revisions\", opts->revisions);\n-\tadd_var(&script_snippet, \"restrict_revision\", opts->restrict_revision ?\n-\t\toid_to_hex(&opts->restrict_revision->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"GIT_QUIET\",\n-\t\topts->flags & REBASE_NO_QUIET ? \"\" : \"t\");\n-\tsq_quote_argv_pretty(&buf, opts->git_am_opts.argv);\n-\tadd_var(&script_snippet, \"git_am_opt\", buf.buf);\n-\tstrbuf_release(&buf);\n-\tadd_var(&script_snippet, \"verbose\",\n-\t\topts->flags & REBASE_VERBOSE ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"diffstat\",\n-\t\topts->flags & REBASE_DIFFSTAT ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"force_rebase\",\n-\t\topts->flags & REBASE_FORCE ? \"t\" : \"\");\n-\tif (opts->switch_to)\n-\t\tadd_var(&script_snippet, \"switch_to\", opts->switch_to);\n-\tadd_var(&script_snippet, \"action\", opts->action ? opts->action : \"\");\n-\tadd_var(&script_snippet, \"signoff\", opts->signoff ? \"--signoff\" : \"\");\n-\tadd_var(&script_snippet, \"allow_rerere_autoupdate\",\n-\t\topts->allow_rerere_autoupdate ?\n-\t\t\topts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?\n-\t\t\t\"--rerere-autoupdate\" : \"--no-rerere-autoupdate\" : \"\");\n-\tadd_var(&script_snippet, \"keep_empty\", opts->keep_empty ? \"yes\" : \"\");\n-\tadd_var(&script_snippet, \"autosquash\", opts->autosquash ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"gpg_sign_opt\", opts->gpg_sign_opt);\n-\tadd_var(&script_snippet, \"cmd\", opts->cmd);\n-\tadd_var(&script_snippet, \"allow_empty_message\",\n-\t\topts->allow_empty_message ?  \"--allow-empty-message\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_merges\",\n-\t\topts->rebase_merges ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_cousins\",\n-\t\topts->rebase_cousins ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"strategy\", opts->strategy);\n-\tadd_var(&script_snippet, \"strategy_opts\", opts->strategy_opts);\n-\tadd_var(&script_snippet, \"rebase_root\", opts->root ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"squash_onto\",\n-\t\topts->squash_onto ? oid_to_hex(opts->squash_onto) : \"\");\n-\tadd_var(&script_snippet, \"git_format_patch_opt\",\n-\t\topts->git_format_patch_opt.buf);\n-\n-\tif (is_interactive(opts) &&\n-\t    !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n-\t\tstrbuf_addstr(&script_snippet,\n-\t\t\t      \"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; \");\n-\t\topts->autosquash = 0;\n-\t}\n-\n-\tswitch (opts->type) {\n-\tcase REBASE_PRESERVE_MERGES:\n-\t\tbackend = \"git-rebase--preserve-merges\";\n-\t\tbackend_func = \"git_rebase__preserve_merges\";\n-\t\tbreak;\n-\tdefault:\n+\telse\n \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n-\t\tbreak;\n-\t}\n \n-\tstrbuf_addf(&script_snippet,\n-\t\t    \". git-sh-setup && . %s && %s\", backend, backend_func);\n-\targv[0] = script_snippet.buf;\n-\n-\tstatus = run_command_v_opt(argv, RUN_USING_SHELL);\n-finished_rebase:\n \tif (opts->dont_finish_rebase)\n \t\t; /* do nothing */\n \telse if (opts->type == REBASE_INTERACTIVE)\n@@ -1471,10 +1377,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\tparse_opt_interactive },\n-\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n-\t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n-\t\t\t\t \"ignoring them\"),\n-\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n \t\tOPT_BOOL('k', \"keep-empty\", &options.keep_empty,\n \t\t\t N_(\"preserve empty commits during rebase\")),\n@@ -1537,8 +1439,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n \t\tif (is_directory(buf.buf)) {\n-\t\t\toptions.type = REBASE_PRESERVE_MERGES;\n-\t\t\toptions.flags |= REBASE_INTERACTIVE_EXPLICIT;\n+\t\t\tdie(\"`rebase -p` is no longer supported\");\n \t\t} else {\n \t\t\tstrbuf_reset(&buf);\n \t\t\tstrbuf_addf(&buf, \"%s/interactive\", merge_dir());\n@@ -1568,10 +1469,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \n-\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\twarning(_(\"git rebase --preserve-merges is deprecated. \"\n-\t\t\t  \"Use --rebase-merges instead.\"));\n-\n \tif (keep_base) {\n \t\tif (options.onto_name)\n \t\t\tdie(_(\"cannot combine '--keep-base' with '--onto'\"));\n@@ -1789,7 +1686,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tdie(_(\"--strategy requires --merge or --interactive\"));\n \t\tcase REBASE_MERGE:\n \t\tcase REBASE_INTERACTIVE:\n-\t\tcase REBASE_PRESERVE_MERGES:\n \t\t\t/* compatible */\n \t\t\tbreak;\n \t\tcase REBASE_UNSPECIFIED:\n@@ -1812,7 +1708,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tswitch (options.type) {\n \tcase REBASE_MERGE:\n \tcase REBASE_INTERACTIVE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\toptions.state_dir = merge_dir();\n \t\tbreak;\n \tcase REBASE_AM:\n@@ -1843,28 +1738,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (options.signoff) {\n-\t\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\t\tdie(\"cannot combine '--signoff' with \"\n-\t\t\t    \"'--preserve-merges'\");\n \t\targv_array_push(&options.git_am_opts, \"--signoff\");\n \t\toptions.flags |= REBASE_FORCE;\n \t}\n \n-\tif (options.type == REBASE_PRESERVE_MERGES) {\n-\t\t/*\n-\t\t * Note: incompatibility with --signoff handled in signoff block above\n-\t\t * Note: incompatibility with --interactive is just a strong warning;\n-\t\t *       git-rebase.txt caveats with \"unless you know what you are doing\"\n-\t\t */\n-\t\tif (options.rebase_merges)\n-\t\t\tdie(_(\"cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--rebase-merges'\"));\n-\n-\t\tif (options.reschedule_failed_exec)\n-\t\t\tdie(_(\"error: cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--reschedule-failed-exec'\"));\n-\t}\n-\n \tif (!options.root) {\n \t\tif (argc < 1) {\n \t\t\tstruct branch *branch;\ndiff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh\ndeleted file mode 100644\nindex dec90e9af6..0000000000\n--- a/git-rebase--preserve-merges.sh\n+++ /dev/null\n@@ -1,1067 +0,0 @@\n-# This shell script fragment is sourced by git-rebase to implement its\n-# preserve-merges mode.\n-#\n-# Copyright (c) 2006 Johannes E. Schindelin\n-#\n-# The file containing rebase commands, comments, and empty lines.\n-# This file is created by \"git rebase -i\" then edited by the user.  As\n-# the lines are processed, they are removed from the front of this\n-# file and written to the tail of $done.\n-todo=\"$state_dir\"/git-rebase-todo\n-\n-# The rebase command lines that have already been processed.  A line\n-# is moved here when it is first handled, before any associated user\n-# actions.\n-done=\"$state_dir\"/done\n-\n-# The commit message that is planned to be used for any changes that\n-# need to be committed following a user interaction.\n-msg=\"$state_dir\"/message\n-\n-# The file into which is accumulated the suggested commit message for\n-# squash/fixup commands.  When the first of a series of squash/fixups\n-# is seen, the file is created and the commit message from the\n-# previous commit and from the first squash/fixup commit are written\n-# to it.  The commit message for each subsequent squash/fixup commit\n-# is appended to the file as it is processed.\n-#\n-# The first line of the file is of the form\n-#     # This is a combination of $count commits.\n-# where $count is the number of commits whose messages have been\n-# written to the file so far (including the initial \"pick\" commit).\n-# Each time that a commit message is processed, this line is read and\n-# updated.  It is deleted just before the combined commit is made.\n-squash_msg=\"$state_dir\"/message-squash\n-\n-# If the current series of squash/fixups has not yet included a squash\n-# command, then this file exists and holds the commit message of the\n-# original \"pick\" commit.  (If the series ends without a \"squash\"\n-# command, then this can be used as the commit message of the combined\n-# commit without opening the editor.)\n-fixup_msg=\"$state_dir\"/message-fixup\n-\n-# $rewritten is the name of a directory containing files for each\n-# commit that is reachable by at least one merge base of $head and\n-# $upstream. They are not necessarily rewritten, but their children\n-# might be.  This ensures that commits on merged, but otherwise\n-# unrelated side branches are left alone. (Think \"X\" in the man page's\n-# example.)\n-rewritten=\"$state_dir\"/rewritten\n-\n-dropped=\"$state_dir\"/dropped\n-\n-end=\"$state_dir\"/end\n-msgnum=\"$state_dir\"/msgnum\n-\n-# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE that will be used for the commit that is currently\n-# being rebased.\n-author_script=\"$state_dir\"/author-script\n-\n-# When an \"edit\" rebase command is being processed, the SHA1 of the\n-# commit to be edited is recorded in this file.  When \"git rebase\n-# --continue\" is executed, if there are any staged changes then they\n-# will be amended to the HEAD commit, but only provided the HEAD\n-# commit is still the commit to be edited.  When any other rebase\n-# command is processed, this file is deleted.\n-amend=\"$state_dir\"/amend\n-\n-# For the post-rewrite hook, we make a list of rewritten commits and\n-# their new sha1s.  The rewritten-pending list keeps the sha1s of\n-# commits that have been processed, but not committed yet,\n-# e.g. because they are waiting for a 'squash' command.\n-rewritten_list=\"$state_dir\"/rewritten-list\n-rewritten_pending=\"$state_dir\"/rewritten-pending\n-\n-# Work around Git for Windows' Bash whose \"read\" does not strip CRLF\n-# and leaves CR at the end instead.\n-cr=$(printf \"\\015\")\n-\n-resolvemsg=\"\n-$(gettext 'Resolve all conflicts manually, mark them as resolved with\n-\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n-You can instead skip this commit: run \"git rebase --skip\".\n-To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".')\n-\"\n-\n-write_basic_state () {\n-\techo \"$head_name\" > \"$state_dir\"/head-name &&\n-\techo \"$onto\" > \"$state_dir\"/onto &&\n-\techo \"$orig_head\" > \"$state_dir\"/orig-head &&\n-\ttest t = \"$GIT_QUIET\" && : > \"$state_dir\"/quiet\n-\ttest t = \"$verbose\" && : > \"$state_dir\"/verbose\n-\ttest -n \"$strategy\" && echo \"$strategy\" > \"$state_dir\"/strategy\n-\ttest -n \"$strategy_opts\" && echo \"$strategy_opts\" > \\\n-\t\t\"$state_dir\"/strategy_opts\n-\ttest -n \"$allow_rerere_autoupdate\" && echo \"$allow_rerere_autoupdate\" > \\\n-\t\t\"$state_dir\"/allow_rerere_autoupdate\n-\ttest -n \"$gpg_sign_opt\" && echo \"$gpg_sign_opt\" > \"$state_dir\"/gpg_sign_opt\n-\ttest -n \"$signoff\" && echo \"$signoff\" >\"$state_dir\"/signoff\n-\ttest -n \"$reschedule_failed_exec\" && : > \"$state_dir\"/reschedule-failed-exec\n-}\n-\n-apply_autostash () {\n-\tif test -f \"$state_dir/autostash\"\n-\tthen\n-\t\tstash_sha1=$(cat \"$state_dir/autostash\")\n-\t\tif git stash apply $stash_sha1 >/dev/null 2>&1\n-\t\tthen\n-\t\t\techo \"$(gettext 'Applied autostash.')\" >&2\n-\t\telse\n-\t\t\tgit stash store -m \"autostash\" -q $stash_sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot store \\$stash_sha1\")\"\n-\t\t\tgettext 'Applying autostash resulted in conflicts.\n-Your changes are safe in the stash.\n-You can run \"git stash pop\" or \"git stash drop\" at any time.\n-' >&2\n-\t\tfi\n-\tfi\n-}\n-\n-output () {\n-\tcase \"$verbose\" in\n-\t'')\n-\t\toutput=$(\"$@\" 2>&1 )\n-\t\tstatus=$?\n-\t\ttest $status != 0 && printf \"%s\\n\" \"$output\"\n-\t\treturn $status\n-\t\t;;\n-\t*)\n-\t\t\"$@\"\n-\t\t;;\n-\tesac\n-}\n-\n-strategy_args=${strategy:+--strategy=$strategy}\n-test -n \"$strategy_opts\" &&\n-eval '\n-\tfor strategy_opt in '\"$strategy_opts\"'\n-\tdo\n-\t\tstrategy_args=\"$strategy_args -X$(git rev-parse --sq-quote \"${strategy_opt#--}\")\"\n-\tdone\n-'\n-\n-GIT_CHERRY_PICK_HELP=\"$resolvemsg\"\n-export GIT_CHERRY_PICK_HELP\n-\n-comment_char=$(git config --get core.commentchar 2>/dev/null)\n-case \"$comment_char\" in\n-'' | auto)\n-\tcomment_char=\"#\"\n-\t;;\n-?)\n-\t;;\n-*)\n-\tcomment_char=$(echo \"$comment_char\" | cut -c1)\n-\t;;\n-esac\n-\n-warn () {\n-\tprintf '%s\\n' \"$*\" >&2\n-}\n-\n-# Output the commit message for the specified commit.\n-commit_message () {\n-\tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n-}\n-\n-orig_reflog_action=\"$GIT_REFLOG_ACTION\"\n-\n-comment_for_reflog () {\n-\tcase \"$orig_reflog_action\" in\n-\t''|rebase*)\n-\t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n-\t\texport GIT_REFLOG_ACTION\n-\t\t;;\n-\tesac\n-}\n-\n-last_count=\n-mark_action_done () {\n-\tsed -e 1q < \"$todo\" >> \"$done\"\n-\tsed -e 1d < \"$todo\" >> \"$todo\".new\n-\tmv -f \"$todo\".new \"$todo\"\n-\tnew_count=$(( $(git stripspace --strip-comments <\"$done\" | wc -l) ))\n-\techo $new_count >\"$msgnum\"\n-\ttotal=$(($new_count + $(git stripspace --strip-comments <\"$todo\" | wc -l)))\n-\techo $total >\"$end\"\n-\tif test \"$last_count\" != \"$new_count\"\n-\tthen\n-\t\tlast_count=$new_count\n-\t\teval_gettext \"Rebasing (\\$new_count/\\$total)\"; printf \"\\r\"\n-\t\ttest -z \"$verbose\" || echo\n-\tfi\n-}\n-\n-# Put the last action marked done at the beginning of the todo list\n-# again. If there has not been an action marked done yet, leave the list of\n-# items on the todo list unchanged.\n-reschedule_last_action () {\n-\ttail -n 1 \"$done\" | cat - \"$todo\" >\"$todo\".new\n-\tsed -e \\$d <\"$done\" >\"$done\".new\n-\tmv -f \"$todo\".new \"$todo\"\n-\tmv -f \"$done\".new \"$done\"\n-}\n-\n-append_todo_help () {\n-\tgettext \"\n-Commands:\n-p, pick <commit> = use commit\n-r, reword <commit> = use commit, but edit the commit message\n-e, edit <commit> = use commit, but stop for amending\n-s, squash <commit> = use commit, but meld into previous commit\n-f, fixup <commit> = like \\\"squash\\\", but discard this commit's log message\n-x, exec <commit> = run command (the rest of the line) using shell\n-d, drop <commit> = remove commit\n-l, label <label> = label current HEAD with a name\n-t, reset <label> = reset HEAD to a label\n-m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n-.       create a merge commit using the original merge commit's\n-.       message (or the oneline, if no original merge commit was\n-.       specified). Use -c <commit> to reword the commit message.\n-\n-These lines can be re-ordered; they are executed from top to bottom.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test $(get_missing_commit_check_level) = error\n-\tthen\n-\t\tgettext \"\n-Do not remove any line. Use 'drop' explicitly to remove a commit.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\telse\n-\t\tgettext \"\n-If you remove a line here THAT COMMIT WILL BE LOST.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\tfi\n-}\n-\n-make_patch () {\n-\tsha1_and_parents=\"$(git rev-list --parents -1 \"$1\")\"\n-\tcase \"$sha1_and_parents\" in\n-\t?*' '?*' '?*)\n-\t\tgit diff --cc $sha1_and_parents\n-\t\t;;\n-\t?*' '?*)\n-\t\tgit diff-tree -p \"$1^!\"\n-\t\t;;\n-\t*)\n-\t\techo \"Root commit\"\n-\t\t;;\n-\tesac > \"$state_dir\"/patch\n-\ttest -f \"$msg\" ||\n-\t\tcommit_message \"$1\" > \"$msg\"\n-\ttest -f \"$author_script\" ||\n-\t\tget_author_ident_from_commit \"$1\" > \"$author_script\"\n-}\n-\n-die_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch \"$1\"\n-\tdie \"$2\"\n-}\n-\n-exit_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch $1\n-\tgit rev-parse --verify HEAD > \"$amend\"\n-\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\twarn \"$(eval_gettext \"\\\n-You can amend the commit now, with\n-\n-\tgit commit --amend \\$gpg_sign_opt_quoted\n-\n-Once you are satisfied with your changes, run\n-\n-\tgit rebase --continue\")\"\n-\twarn\n-\texit $2\n-}\n-\n-die_abort () {\n-\tapply_autostash\n-\trm -rf \"$state_dir\"\n-\tdie \"$1\"\n-}\n-\n-has_action () {\n-\ttest -n \"$(git stripspace --strip-comments <\"$1\")\"\n-}\n-\n-is_empty_commit() {\n-\ttree=$(git rev-parse -q --verify \"$1\"^{tree} 2>/dev/null) || {\n-\t\tsha1=$1\n-\t\tdie \"$(eval_gettext \"\\$sha1: not a commit that can be picked\")\"\n-\t}\n-\tptree=$(git rev-parse -q --verify \"$1\"^^{tree} 2>/dev/null) ||\n-\t\tptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904\n-\ttest \"$tree\" = \"$ptree\"\n-}\n-\n-is_merge_commit()\n-{\n-\tgit rev-parse --verify --quiet \"$1\"^2 >/dev/null 2>&1\n-}\n-\n-# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE exported from the current environment.\n-do_with_author () {\n-\t(\n-\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE\n-\t\t\"$@\"\n-\t)\n-}\n-\n-git_sequence_editor () {\n-\tif test -z \"$GIT_SEQUENCE_EDITOR\"\n-\tthen\n-\t\tGIT_SEQUENCE_EDITOR=\"$(git config sequence.editor)\"\n-\t\tif [ -z \"$GIT_SEQUENCE_EDITOR\" ]\n-\t\tthen\n-\t\t\tGIT_SEQUENCE_EDITOR=\"$(git var GIT_EDITOR)\" || return $?\n-\t\tfi\n-\tfi\n-\n-\teval \"$GIT_SEQUENCE_EDITOR\" '\"$@\"'\n-}\n-\n-pick_one () {\n-\tff=--ff\n-\n-\tcase \"$1\" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac\n-\tcase \"$force_rebase\" in '') ;; ?*) ff= ;; esac\n-\toutput git rev-parse --verify $sha1 || die \"$(eval_gettext \"Invalid commit name: \\$sha1\")\"\n-\n-\tif is_empty_commit \"$sha1\"\n-\tthen\n-\t\tempty_args=\"--allow-empty\"\n-\tfi\n-\n-\tpick_one_preserving_merges \"$@\"\n-}\n-\n-pick_one_preserving_merges () {\n-\tfast_forward=t\n-\tcase \"$1\" in\n-\t-n)\n-\t\tfast_forward=f\n-\t\tsha1=$2\n-\t\t;;\n-\t*)\n-\t\tsha1=$1\n-\t\t;;\n-\tesac\n-\tsha1=$(git rev-parse $sha1)\n-\n-\tif test -f \"$state_dir\"/current-commit && test \"$fast_forward\" = t\n-\tthen\n-\t\twhile read current_commit\n-\t\tdo\n-\t\t\tgit rev-parse HEAD > \"$rewritten\"/$current_commit\n-\t\tdone <\"$state_dir\"/current-commit\n-\t\trm \"$state_dir\"/current-commit ||\n-\t\t\tdie \"$(gettext \"Cannot write current commit's replacement sha1\")\"\n-\tfi\n-\n-\techo $sha1 >> \"$state_dir\"/current-commit\n-\n-\t# rewrite parents; if none were rewritten, we can fast-forward.\n-\tnew_parents=\n-\tpend=\" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\"\n-\tif test \"$pend\" = \" \"\n-\tthen\n-\t\tpend=\" root\"\n-\tfi\n-\twhile [ \"$pend\" != \"\" ]\n-\tdo\n-\t\tp=$(expr \"$pend\" : ' \\([^ ]*\\)')\n-\t\tpend=\"${pend# $p}\"\n-\n-\t\tif test -f \"$rewritten\"/$p\n-\t\tthen\n-\t\t\tnew_p=$(cat \"$rewritten\"/$p)\n-\n-\t\t\t# If the todo reordered commits, and our parent is marked for\n-\t\t\t# rewriting, but hasn't been gotten to yet, assume the user meant to\n-\t\t\t# drop it on top of the current HEAD\n-\t\t\tif test -z \"$new_p\"\n-\t\t\tthen\n-\t\t\t\tnew_p=$(git rev-parse HEAD)\n-\t\t\tfi\n-\n-\t\t\ttest $p != $new_p && fast_forward=f\n-\t\t\tcase \"$new_parents\" in\n-\t\t\t*$new_p*)\n-\t\t\t\t;; # do nothing; that parent is already there\n-\t\t\t*)\n-\t\t\t\tnew_parents=\"$new_parents $new_p\"\n-\t\t\t\t;;\n-\t\t\tesac\n-\t\telse\n-\t\t\tif test -f \"$dropped\"/$p\n-\t\t\tthen\n-\t\t\t\tfast_forward=f\n-\t\t\t\treplacement=\"$(cat \"$dropped\"/$p)\"\n-\t\t\t\ttest -z \"$replacement\" && replacement=root\n-\t\t\t\tpend=\" $replacement$pend\"\n-\t\t\telse\n-\t\t\t\tnew_parents=\"$new_parents $p\"\n-\t\t\tfi\n-\t\tfi\n-\tdone\n-\tcase $fast_forward in\n-\tt)\n-\t\toutput warn \"$(eval_gettext \"Fast-forward to \\$sha1\")\"\n-\t\toutput git reset --hard $sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot fast-forward to \\$sha1\")\"\n-\t\t;;\n-\tf)\n-\t\tfirst_parent=$(expr \"$new_parents\" : ' \\([^ ]*\\)')\n-\n-\t\tif [ \"$1\" != \"-n\" ]\n-\t\tthen\n-\t\t\t# detach HEAD to current parent\n-\t\t\toutput git checkout $first_parent 2> /dev/null ||\n-\t\t\t\tdie \"$(eval_gettext \"Cannot move HEAD to \\$first_parent\")\"\n-\t\tfi\n-\n-\t\tcase \"$new_parents\" in\n-\t\t' '*' '*)\n-\t\t\ttest \"a$1\" = a-n && die \"$(eval_gettext \"Refusing to squash a merge: \\$sha1\")\"\n-\n-\t\t\t# redo merge\n-\t\t\tauthor_script_content=$(get_author_ident_from_commit $sha1)\n-\t\t\teval \"$author_script_content\"\n-\t\t\tmsg_content=\"$(commit_message $sha1)\"\n-\t\t\t# No point in merging the first parent, that's HEAD\n-\t\t\tnew_parents=${new_parents# $first_parent}\n-\t\t\tmerge_args=\"--no-log --no-ff\"\n-\t\t\tif ! do_with_author output eval \\\n-\t\t\t\tgit merge ${gpg_sign_opt:+$(git rev-parse \\\n-\t\t\t\t\t--sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t$allow_rerere_autoupdate \"$merge_args\" \\\n-\t\t\t\t\"$strategy_args\" \\\n-\t\t\t\t-m \"$(git rev-parse --sq-quote \"$msg_content\")\" \\\n-\t\t\t\t\"$new_parents\"\n-\t\t\tthen\n-\t\t\t\tprintf \"%s\\n\" \"$msg_content\" > \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Error redoing merge \\$sha1\")\"\n-\t\t\tfi\n-\t\t\techo \"$sha1 $(git rev-parse HEAD^0)\" >> \"$rewritten_list\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\toutput eval git cherry-pick $allow_rerere_autoupdate \\\n-\t\t\t\t$allow_empty_message \\\n-\t\t\t\t${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t\"$strategy_args\" \"$@\" ||\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not pick \\$sha1\")\"\n-\t\t\t;;\n-\t\tesac\n-\t\t;;\n-\tesac\n-}\n-\n-this_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"This is the commit message #\\${n}:\"\n-}\n-\n-skip_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"The commit message #\\${n} will be skipped:\"\n-}\n-\n-update_squash_messages () {\n-\tif test -f \"$squash_msg\"; then\n-\t\tmv \"$squash_msg\" \"$squash_msg\".bak || exit\n-\t\tcount=$(($(sed -n \\\n-\t\t\t-e \"1s/^$comment_char[^0-9]*\\([0-9][0-9]*\\).*/\\1/p\" \\\n-\t\t\t-e \"q\" < \"$squash_msg\".bak)+1))\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(eval_ngettext \\\n-\t\t\t\t\"This is a combination of \\$count commit.\" \\\n-\t\t\t\t\"This is a combination of \\$count commits.\" \\\n-\t\t\t\t$count)\"\n-\t\t\tsed -e 1d -e '2,/^./{\n-\t\t\t\t/^$/d\n-\t\t\t}' <\"$squash_msg\".bak\n-\t\t} >\"$squash_msg\"\n-\telse\n-\t\tcommit_message HEAD >\"$fixup_msg\" ||\n-\t\tdie \"$(eval_gettext \"Cannot write \\$fixup_msg\")\"\n-\t\tcount=2\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is a combination of 2 commits.\")\"\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is the 1st commit message:\")\"\n-\t\t\techo\n-\t\t\tcat \"$fixup_msg\"\n-\t\t} >\"$squash_msg\"\n-\tfi\n-\tcase $1 in\n-\tsquash)\n-\t\trm -f \"$fixup_msg\"\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(this_nth_commit_message $count)\"\n-\t\techo\n-\t\tcommit_message $2\n-\t\t;;\n-\tfixup)\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(skip_nth_commit_message $count)\"\n-\t\techo\n-\t\t# Change the space after the comment character to TAB:\n-\t\tcommit_message $2 | git stripspace --comment-lines | sed -e 's/ /\t/'\n-\t\t;;\n-\tesac >>\"$squash_msg\"\n-}\n-\n-peek_next_command () {\n-\tgit stripspace --strip-comments <\"$todo\" | sed -n -e 's/ .*//p' -e q\n-}\n-\n-# A squash/fixup has failed.  Prepare the long version of the squash\n-# commit message, then die_with_patch.  This code path requires the\n-# user to edit the combined commit message for all commits that have\n-# been squashed/fixedup so far.  So also erase the old squash\n-# messages, effectively causing the combined commit to be used as the\n-# new basis for any further squash/fixups.  Args: sha1 rest\n-die_failed_squash() {\n-\tsha1=$1\n-\trest=$2\n-\tmv \"$squash_msg\" \"$msg\" || exit\n-\trm -f \"$fixup_msg\"\n-\tcp \"$msg\" \"$GIT_DIR\"/MERGE_MSG || exit\n-\twarn\n-\twarn \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tdie_with_patch $sha1 \"\"\n-}\n-\n-flush_rewritten_pending() {\n-\ttest -s \"$rewritten_pending\" || return\n-\tnewsha1=\"$(git rev-parse HEAD^0)\"\n-\tsed \"s/$/ $newsha1/\" < \"$rewritten_pending\" >> \"$rewritten_list\"\n-\trm -f \"$rewritten_pending\"\n-}\n-\n-record_in_rewritten() {\n-\toldsha1=\"$(git rev-parse $1)\"\n-\techo \"$oldsha1\" >> \"$rewritten_pending\"\n-\n-\tcase \"$(peek_next_command)\" in\n-\tsquash|s|fixup|f)\n-\t\t;;\n-\t*)\n-\t\tflush_rewritten_pending\n-\t\t;;\n-\tesac\n-}\n-\n-do_pick () {\n-\tsha1=$1\n-\trest=$2\n-\tif test \"$(git rev-parse HEAD)\" = \"$squash_onto\"\n-\tthen\n-\t\t# Set the correct commit message and author info on the\n-\t\t# sentinel root before cherry-picking the original changes\n-\t\t# without committing (-n).  Finally, update the sentinel again\n-\t\t# to include these changes.  If the cherry-pick results in a\n-\t\t# conflict, this means our behaviour is similar to a standard\n-\t\t# failed cherry-pick during rebase, with a dirty index to\n-\t\t# resolve before manually running git commit --amend then git\n-\t\t# rebase --continue.\n-\t\tgit commit --allow-empty --allow-empty-message --amend \\\n-\t\t\t   --no-post-rewrite -n -q -C $sha1 $signoff &&\n-\t\t\tpick_one -n $sha1 &&\n-\t\t\tgit commit --allow-empty --allow-empty-message \\\n-\t\t\t\t   --amend --no-post-rewrite -n -q -C $sha1 $signoff \\\n-\t\t\t\t   ${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n-\t\t\t\t   die_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\telse\n-\t\tpick_one $sha1 ||\n-\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tfi\n-}\n-\n-do_next () {\n-\trm -f \"$msg\" \"$author_script\" \"$amend\" \"$state_dir\"/stopped-sha || exit\n-\tread -r command sha1 rest < \"$todo\"\n-\tcase \"$command\" in\n-\t\"$comment_char\"*|''|noop|drop|d)\n-\t\tmark_action_done\n-\t\t;;\n-\t\"$cr\")\n-\t\t# Work around CR left by \"read\" (e.g. with Git for Windows' Bash).\n-\t\tmark_action_done\n-\t\t;;\n-\tpick|p)\n-\t\tcomment_for_reflog pick\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\treword|r)\n-\t\tcomment_for_reflog reword\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tgit commit --amend --no-post-rewrite ${gpg_sign_opt:+\"$gpg_sign_opt\"} \\\n-\t\t\t$allow_empty_message || {\n-\t\t\twarn \"$(eval_gettext \"\\\n-Could not amend commit after successfully picking \\$sha1... \\$rest\n-This is most likely due to an empty commit message, or the pre-commit hook\n-failed. If the pre-commit hook failed, you may need to resolve the issue before\n-you are able to reword the commit.\")\"\n-\t\t\texit_with_patch $sha1 1\n-\t\t}\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tedit|e)\n-\t\tcomment_for_reflog edit\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tsha1_abbrev=$(git rev-parse --short $sha1)\n-\t\twarn \"$(eval_gettext \"Stopped at \\$sha1_abbrev... \\$rest\")\"\n-\t\texit_with_patch $sha1 0\n-\t\t;;\n-\tsquash|s|fixup|f)\n-\t\tcase \"$command\" in\n-\t\tsquash|s)\n-\t\t\tsquash_style=squash\n-\t\t\t;;\n-\t\tfixup|f)\n-\t\t\tsquash_style=fixup\n-\t\t\t;;\n-\t\tesac\n-\t\tcomment_for_reflog $squash_style\n-\n-\t\ttest -f \"$done\" && has_action \"$done\" ||\n-\t\t\tdie \"$(eval_gettext \"Cannot '\\$squash_style' without a previous commit\")\"\n-\n-\t\tmark_action_done\n-\t\tupdate_squash_messages $squash_style $sha1\n-\t\tauthor_script_content=$(get_author_ident_from_commit HEAD)\n-\t\techo \"$author_script_content\" > \"$author_script\"\n-\t\teval \"$author_script_content\"\n-\t\tif ! pick_one -n $sha1\n-\t\tthen\n-\t\t\tgit rev-parse --verify HEAD >\"$amend\"\n-\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\tfi\n-\t\tcase \"$(peek_next_command)\" in\n-\t\tsquash|s|fixup|f)\n-\t\t\t# This is an intermediate commit; its message will only be\n-\t\t\t# used in case of trouble.  So use the long version:\n-\t\t\tdo_with_author output git commit --amend --no-verify -F \"$squash_msg\" \\\n-\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t# This is the final command of this squash/fixup group\n-\t\t\tif test -f \"$fixup_msg\"\n-\t\t\tthen\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$fixup_msg\" \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\telse\n-\t\t\t\tcp \"$squash_msg\" \"$GIT_DIR\"/SQUASH_MSG || exit\n-\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$GIT_DIR\"/SQUASH_MSG -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\tfi\n-\t\t\trm -f \"$squash_msg\" \"$fixup_msg\"\n-\t\t\t;;\n-\t\tesac\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tx|\"exec\")\n-\t\tread -r command rest < \"$todo\"\n-\t\tmark_action_done\n-\t\teval_gettextln \"Executing: \\$rest\"\n-\t\t\"${SHELL:-@SHELL_PATH@}\" -c \"$rest\" # Actual execution\n-\t\tstatus=$?\n-\t\t# Run in subshell because require_clean_work_tree can die.\n-\t\tdirty=f\n-\t\t(require_clean_work_tree \"rebase\" 2>/dev/null) || dirty=t\n-\t\tif test \"$status\" -ne 0\n-\t\tthen\n-\t\t\twarn \"$(eval_gettext \"Execution failed: \\$rest\")\"\n-\t\t\ttest \"$dirty\" = f ||\n-\t\t\t\twarn \"$(gettext \"and made changes to the index and/or the working tree\")\"\n-\n-\t\t\twarn \"$(gettext \"\\\n-You can fix the problem, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\tif test $status -eq 127\t\t# command not found\n-\t\t\tthen\n-\t\t\t\tstatus=1\n-\t\t\tfi\n-\t\t\texit \"$status\"\n-\t\telif test \"$dirty\" = t\n-\t\tthen\n-\t\t\t# TRANSLATORS: after these lines is a command to be issued by the user\n-\t\t\twarn \"$(eval_gettext \"\\\n-Execution succeeded: \\$rest\n-but left changes to the index and/or the working tree\n-Commit or stash your changes, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\texit 1\n-\t\tfi\n-\t\t;;\n-\t*)\n-\t\twarn \"$(eval_gettext \"Unknown command: \\$command \\$sha1 \\$rest\")\"\n-\t\tfixtodo=\"$(gettext \"Please fix this using 'git rebase --edit-todo'.\")\"\n-\t\tif git rev-parse --verify -q \"$sha1\" >/dev/null\n-\t\tthen\n-\t\t\tdie_with_patch $sha1 \"$fixtodo\"\n-\t\telse\n-\t\t\tdie \"$fixtodo\"\n-\t\tfi\n-\t\t;;\n-\tesac\n-\ttest -s \"$todo\" && return\n-\n-\tcomment_for_reflog finish &&\n-\tnewhead=$(git rev-parse HEAD) &&\n-\tcase $head_name in\n-\trefs/*)\n-\t\tmessage=\"$GIT_REFLOG_ACTION: $head_name onto $onto\" &&\n-\t\tgit update-ref -m \"$message\" $head_name $newhead $orig_head &&\n-\t\tgit symbolic-ref \\\n-\t\t  -m \"$GIT_REFLOG_ACTION: returning to $head_name\" \\\n-\t\t  HEAD $head_name\n-\t\t;;\n-\tesac && {\n-\t\ttest ! -f \"$state_dir\"/verbose ||\n-\t\t\tgit diff-tree --stat $orig_head..HEAD\n-\t} &&\n-\t{\n-\t\ttest -s \"$rewritten_list\" &&\n-\t\tgit notes copy --for-rewrite=rebase < \"$rewritten_list\" ||\n-\t\ttrue # we don't care if this copying failed\n-\t} &&\n-\thook=\"$(git rev-parse --git-path hooks/post-rewrite)\"\n-\tif test -x \"$hook\" && test -s \"$rewritten_list\"; then\n-\t\t\"$hook\" rebase < \"$rewritten_list\"\n-\t\ttrue # we don't care if this hook failed\n-\tfi &&\n-\t\twarn \"$(eval_gettext \"Successfully rebased and updated \\$head_name.\")\"\n-\n-\treturn 1 # not failure; just to break the do_rest loop\n-}\n-\n-# can only return 0, when the infinite loop breaks\n-do_rest () {\n-\twhile :\n-\tdo\n-\t\tdo_next || break\n-\tdone\n-}\n-\n-expand_todo_ids() {\n-\tgit rebase--interactive --expand-ids\n-}\n-\n-collapse_todo_ids() {\n-\tgit rebase--interactive --shorten-ids\n-}\n-\n-# Switch to the branch in $into and notify it in the reflog\n-checkout_onto () {\n-\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $onto_name\"\n-\toutput git checkout $onto || die_abort \"$(gettext \"could not detach HEAD\")\"\n-\tgit update-ref ORIG_HEAD $orig_head\n-}\n-\n-get_missing_commit_check_level () {\n-\tcheck_level=$(git config --get rebase.missingCommitsCheck)\n-\tcheck_level=${check_level:-ignore}\n-\t# Don't be case sensitive\n-\tprintf '%s' \"$check_level\" | tr 'A-Z' 'a-z'\n-}\n-\n-# Initiate an action. If the cannot be any\n-# further action it  may exec a command\n-# or exit and not return.\n-#\n-# TODO: Consider a cleaner return model so it\n-# never exits and always return 0 if process\n-# is complete.\n-#\n-# Parameter 1 is the action to initiate.\n-#\n-# Returns 0 if the action was able to complete\n-# and if 1 if further processing is required.\n-initiate_action () {\n-\tcase \"$1\" in\n-\tcontinue)\n-\t\t# do we have anything to commit?\n-\t\tif git diff-index --cached --quiet HEAD --\n-\t\tthen\n-\t\t\t# Nothing to commit -- skip this commit\n-\n-\t\t\ttest ! -f \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\trm \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\tdie \"$(gettext \"Could not remove CHERRY_PICK_HEAD\")\"\n-\t\telse\n-\t\t\tif ! test -f \"$author_script\"\n-\t\t\tthen\n-\t\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\t\t\t\tdie \"$(eval_gettext \"\\\n-You have staged changes in your working tree.\n-If these changes are meant to be\n-squashed into the previous commit, run:\n-\n-  git commit --amend \\$gpg_sign_opt_quoted\n-\n-If they are meant to go into a new commit, run:\n-\n-  git commit \\$gpg_sign_opt_quoted\n-\n-In both cases, once you're done, continue with:\n-\n-  git rebase --continue\n-\")\"\n-\t\t\tfi\n-\t\t\t. \"$author_script\" ||\n-\t\t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n-\t\t\tif test -f \"$amend\"\n-\t\t\tthen\n-\t\t\t\tcurrent_head=$(git rev-parse --verify HEAD)\n-\t\t\t\ttest \"$current_head\" = $(cat \"$amend\") ||\n-\t\t\t\tdie \"$(gettext \"\\\n-You have uncommitted changes in your working tree. Please commit them\n-first and then run 'git rebase --continue' again.\")\"\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\telse\n-\t\t\t\tdo_with_author git commit --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\tfi\n-\t\tfi\n-\n-\t\tif test -r \"$state_dir\"/stopped-sha\n-\t\tthen\n-\t\t\trecord_in_rewritten \"$(cat \"$state_dir\"/stopped-sha)\"\n-\t\tfi\n-\n-\t\trequire_clean_work_tree \"rebase\"\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tskip)\n-\t\tgit rerere clear\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tedit-todo)\n-\t\tgit stripspace --strip-comments <\"$todo\" >\"$todo\".new\n-\t\tmv -f \"$todo\".new \"$todo\"\n-\t\tcollapse_todo_ids\n-\t\tappend_todo_help\n-\t\tgettext \"\n-You are editing the todo file of an ongoing interactive rebase.\n-To continue rebase after editing, run:\n-    git rebase --continue\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\t\tgit_sequence_editor \"$todo\" ||\n-\t\t\tdie \"$(gettext \"Could not execute editor\")\"\n-\t\texpand_todo_ids\n-\n-\t\texit\n-\t\t;;\n-\tshow-current-patch)\n-\t\texec git show REBASE_HEAD --\n-\t\t;;\n-\t*)\n-\t\treturn 1 # continue\n-\t\t;;\n-\tesac\n-}\n-\n-setup_reflog_action () {\n-\tcomment_for_reflog start\n-\n-\tif test ! -z \"$switch_to\"\n-\tthen\n-\t\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $switch_to\"\n-\t\toutput git checkout \"$switch_to\" -- ||\n-\t\t\tdie \"$(eval_gettext \"Could not checkout \\$switch_to\")\"\n-\n-\t\tcomment_for_reflog start\n-\tfi\n-}\n-\n-init_basic_state () {\n-\torig_head=$(git rev-parse --verify HEAD) || die \"$(gettext \"No HEAD?\")\"\n-\tmkdir -p \"$state_dir\" || die \"$(eval_gettext \"Could not create temporary \\$state_dir\")\"\n-\trm -f \"$(git rev-parse --git-path REBASE_HEAD)\"\n-\n-\t: > \"$state_dir\"/interactive || die \"$(gettext \"Could not mark as interactive\")\"\n-\twrite_basic_state\n-}\n-\n-init_revisions_and_shortrevisions () {\n-\tshorthead=$(git rev-parse --short $orig_head)\n-\tshortonto=$(git rev-parse --short $onto)\n-\tif test -z \"$rebase_root\"\n-\t\t# this is now equivalent to ! -z \"$upstream\"\n-\tthen\n-\t\tshortupstream=$(git rev-parse --short $upstream)\n-\t\trevisions=$upstream...$orig_head\n-\t\tshortrevisions=$shortupstream..$shorthead\n-\telse\n-\t\trevisions=$onto...$orig_head\n-\t\tshortrevisions=$shorthead\n-\t\ttest -z \"$squash_onto\" ||\n-\t\techo \"$squash_onto\" >\"$state_dir\"/squash-onto\n-\tfi\n-}\n-\n-complete_action() {\n-\ttest -s \"$todo\" || echo noop >> \"$todo\"\n-\ttest -z \"$autosquash\" || git rebase--interactive --rearrange-squash || exit\n-\ttest -n \"$cmd\" && git rebase--interactive --add-exec-commands --cmd \"$cmd\"\n-\n-\ttodocount=$(git stripspace --strip-comments <\"$todo\" | wc -l)\n-\ttodocount=${todocount##* }\n-\n-cat >>\"$todo\" <<EOF\n-\n-$comment_char $(eval_ngettext \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount command)\" \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount commands)\" \\\n-\t\"$todocount\")\n-EOF\n-\tappend_todo_help\n-\tgettext \"\n-However, if you remove everything, the rebase will be aborted.\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test -z \"$keep_empty\"\n-\tthen\n-\t\tprintf '%s\\n' \"$comment_char $(gettext \"Note that empty commits are commented out\")\" >>\"$todo\"\n-\tfi\n-\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tcp \"$todo\" \"$todo\".backup\n-\tcollapse_todo_ids\n-\tgit_sequence_editor \"$todo\" ||\n-\t\tdie_abort \"$(gettext \"Could not execute editor\")\"\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tgit rebase--interactive --check-todo-list || {\n-\t\tret=$?\n-\t\tcheckout_onto\n-\t\texit $ret\n-\t}\n-\n-\texpand_todo_ids\n-\tcheckout_onto\n-\tdo_rest\n-}\n-\n-git_rebase__preserve_merges () {\n-\tinitiate_action \"$action\"\n-\tret=$?\n-\tif test $ret = 0; then\n-\t\treturn 0\n-\tfi\n-\n-\tsetup_reflog_action\n-\tinit_basic_state\n-\n-\tif test -z \"$rebase_root\"\n-\tthen\n-\t\tmkdir \"$rewritten\" &&\n-\t\tfor c in $(git merge-base --all $orig_head $upstream)\n-\t\tdo\n-\t\t\techo $onto > \"$rewritten\"/$c ||\n-\t\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\t\tdone\n-\telse\n-\t\tmkdir \"$rewritten\" &&\n-\t\techo $onto > \"$rewritten\"/root ||\n-\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\tfi\n-\n-\tinit_revisions_and_shortrevisions\n-\n-\tformat=$(git config --get rebase.instructionFormat)\n-\t# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse\n-\tgit rev-list --format=\"%m%H ${format:-%s}\" \\\n-\t\t--reverse --left-right --topo-order \\\n-\t\t$revisions ${restrict_revision+^$restrict_revision} | \\\n-\t\tsed -n \"s/^>//p\" |\n-\twhile read -r sha1 rest\n-\tdo\n-\t\tif test -z \"$keep_empty\" && is_empty_commit $sha1 && ! is_merge_commit $sha1\n-\t\tthen\n-\t\t\tcomment_out=\"$comment_char \"\n-\t\telse\n-\t\t\tcomment_out=\n-\t\tfi\n-\n-\t\tif test -z \"$rebase_root\"\n-\t\tthen\n-\t\t\tpreserve=t\n-\t\t\tfor p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\n-\t\t\tdo\n-\t\t\t\tif test -f \"$rewritten\"/$p\n-\t\t\t\tthen\n-\t\t\t\t\tpreserve=f\n-\t\t\t\tfi\n-\t\t\tdone\n-\t\telse\n-\t\t\tpreserve=f\n-\t\tfi\n-\t\tif test f = \"$preserve\"\n-\t\tthen\n-\t\t\ttouch \"$rewritten\"/$sha1\n-\t\t\tprintf '%s\\n' \"${comment_out}pick $sha1 $rest\" >>\"$todo\"\n-\t\tfi\n-\tdone\n-\n-\t# Watch for commits that been dropped by --cherry-pick\n-\tmkdir \"$dropped\"\n-\t# Save all non-cherry-picked changes\n-\tgit rev-list $revisions --left-right --cherry-pick | \\\n-\t\tsed -n \"s/^>//p\" > \"$state_dir\"/not-cherry-picks\n-\t# Now all commits and note which ones are missing in\n-\t# not-cherry-picks and hence being dropped\n-\tgit rev-list $revisions |\n-\twhile read rev\n-\tdo\n-\t\tif test -f \"$rewritten\"/$rev &&\n-\t\t   ! sane_grep \"$rev\" \"$state_dir\"/not-cherry-picks >/dev/null\n-\t\tthen\n-\t\t\t# Use -f2 because if rev-list is telling us this commit is\n-\t\t\t# not worthwhile, we don't want to track its multiple heads,\n-\t\t\t# just the history of its first-parent for others that will\n-\t\t\t# be rebasing on top of it\n-\t\t\tgit rev-list --parents -1 $rev | cut -d' ' -s -f2 > \"$dropped\"/$rev\n-\t\t\tsha1=$(git rev-list -1 $rev)\n-\t\t\tsane_grep -v \"^[a-z][a-z]* $sha1\" <\"$todo\" > \"${todo}2\" ; mv \"${todo}2\" \"$todo\"\n-\t\t\trm \"$rewritten\"/$rev\n-\t\tfi\n-\tdone\n-\n-\tcomplete_action\n-}\n-- \ngitgitgadget\n\n"},{"id":"386925","messageId":"20191123220850.GA29423@dcvr","threadId":"52325","inReplyTo":"b7ba83969da8fd2db4e6074d5044938c05b992fd.1574542243.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 6/8] git-svn: drop support for `--preserve-merges`","fromName":"Eric Wong","fromEmail":"e@80x24.org","sentAt":"2019-11-23T22:08:50Z","receivedAt":"2019-11-23T22:09:54Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> We already passed the `--rebase-merges` option to `git rebase` instead,\n> now we make this move permanent.\n\n> diff --git a/git-svn.perl b/git-svn.perl\n> index 4aa208ff5f..f1fa1bc7f7 100755\n> --- a/git-svn.perl\n> +++ b/git-svn.perl\n> @@ -271,7 +271,6 @@ sub _req_svn {\n>  \t\t\t  'fetch-all|all' => \\$_fetch_all,\n>  \t\t\t  'dry-run|n' => \\$_dry_run,\n>  \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n> -\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n>  \t\t\t  %fc_opts } ],\n>  \t'commit-diff' => [ \\&cmd_commit_diff,\n>  \t                   'Commit a diff between two trees',\n\nNack, it breaks existing usages.   Why the urgency with removal?\n\nI don't know a whole lot about this rebase feature in\nparticular, but deprecation periods should be measured in years\nor even decades because of LTS distros.  Not months, especially\nfor things which have been around for a long while.\n"},{"id":"386958","messageId":"nycvar.QRO.7.76.6.1911242224400.31080@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"20191123220850.GA29423@dcvr","subject":"Re: [PATCH 6/8] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-11-24T21:29:30Z","receivedAt":"2019-11-24T21:33:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Eric,\n\nOn Sat, 23 Nov 2019, Eric Wong wrote:\n\n> Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> > We already passed the `--rebase-merges` option to `git rebase` instead,\n> > now we make this move permanent.\n>\n> > diff --git a/git-svn.perl b/git-svn.perl\n> > index 4aa208ff5f..f1fa1bc7f7 100755\n> > --- a/git-svn.perl\n> > +++ b/git-svn.perl\n> > @@ -271,7 +271,6 @@ sub _req_svn {\n> >  \t\t\t  'fetch-all|all' => \\$_fetch_all,\n> >  \t\t\t  'dry-run|n' => \\$_dry_run,\n> >  \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n> > -\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n> >  \t\t\t  %fc_opts } ],\n> >  \t'commit-diff' => [ \\&cmd_commit_diff,\n> >  \t                   'Commit a diff between two trees',\n>\n> Nack, it breaks existing usages.   Why the urgency with removal?\n\nWhich urgency? The cover letter spells it out quite clearly that this is\nnot even intended for v2.25.0, which is still over 2 months out.\n\nThe reason I submitted this patch series now is so that we can avoid\ninadvertent new users of the `--preserve-merges` backend.\n\n> I don't know a whole lot about this rebase feature in\n> particular, but deprecation periods should be measured in years\n> or even decades because of LTS distros.  Not months, especially\n> for things which have been around for a long while.\n\nThe LTS distros will not even pick up this patch. So that's a red herring.\n\nBut yes, you're right, v2.25.0 will probably be the first version to even\nhave the `--rebase-merges` option in `git svn`, and therefore v2.26.0\nwould be awfully early a time to drop `--preserve-merges` in `git svn`.\nQuestion is whether we want to split this patch series, or just rather\nwait with merging it to `master` until a year from now, or something like\nthat?\n\nCiao,\nDscho\n"},{"id":"386969","messageId":"20191125031530.GA29212@dcvr","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.1911242224400.31080@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 6/8] git-svn: drop support for `--preserve-merges`","fromName":"Eric Wong","fromEmail":"e@80x24.org","sentAt":"2019-11-25T03:15:30Z","receivedAt":"2019-11-25T03:15:32Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> > > We already passed the `--rebase-merges` option to `git rebase` instead,\n> > > now we make this move permanent.\n> >\n> > > diff --git a/git-svn.perl b/git-svn.perl\n> > > index 4aa208ff5f..f1fa1bc7f7 100755\n> > > --- a/git-svn.perl\n> > > +++ b/git-svn.perl\n> > > @@ -271,7 +271,6 @@ sub _req_svn {\n> > >  \t\t\t  'fetch-all|all' => \\$_fetch_all,\n> > >  \t\t\t  'dry-run|n' => \\$_dry_run,\n> > >  \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n> > > -\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n> > >  \t\t\t  %fc_opts } ],\n> > >  \t'commit-diff' => [ \\&cmd_commit_diff,\n> > >  \t                   'Commit a diff between two trees',\n> >\n> > Nack, it breaks existing usages.   Why the urgency with removal?\n> \n> Which urgency? The cover letter spells it out quite clearly that this is\n> not even intended for v2.25.0, which is still over 2 months out.\n\n\"Months\" a blink of an eye when it comes to deprecations and removals.\n\n> The reason I submitted this patch series now is so that we can avoid\n> inadvertent new users of the `--preserve-merges` backend.\n\nThen documenting it as deprecated and warning is all that's\nneeded.\n\n> > I don't know a whole lot about this rebase feature in\n> > particular, but deprecation periods should be measured in years\n> > or even decades because of LTS distros.  Not months, especially\n> > for things which have been around for a long while.\n> \n> The LTS distros will not even pick up this patch. So that's a red herring.\n> \n> But yes, you're right, v2.25.0 will probably be the first version to even\n> have the `--rebase-merges` option in `git svn`, and therefore v2.26.0\n> would be awfully early a time to drop `--preserve-merges` in `git svn`.\n> Question is whether we want to split this patch series, or just rather\n> wait with merging it to `master` until a year from now, or something like\n> that?\n\nFwiw, I object to the regressions to all the other commands\n(rebase/pull/remote) in this series, too, but I mainly do Perl.\n\n--preserve-merges was only deprecated in v2.22.0 (2019-06-07).\nLTS distro users are very likely on pre-v2.22.0, more likely\nv2.1x.0 and maybe even v2.x.0.\n\nTheir next LTS release could be several years from now.  We\ncould be on git 2.[345]x.0 by then and that's when the LTS\npackagers could package the next version.  LTS users are likely\nto never see the entire period from v2.22.0..v2.25.0 and thus\nnever see a deprecation warning.\n\nEven Debian stable (not exactly LTS, but still on the slower\nside) went from v2.11.0 in Debian 9 all the way to v2.20.1\nin Debian 10.  Actual LTS users will see bigger jumps.\n"},{"id":"434416","messageId":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.git.1574542242.gitgitgadget@gmail.com","subject":"[PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:07Z","receivedAt":"2021-09-01T11:57:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\nincluded in v2.22.0), we officially deprecated the --preserve-merges\nbackend. Over two years later, it is time to drop that backend, and here is\na patch series that does just that.\n\nChanges since v1:\n\n * Rebased onto v2.33.0\n\nJohannes Schindelin (7):\n  t5520: do not use `pull.rebase=preserve`\n  remote: warn about unhandled branch.<name>.rebase values\n  tests: stop testing `git rebase --preserve-merges`\n  pull: remove support for `--rebase=preserve`\n  rebase: drop support for `--preserve-merges`\n  git-svn: drop support for `--preserve-merges`\n  rebase: drop the internal `rebase--interactive` command\n\n .github/workflows/main.yml                |    1 -\n .gitignore                                |    1 -\n Documentation/config/branch.txt           |    4 -\n Documentation/config/pull.txt             |    4 -\n Documentation/git-pull.txt                |    6 +-\n Documentation/git-rebase.txt              |   51 -\n Documentation/git-svn.txt                 |    1 -\n Makefile                                  |    2 -\n builtin/pull.c                            |    9 +-\n builtin/rebase.c                          |  318 +------\n builtin/remote.c                          |    3 +\n contrib/completion/git-completion.bash    |    2 +-\n git-rebase--preserve-merges.sh            | 1057 ---------------------\n git-svn.perl                              |    1 -\n git.c                                     |    1 -\n rebase.c                                  |    2 -\n rebase.h                                  |    1 -\n t/t3404-rebase-interactive.sh             |   76 --\n t/t3408-rebase-multi-line.sh              |   10 -\n t/t3409-rebase-preserve-merges.sh         |  130 ---\n t/t3410-rebase-preserve-dropped-merges.sh |   90 --\n t/t3411-rebase-preserve-around-merges.sh  |   80 --\n t/t3412-rebase-root.sh                    |   37 -\n t/t3414-rebase-preserve-onto.sh           |   85 --\n t/t3418-rebase-continue.sh                |   15 -\n t/t3421-rebase-topology-linear.sh         |   19 -\n t/t3422-rebase-incompatible-options.sh    |   11 -\n t/t3425-rebase-topology-merges.sh         |  151 ---\n t/t3427-rebase-subtree.sh                 |   19 -\n t/t5520-pull.sh                           |   24 +-\n t/t7505-prepare-commit-msg-hook.sh        |    1 -\n t/t7517-per-repo-email.sh                 |   13 -\n t/test-lib.sh                             |    4 -\n 33 files changed, 17 insertions(+), 2212 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\n\nbase-commit: 225bc32a989d7a22fa6addafd4ce7dcd04675dbf\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-195%2Fdscho%2Fdrop-rebase-p-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-195/dscho/drop-rebase-p-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/195\n\nRange-diff vs v1:\n\n 1:  662e16dbc12 ! 1:  8da29d539fc t5520: do not use `pull.rebase=preserve`\n     @@ t/t5520-pull.sh: test_expect_success '--rebase=false create a new merge commit'\n      -\ttest_config pull.rebase preserve &&\n      +\ttest_config pull.rebase merges &&\n       \tgit pull --rebase=true . copy &&\n     - \ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n     - \ttest file3 = \"$(git show HEAD:file3.t)\"\n     + \ttest_cmp_rev HEAD^^ copy &&\n     + \techo file3 >expect &&\n      @@ t/t5520-pull.sh: test_expect_success '--rebase=invalid fails' '\n     - \t! git pull --rebase=invalid . copy\n     + \ttest_must_fail git pull --rebase=invalid . copy\n       '\n       \n      -test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '\n     @@ t/t5520-pull.sh: test_expect_success '--rebase=invalid fails' '\n      -\ttest_config pull.rebase preserve &&\n      +\ttest_config pull.rebase merges &&\n       \tgit pull --rebase . copy &&\n     - \ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n     - \ttest file3 = \"$(git show HEAD:file3.t)\"\n     + \ttest_cmp_rev HEAD^^ copy &&\n     + \techo file3 >expect &&\n 2:  fb531064b35 < -:  ----------- remote: warn about unhandled branch.<name>.rebase values\n -:  ----------- > 2:  acda0f59947 remote: warn about unhandled branch.<name>.rebase values\n 3:  b614336f3df ! 3:  cdb9fae4b93 tests: stop testing `git rebase --preserve-merges`\n     @@ Commit message\n      \n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n     - ## azure-pipelines.yml ##\n     -@@ azure-pipelines.yml: jobs:\n     -       HOME: $(Build.SourcesDirectory)\n     -       MSYSTEM: MINGW64\n     -       NO_SVN_TESTS: 1\n     --      GIT_TEST_SKIP_REBASE_P: 1\n     -   - powershell: |\n     -       if (\"$GITFILESHAREPWD\" -ne \"\" -and \"$GITFILESHAREPWD\" -ne \"`$`(gitfileshare.pwd)\") {\n     -         cmd /c rmdir \"$(Build.SourcesDirectory)\\test-cache\"\n     -@@ azure-pipelines.yml: jobs:\n     -       HOME: $(Build.SourcesDirectory)\n     -       MSYSTEM: MINGW64\n     -       NO_SVN_TESTS: 1\n     --      GIT_TEST_SKIP_REBASE_P: 1\n     -   - powershell: |\n     -       if (\"$GITFILESHAREPWD\" -ne \"\" -and \"$GITFILESHAREPWD\" -ne \"`$`(gitfileshare.pwd)\") {\n     -         cmd /c rmdir \"$(Build.SourcesDirectory)\\test-cache\"\n     + ## .github/workflows/main.yml ##\n     +@@ .github/workflows/main.yml: jobs:\n     +       shell: bash\n     +       env:\n     +         NO_SVN_TESTS: 1\n     +-        GIT_TEST_SKIP_REBASE_P: 1\n     +       run: ci/run-test-slice.sh ${{matrix.nr}} 10\n     +     - name: ci/print-test-failures.sh\n     +       if: failure()\n      \n       ## t/t3404-rebase-interactive.sh ##\n      @@ t/t3404-rebase-interactive.sh: test_expect_success 'retain authorship when squashing' '\n     @@ t/t3404-rebase-interactive.sh: test_expect_success 'retain authorship when squas\n      -'\n      -\n      -test_expect_success REBASE_P 'preserve merges with -p' '\n     --\tgit checkout -b to-be-preserved master^ &&\n     +-\tgit checkout -b to-be-preserved primary^ &&\n      -\t: > unrelated-file &&\n      -\tgit add unrelated-file &&\n      -\ttest_tick &&\n      -\tgit commit -m \"unrelated\" &&\n     --\tgit checkout -b another-branch master &&\n     +-\tgit checkout -b another-branch primary &&\n      -\techo B > file1 &&\n      -\ttest_tick &&\n      -\tgit commit -m J file1 &&\n     @@ t/t3404-rebase-interactive.sh: test_expect_success 'retain authorship when squas\n      -\tgit commit -m M file1 &&\n      -\tgit checkout -b to-be-rebased &&\n      -\ttest_tick &&\n     --\tgit rebase -i -p --onto branch1 master &&\n     +-\tgit rebase -i -p --onto branch1 primary &&\n      -\tgit update-index --refresh &&\n      -\tgit diff-files --quiet &&\n      -\tgit diff-index --quiet --cached HEAD -- &&\n     --\ttest $(git rev-parse HEAD~6) = $(git rev-parse branch1) &&\n     --\ttest $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) &&\n     --\ttest $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) &&\n     +-\ttest_cmp_rev HEAD~6 branch1 &&\n     +-\ttest_cmp_rev HEAD~4^2 to-be-preserved &&\n     +-\ttest_cmp_rev HEAD^^2^ HEAD^^^ &&\n      -\ttest $(git show HEAD~5:file1) = B &&\n      -\ttest $(git show HEAD~3:file1) = C &&\n      -\ttest $(git show HEAD:file1) = E &&\n     @@ t/t3409-rebase-preserve-merges.sh (deleted)\n      -\n      -Run \"git rebase -p\" and check that merges are properly carried along\n      -'\n     +-GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n     +-export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n     +-\n      -. ./test-lib.sh\n      -\n      -if ! test_have_prereq REBASE_P; then\n     @@ t/t3409-rebase-preserve-merges.sh (deleted)\n      -\n      -# Clone 2 (conflicting merge):\n      -#\n     --# A1--A2--B3   <-- origin/master\n     +-# A1--A2--B3   <-- origin/main\n      -#  \\       \\\n      -#   B1------M  <-- topic\n      -#    \\\n     @@ t/t3409-rebase-preserve-merges.sh (deleted)\n      -#\n      -# Clone 3 (no-ff merge):\n      -#\n     --# A1--A2--B3   <-- origin/master\n     +-# A1--A2--B3   <-- origin/main\n      -#  \\\n      -#   B1------M  <-- topic\n      -#    \\     /\n     @@ t/t3409-rebase-preserve-merges.sh (deleted)\n      -\techo Second > B &&\n      -\tgit add B &&\n      -\tgit commit -m \"Add B1\" &&\n     --\tgit checkout -f master &&\n     +-\tgit checkout -f main &&\n      -\techo Third >> A &&\n      -\tgit commit -a -m \"Modify A2\" &&\n      -\techo Fifth > B &&\n     @@ t/t3409-rebase-preserve-merges.sh (deleted)\n      -\t(\n      -\t\tcd clone2 &&\n      -\t\tgit checkout -b topic origin/topic &&\n     --\t\ttest_must_fail git merge origin/master &&\n     +-\t\ttest_must_fail git merge origin/main &&\n      -\t\techo Resolved >B &&\n      -\t\tgit add B &&\n     --\t\tgit commit -m \"Merge origin/master into topic\"\n     +-\t\tgit commit -m \"Merge origin/main into topic\"\n      -\t) &&\n      -\n      -\tgit clone ./. clone3 &&\n     @@ t/t3412-rebase-root.sh: test_expect_success 'pre-rebase got correct input (4)' '\n       \n      -test_expect_success REBASE_P 'rebase -i -p with linear history' '\n      -\tgit checkout -b work5 other &&\n     --\tgit rebase -i -p --root --onto master &&\n     +-\tgit rebase -i -p --root --onto main &&\n      -\tgit log --pretty=tformat:\"%s\" > rebased5 &&\n      -\ttest_cmp expect rebased5\n      -'\n     @@ t/t3412-rebase-root.sh: commit work6~4\n       \n      -test_expect_success REBASE_P 'rebase -i -p with merge' '\n      -\tgit checkout -b work6 other &&\n     --\tgit rebase -i -p --root --onto master &&\n     +-\tgit rebase -i -p --root --onto main &&\n      -\tlog_with_names work6 > rebased6 &&\n      -\ttest_cmp expect-side rebased6\n      -'\n     @@ t/t3412-rebase-root.sh: commit work7~5\n       \n      -test_expect_success REBASE_P 'rebase -i -p with two roots' '\n      -\tgit checkout -b work7 other &&\n     --\tgit rebase -i -p --root --onto master &&\n     +-\tgit rebase -i -p --root --onto main &&\n      -\tlog_with_names work7 > rebased7 &&\n      -\ttest_cmp expect-third rebased7\n      -'\n     @@ t/t3412-rebase-root.sh: commit conflict3~6\n       \n      -test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' '\n      -\tgit checkout -b conflict3 other &&\n     --\ttest_must_fail git rebase -i -p --root --onto master &&\n     +-\ttest_must_fail git rebase -i -p --root --onto main &&\n      -\tgit ls-files -u | grep \"B$\"\n      -'\n      -\n     @@ t/t3418-rebase-continue.sh: test_rerere_autoupdate\n      \n       ## t/t3421-rebase-topology-linear.sh ##\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_expect_success 'setup branches and remote tracking' '\n       \tgit tag -l >tags &&\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n       \n       test_run_rebase () {\n       \tresult=$1\n     -@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n     +@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success --apply\n       test_run_rebase success --fork-point\n       test_run_rebase success -m\n       test_run_rebase success -i\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n       \n       test_run_rebase () {\n       \tresult=$1\n     -@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n     +@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success --apply\n       test_run_rebase success --fork-point\n       test_run_rebase success -m\n       test_run_rebase success -i\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n       \n       test_run_rebase () {\n       \tresult=$1\n     -@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n     +@@ t/t3421-rebase-topology-linear.sh: test_run_rebase success --apply\n       test_run_rebase success --fork-point\n       test_run_rebase success -m\n       test_run_rebase success -i\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase success ''\n       #       f\n       #      /\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       # a---b---c---j!\n       #      \\\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase failure --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n     --test_have_prereq !REBASE_P || test_run_rebase success -p\n     +-test_have_prereq !REBASE_P || test_run_rebase failure -p\n       \n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + }\n       test_run_rebase success -m\n       test_run_rebase success -i\n     --test_have_prereq !REBASE_P || test_run_rebase failure -p\n     +-test_have_prereq !REBASE_P || test_run_rebase success -p\n       \n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + }\n       test_run_rebase success -m\n       test_run_rebase success -i\n     --test_have_prereq !REBASE_P || test_run_rebase failure -p\n     +-test_have_prereq !REBASE_P || test_run_rebase success -p\n       test_run_rebase success --rebase-merges\n       \n       #       m\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase failure -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase success -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase failure -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_run_rebase () {\n       \tresult=$1\n      @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n     - test_run_rebase success ''\n     + test_run_rebase success --apply\n       test_run_rebase success -m\n       test_run_rebase success -i\n      -test_have_prereq !REBASE_P || test_run_rebase failure -p\n     @@ t/t3421-rebase-topology-linear.sh: test_run_rebase () {\n       test_done\n      \n       ## t/t3422-rebase-incompatible-options.sh ##\n     -@@ t/t3422-rebase-incompatible-options.sh: test_rebase_am_only --ignore-whitespace\n     - test_rebase_am_only --committer-date-is-author-date\n     +@@ t/t3422-rebase-incompatible-options.sh: test_rebase_am_only () {\n     + test_rebase_am_only --whitespace=fix\n       test_rebase_am_only -C4\n       \n      -test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\n     @@ t/t3422-rebase-incompatible-options.sh: test_rebase_am_only --ignore-whitespace\n       test_done\n      \n       ## t/t3425-rebase-topology-merges.sh ##\n     -@@ t/t3425-rebase-topology-merges.sh: test_run_rebase success 'd n o e' ''\n     +@@ t/t3425-rebase-topology-merges.sh: test_run_rebase success 'd n o e' --apply\n       test_run_rebase success 'd n o e' -m\n       test_run_rebase success 'd n o e' -i\n       \n     @@ t/t3427-rebase-subtree.sh: test_expect_success 'setup' '\n       \tgit commit -m \"Empty commit\" --allow-empty\n       '\n       \n     --# FAILURE: Does not preserve master4.\n     +-# FAILURE: Does not preserve topic_4.\n      -test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n      -\treset_rebase &&\n      -\tgit checkout -b rebase-preserve-merges to-rebase &&\n     --\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n     --\tverbose test \"$(commit_message HEAD~)\" = \"master4\" &&\n     --\tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n     +-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-main main &&\n     +-\tverbose test \"$(commit_message HEAD~)\" = \"topic_4\" &&\n     +-\tverbose test \"$(commit_message HEAD)\" = \"files_subtree/topic_5\"\n      -'\n      -\n     --# FAILURE: Does not preserve master4.\n     +-# FAILURE: Does not preserve topic_4.\n      -test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n      -\treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty to-rebase &&\n     --\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n     --\tverbose test \"$(commit_message HEAD~2)\" = \"master4\" &&\n     --\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n     +-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-main main &&\n     +-\tverbose test \"$(commit_message HEAD~2)\" = \"topic_4\" &&\n     +-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/topic_5\" &&\n      -\tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n      -'\n      -\n     - test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n     + test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' '\n       \treset_rebase &&\n       \tgit checkout -b rebase-onto to-rebase &&\n      \n       ## t/t5520-pull.sh ##\n      @@ t/t5520-pull.sh: test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '\n     - \ttest file3 = \"$(git show HEAD:file3.t)\"\n     + \ttest_cmp expect actual\n       '\n       \n      -test_expect_success REBASE_P \\\n     @@ t/t5520-pull.sh: test_expect_success 'pull.rebase=1 is treated as true and flatt\n      -\tgit reset --hard before-preserve-rebase &&\n      -\ttest_config pull.rebase preserve &&\n      -\tgit pull . copy &&\n     --\ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n     --\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse keep-merge)\"\n     +-\ttest_cmp_rev HEAD^^ copy &&\n     +-\ttest_cmp_rev HEAD^2 keep-merge\n      -'\n      -\n       test_expect_success 'pull.rebase=interactive' '\n       \twrite_script \"$TRASH_DIRECTORY/fake-editor\" <<-\\EOF &&\n       \techo I was here >fake.out &&\n      @@ t/t5520-pull.sh: test_expect_success '--rebase=true rebases and flattens keep-merge' '\n     - \ttest file3 = \"$(git show HEAD:file3.t)\"\n     + \ttest_cmp expect actual\n       '\n       \n      -test_expect_success REBASE_P \\\n     @@ t/t5520-pull.sh: test_expect_success '--rebase=true rebases and flattens keep-me\n      -\tgit reset --hard before-preserve-rebase &&\n      -\ttest_config pull.rebase true &&\n      -\tgit pull --rebase=preserve . copy &&\n     --\ttest \"$(git rev-parse HEAD^^)\" = \"$(git rev-parse copy)\" &&\n     --\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse keep-merge)\"\n     +-\ttest_cmp_rev HEAD^^ copy &&\n     +-\ttest_cmp_rev HEAD^2 keep-merge\n      -'\n      -\n       test_expect_success '--rebase=invalid fails' '\n       \tgit reset --hard before-preserve-rebase &&\n     - \t! git pull --rebase=invalid . copy\n     + \ttest_must_fail git pull --rebase=invalid . copy\n      \n       ## t/t7505-prepare-commit-msg-hook.sh ##\n      @@ t/t7505-prepare-commit-msg-hook.sh: test_rebase () {\n     @@ t/t7505-prepare-commit-msg-hook.sh: test_rebase () {\n      -test_have_prereq !REBASE_P || test_rebase success -p\n       \n       test_expect_success 'with hook (cherry-pick)' '\n     - \ttest_when_finished \"git checkout -f master\" &&\n     + \ttest_when_finished \"git checkout -f main\" &&\n      \n       ## t/t7517-per-repo-email.sh ##\n      @@ t/t7517-per-repo-email.sh: test_expect_success 'noop interactive rebase does not care about ident' '\n     @@ t/t7517-per-repo-email.sh: test_expect_success 'noop interactive rebase does not\n      -test_expect_success REBASE_P \\\n      -\t'fast-forward rebase does not care about ident (preserve)' '\n      -\tgit checkout -B tmp side-without-commit &&\n     --\tgit rebase -p master\n     +-\tgit rebase -p main\n      -'\n      -\n      -test_expect_success REBASE_P \\\n      -\t'non-fast-forward rebase refuses to write commits (preserve)' '\n      -\ttest_when_finished \"git rebase --abort || true\" &&\n      -\tgit checkout -B tmp side-with-commit &&\n     --\ttest_must_fail git rebase -p master\n     +-\ttest_must_fail git rebase -p main\n      -'\n      -\n       test_expect_success 'author.name overrides user.name' '\n     @@ t/t7517-per-repo-email.sh: test_expect_success 'noop interactive rebase does not\n       \ttest_config user.email user@example.com &&\n      \n       ## t/test-lib.sh ##\n     -@@ t/test-lib.sh: test_lazy_prereq CURL '\n     - test_lazy_prereq SHA1 '\n     - \ttest $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n     +@@ t/test-lib.sh: test_lazy_prereq SHA1 '\n     + \tesac\n       '\n     --\n     + \n      -test_lazy_prereq REBASE_P '\n      -\ttest -z \"$GIT_TEST_SKIP_REBASE_P\"\n      -'\n     +-\n     + # Ensure that no test accidentally triggers a Git command\n     + # that runs the actual maintenance scheduler, affecting a user's\n     + # system permanently.\n 4:  0c8bfe5d18d ! 4:  b493046134d pull: remove support for `--rebase=preserve`\n     @@ Commit message\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       ## Documentation/config/branch.txt ##\n     -@@ Documentation/config/branch.txt: When `merges`, pass the `--rebase-merges` option to 'git rebase'\n     +@@ Documentation/config/branch.txt: When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n       so that the local merge commits are included in the rebase (see\n       linkgit:git-rebase[1] for details).\n       +\n     --When `preserve` (deprecated in favor of `merges`), also pass\n     +-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n      -`--preserve-merges` along to 'git rebase' so that locally committed merge\n      -commits will not be flattened by running 'git pull'.\n      -+\n     - When the value is `interactive`, the rebase is run in interactive mode.\n     + When the value is `interactive` (or just 'i'), the rebase is run in interactive\n     + mode.\n       +\n     - *NOTE*: this is a possibly dangerous operation; do *not* use\n      \n       ## Documentation/config/pull.txt ##\n     -@@ Documentation/config/pull.txt: When `merges`, pass the `--rebase-merges` option to 'git rebase'\n     +@@ Documentation/config/pull.txt: When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n       so that the local merge commits are included in the rebase (see\n       linkgit:git-rebase[1] for details).\n       +\n     --When `preserve` (deprecated in favor of `merges`), also pass\n     +-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n      -`--preserve-merges` along to 'git rebase' so that locally committed merge\n      -commits will not be flattened by running 'git pull'.\n      -+\n     - When the value is `interactive`, the rebase is run in interactive mode.\n     + When the value is `interactive` (or just 'i'), the rebase is run in interactive\n     + mode.\n       +\n     - *NOTE*: this is a possibly dangerous operation; do *not* use\n      \n       ## Documentation/git-pull.txt ##\n      @@ Documentation/git-pull.txt: Options related to merging\n     @@ Documentation/git-pull.txt: When set to `merges`, rebase using `git rebase --reb\n      -`--preserve-merges` option passed to `git rebase` so that locally created\n      -merge commits will not be flattened.\n      -+\n     - When false, merge the current branch into the upstream branch.\n     + When false, merge the upstream branch into the current branch.\n       +\n       When `interactive`, enable the interactive mode of rebase.\n      \n       ## builtin/pull.c ##\n     -@@ builtin/pull.c: enum rebase_type {\n     - \tREBASE_INVALID = -1,\n     - \tREBASE_FALSE = 0,\n     - \tREBASE_TRUE,\n     --\tREBASE_PRESERVE,\n     - \tREBASE_MERGES,\n     - \tREBASE_INTERACTIVE\n     - };\n     -@@ builtin/pull.c: enum rebase_type {\n     +@@\n       /**\n        * Parses the value of --rebase. If value is a false value, returns\n        * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n     @@ builtin/pull.c: enum rebase_type {\n        */\n       static enum rebase_type parse_config_rebase(const char *key, const char *value,\n       \t\tint fatal)\n     -@@ builtin/pull.c: static enum rebase_type parse_config_rebase(const char *key, const char *value,\n     - \t\treturn REBASE_FALSE;\n     - \telse if (v > 0)\n     - \t\treturn REBASE_TRUE;\n     --\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n     --\t\treturn REBASE_PRESERVE;\n     - \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n     - \t\treturn REBASE_MERGES;\n     - \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\n      @@ builtin/pull.c: static struct option pull_options[] = {\n       \t/* Options passed to git-merge or git-rebase */\n       \tOPT_GROUP(N_(\"Options related to merging\")),\n     - \t{ OPTION_CALLBACK, 'r', \"rebase\", &opt_rebase,\n     --\t  \"(false|true|merges|preserve|interactive)\",\n     -+\t  \"(false|true|merges|interactive)\",\n     - \t  N_(\"incorporate changes by rebasing rather than merging\"),\n     - \t  PARSE_OPT_OPTARG, parse_opt_rebase },\n     + \tOPT_CALLBACK_F('r', \"rebase\", &opt_rebase,\n     +-\t\t\"(false|true|merges|preserve|interactive)\",\n     ++\t\t\"(false|true|merges|interactive)\",\n     + \t\tN_(\"incorporate changes by rebasing rather than merging\"),\n     + \t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n       \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n     -@@ builtin/pull.c: static int run_rebase(const struct object_id *curr_head,\n     +@@ builtin/pull.c: static int run_rebase(const struct object_id *newbase,\n       \t/* Options passed to git-rebase */\n       \tif (opt_rebase == REBASE_MERGES)\n     - \t\targv_array_push(&args, \"--rebase-merges\");\n     + \t\tstrvec_push(&args, \"--rebase-merges\");\n      -\telse if (opt_rebase == REBASE_PRESERVE)\n     --\t\targv_array_push(&args, \"--preserve-merges\");\n     +-\t\tstrvec_push(&args, \"--preserve-merges\");\n       \telse if (opt_rebase == REBASE_INTERACTIVE)\n     - \t\targv_array_push(&args, \"--interactive\");\n     + \t\tstrvec_push(&args, \"--interactive\");\n       \tif (opt_diffstat)\n      \n       ## contrib/completion/git-completion.bash ##\n     @@ contrib/completion/git-completion.bash: __git_complete_config_variable_value ()\n       \t\treturn\n       \t\t;;\n       \tremote.pushdefault)\n     +\n     + ## rebase.c ##\n     +@@ rebase.c: enum rebase_type rebase_parse_value(const char *value)\n     + \t\treturn REBASE_FALSE;\n     + \telse if (v > 0)\n     + \t\treturn REBASE_TRUE;\n     +-\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n     +-\t\treturn REBASE_PRESERVE;\n     + \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n     + \t\treturn REBASE_MERGES;\n     + \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\n     +\n     + ## rebase.h ##\n     +@@ rebase.h: enum rebase_type {\n     + \tREBASE_INVALID = -1,\n     + \tREBASE_FALSE = 0,\n     + \tREBASE_TRUE,\n     +-\tREBASE_PRESERVE,\n     + \tREBASE_MERGES,\n     + \tREBASE_INTERACTIVE\n     + };\n 5:  14e242b3cf9 ! 5:  eb738b1bf05 rebase: drop support for `--preserve-merges`\n     @@ Documentation/git-rebase.txt: i.e. commits that would be excluded by linkgit:git\n       onto `<upstream>` (or `<onto>`, if specified).\n       +\n      -The `--rebase-merges` mode is similar in spirit to the deprecated\n     --`--preserve-merges`, but in contrast to that option works well in interactive\n     --rebases: commits can be reordered, inserted and dropped at will.\n     +-`--preserve-merges` but works with interactive rebases,\n     +-where commits can be reordered, inserted and dropped at will.\n      -+\n       It is currently only possible to recreate the merge commits using the\n       `recursive` merge strategy; Different merge strategies can be used only via\n     @@ Documentation/git-rebase.txt: are incompatible with the following options:\n      - * --preserve-merges\n        * --interactive\n        * --exec\n     -  * --keep-empty\n     +  * --no-keep-empty\n      @@ Documentation/git-rebase.txt: are incompatible with the following options:\n       \n       In addition, the following pairs of options are incompatible:\n     @@ Documentation/git-rebase.txt: are incompatible with the following options:\n      - * --preserve-merges and --interactive\n      - * --preserve-merges and --signoff\n      - * --preserve-merges and --rebase-merges\n     +- * --preserve-merges and --empty=\n     +- * --preserve-merges and --ignore-whitespace\n     +- * --preserve-merges and --committer-date-is-author-date\n     +- * --preserve-merges and --ignore-date\n        * --keep-base and --onto\n        * --keep-base and --root\n     - \n     -@@ Documentation/git-rebase.txt: merge tlsv1.3\n     - merge cmake\n     - ------------\n     +  * --fork-point and --root\n     +@@ Documentation/git-rebase.txt: CONFIGURATION\n     + include::config/rebase.txt[]\n     + include::config/sequencer.txt[]\n       \n      -BUGS\n      -----\n     @@ Documentation/git-rebase.txt: merge tlsv1.3\n       Part of the linkgit:git[1] suite\n      \n       ## Makefile ##\n     -@@ Makefile: SCRIPT_SH += git-web--browse.sh\n     +@@ Makefile: SCRIPT_SH += git-submodule.sh\n     + SCRIPT_SH += git-web--browse.sh\n       \n       SCRIPT_LIB += git-mergetool--lib\n     - SCRIPT_LIB += git-parse-remote\n      -SCRIPT_LIB += git-rebase--preserve-merges\n     - SCRIPT_LIB += git-sh-setup\n       SCRIPT_LIB += git-sh-i18n\n     + SCRIPT_LIB += git-sh-setup\n       \n      @@ Makefile: XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \\\n     + \t--keyword=__ --keyword=N__ --keyword=\"__n:1,2\"\n       LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)\n       LOCALIZED_SH = $(SCRIPT_SH)\n     - LOCALIZED_SH += git-parse-remote.sh\n      -LOCALIZED_SH += git-rebase--preserve-merges.sh\n       LOCALIZED_SH += git-sh-setup.sh\n       LOCALIZED_PERL = $(SCRIPT_PERL)\n       \n      \n       ## builtin/rebase.c ##\n     -@@ builtin/rebase.c: enum rebase_type {\n     +@@ builtin/rebase.c: static GIT_PATH_FUNC(merge_dir, \"rebase-merge\")\n     + enum rebase_type {\n       \tREBASE_UNSPECIFIED = -1,\n     - \tREBASE_AM,\n     - \tREBASE_MERGE,\n     --\tREBASE_INTERACTIVE,\n     + \tREBASE_APPLY,\n     +-\tREBASE_MERGE,\n      -\tREBASE_PRESERVE_MERGES\n     -+\tREBASE_INTERACTIVE\n     ++\tREBASE_MERGE\n       };\n       \n     - struct rebase_options {\n     + enum empty_type {\n      @@ builtin/rebase.c: int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n       \n     - static int is_interactive(struct rebase_options *opts)\n     + static int is_merge(struct rebase_options *opts)\n       {\n     --\treturn opts->type == REBASE_INTERACTIVE ||\n     +-\treturn opts->type == REBASE_MERGE ||\n      -\t\topts->type == REBASE_PRESERVE_MERGES;\n     -+\treturn opts->type == REBASE_INTERACTIVE;\n     ++\treturn opts->type == REBASE_MERGE;\n       }\n       \n     - static void imply_interactive(struct rebase_options *opts, const char *option)\n     -@@ builtin/rebase.c: static void imply_interactive(struct rebase_options *opts, const char *option)\n     - \t\tdie(_(\"%s requires an interactive rebase\"), option);\n     + static void imply_merge(struct rebase_options *opts, const char *option)\n     +@@ builtin/rebase.c: static void imply_merge(struct rebase_options *opts, const char *option)\n     + \t\tdie(_(\"%s requires the merge backend\"), option);\n       \t\tbreak;\n     - \tcase REBASE_INTERACTIVE:\n     + \tcase REBASE_MERGE:\n      -\tcase REBASE_PRESERVE_MERGES:\n       \t\tbreak;\n     - \tcase REBASE_MERGE:\n     - \t\t/* we now implement --merge via --interactive */\n     + \tdefault:\n     + \t\topts->type = REBASE_MERGE; /* implied */\n      @@ builtin/rebase.c: static struct commit *peel_committish(const char *name)\n       \treturn (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);\n       }\n     @@ builtin/rebase.c: static struct commit *peel_committish(const char *name)\n      -\t}\n      -}\n      -\n     - #define GIT_REFLOG_ACTION_ENVIRONMENT \"GIT_REFLOG_ACTION\"\n     - \n     - #define RESET_HEAD_DETACH (1<<0)\n     + static int move_to_original_branch(struct rebase_options *opts)\n     + {\n     + \tstruct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;\n      @@ builtin/rebase.c: static int run_am(struct rebase_options *opts)\n       \n       static int run_specific_rebase(struct rebase_options *opts, enum action action)\n     @@ builtin/rebase.c: static int run_am(struct rebase_options *opts)\n       \tint status;\n      -\tconst char *backend, *backend_func;\n       \n     - \tif (opts->type == REBASE_INTERACTIVE) {\n     - \t\t/* Run builtin interactive rebase */\n     + \tif (opts->type == REBASE_MERGE) {\n     + \t\t/* Run sequencer-based rebase */\n      @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, enum action action)\n       \t\t}\n       \n     - \t\tstatus = run_rebase_interactive(opts, action);\n     + \t\tstatus = run_sequencer_rebase(opts, action);\n      -\t\tgoto finished_rebase;\n      -\t}\n      -\n     --\tif (opts->type == REBASE_AM) {\n     -+\t} else if (opts->type == REBASE_AM)\n     +-\tif (opts->type == REBASE_APPLY) {\n     ++\t} else if (opts->type == REBASE_APPLY)\n       \t\tstatus = run_am(opts);\n      -\t\tgoto finished_rebase;\n      -\t}\n     @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, en\n      -\tadd_var(&script_snippet, \"revisions\", opts->revisions);\n      -\tadd_var(&script_snippet, \"restrict_revision\", opts->restrict_revision ?\n      -\t\toid_to_hex(&opts->restrict_revision->object.oid) : NULL);\n     --\tadd_var(&script_snippet, \"GIT_QUIET\",\n     --\t\topts->flags & REBASE_NO_QUIET ? \"\" : \"t\");\n     --\tsq_quote_argv_pretty(&buf, opts->git_am_opts.argv);\n     +-\tsq_quote_argv_pretty(&buf, opts->git_am_opts.v);\n      -\tadd_var(&script_snippet, \"git_am_opt\", buf.buf);\n      -\tstrbuf_release(&buf);\n      -\tadd_var(&script_snippet, \"verbose\",\n     @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, en\n      -\tadd_var(&script_snippet, \"git_format_patch_opt\",\n      -\t\topts->git_format_patch_opt.buf);\n      -\n     --\tif (is_interactive(opts) &&\n     +-\tif (is_merge(opts) &&\n      -\t    !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n      -\t\tstrbuf_addstr(&script_snippet,\n      -\t\t\t      \"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; \");\n     @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, en\n      -finished_rebase:\n       \tif (opts->dont_finish_rebase)\n       \t\t; /* do nothing */\n     - \telse if (opts->type == REBASE_INTERACTIVE)\n     + \telse if (opts->type == REBASE_MERGE)\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n       \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n     - \t\t\tparse_opt_interactive },\n     + \t\t\tparse_opt_interactive),\n      -\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n      -\t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n      -\t\t\t\t \"ignoring them\"),\n      -\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n       \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n     - \t\tOPT_BOOL('k', \"keep-empty\", &options.keep_empty,\n     - \t\t\t N_(\"preserve empty commits during rebase\")),\n     + \t\tOPT_CALLBACK_F(0, \"empty\", &options, \"{drop,keep,ask}\",\n     + \t\t\t       N_(\"how to handle commits that become empty\"),\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \t\tstrbuf_reset(&buf);\n       \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t\tif (options.onto_name)\n       \t\t\tdie(_(\"cannot combine '--keep-base' with '--onto'\"));\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     + \t\tcase REBASE_APPLY:\n       \t\t\tdie(_(\"--strategy requires --merge or --interactive\"));\n       \t\tcase REBASE_MERGE:\n     - \t\tcase REBASE_INTERACTIVE:\n      -\t\tcase REBASE_PRESERVE_MERGES:\n       \t\t\t/* compatible */\n       \t\t\tbreak;\n       \t\tcase REBASE_UNSPECIFIED:\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     + \n       \tswitch (options.type) {\n       \tcase REBASE_MERGE:\n     - \tcase REBASE_INTERACTIVE:\n      -\tcase REBASE_PRESERVE_MERGES:\n       \t\toptions.state_dir = merge_dir();\n       \t\tbreak;\n     - \tcase REBASE_AM:\n     + \tcase REBASE_APPLY:\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     - \t}\n     + \t\toptions.reschedule_failed_exec = reschedule_failed_exec;\n       \n       \tif (options.signoff) {\n      -\t\tif (options.type == REBASE_PRESERVE_MERGES)\n      -\t\t\tdie(\"cannot combine '--signoff' with \"\n      -\t\t\t    \"'--preserve-merges'\");\n     - \t\targv_array_push(&options.git_am_opts, \"--signoff\");\n     + \t\tstrvec_push(&options.git_am_opts, \"--signoff\");\n       \t\toptions.flags |= REBASE_FORCE;\n       \t}\n       \n     @@ git-rebase--preserve-merges.sh (deleted)\n      -\tfi\n      -}\n      -\n     --# Put the last action marked done at the beginning of the todo list\n     --# again. If there has not been an action marked done yet, leave the list of\n     --# items on the todo list unchanged.\n     --reschedule_last_action () {\n     --\ttail -n 1 \"$done\" | cat - \"$todo\" >\"$todo\".new\n     --\tsed -e \\$d <\"$done\" >\"$done\".new\n     --\tmv -f \"$todo\".new \"$todo\"\n     --\tmv -f \"$done\".new \"$done\"\n     --}\n     --\n      -append_todo_help () {\n      -\tgettext \"\n      -Commands:\n 6:  b7ba83969da = 6:  a987e9439af git-svn: drop support for `--preserve-merges`\n 7:  634e4141e97 ! 7:  4492cca369c rebase: drop the internal `rebase--interactive` command\n     @@ builtin/rebase.c: static const char *action_names[] = { \"undefined\",\n       static int edit_todo_file(unsigned flags)\n       {\n       \tconst char *todo_file = rebase_path_todo();\n     -@@ builtin/rebase.c: static int run_rebase_interactive(struct rebase_options *opts,\n     +@@ builtin/rebase.c: static int run_sequencer_rebase(struct rebase_options *opts,\n       \n       \t\tbreak;\n       \t}\n     @@ builtin/rebase.c: static int run_rebase_interactive(struct rebase_options *opts,\n       \tdefault:\n       \t\tBUG(\"invalid command '%d'\", command);\n       \t}\n     -@@ builtin/rebase.c: static int run_rebase_interactive(struct rebase_options *opts,\n     - \treturn ret;\n     +@@ builtin/rebase.c: static int parse_opt_keep_empty(const struct option *opt, const char *arg,\n     + \treturn 0;\n       }\n       \n      -static const char * const builtin_rebase_interactive_usage[] = {\n     @@ builtin/rebase.c: static int run_rebase_interactive(struct rebase_options *opts,\n      -int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n      -{\n      -\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n     --\tstruct object_id squash_onto = null_oid;\n     +-\tstruct object_id squash_onto = *null_oid();\n      -\tenum action command = ACTION_NONE;\n      -\tstruct option options[] = {\n      -\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n      -\t\t\t   REBASE_FORCE),\n     --\t\tOPT_BOOL(0, \"keep-empty\", &opts.keep_empty, N_(\"keep empty commits\")),\n     --\t\tOPT_BOOL(0, \"allow-empty-message\", &opts.allow_empty_message,\n     --\t\t\t N_(\"allow commits with empty messages\")),\n     +-\t\tOPT_CALLBACK_F('k', \"keep-empty\", &options, NULL,\n     +-\t\t\tN_(\"keep commits which start empty\"),\n     +-\t\t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN,\n     +-\t\t\tparse_opt_keep_empty),\n     +-\t\tOPT_BOOL_F(0, \"allow-empty-message\", &opts.allow_empty_message,\n     +-\t\t\t   N_(\"allow commits with empty messages\"),\n     +-\t\t\t   PARSE_OPT_HIDDEN),\n      -\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase merge commits\")),\n      -\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n      -\t\t\t N_(\"keep original branch points of cousins\")),\n     @@ builtin/rebase.c: static int run_rebase_interactive(struct rebase_options *opts,\n      -\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n      -\t\t\t  \"--rebase-merges\"));\n      -\n     --\treturn !!run_rebase_interactive(&opts, command);\n     +-\treturn !!run_sequencer_rebase(&opts, command);\n      -}\n      -\n     - static int is_interactive(struct rebase_options *opts)\n     + static int is_merge(struct rebase_options *opts)\n       {\n     - \treturn opts->type == REBASE_INTERACTIVE;\n     + \treturn opts->type == REBASE_MERGE;\n      \n       ## git.c ##\n      @@ git.c: static struct cmd_struct commands[] = {\n 8:  45fee72059d < -:  ----------- remote: no longer claim that branch.*.rebase=preserve is a thing\n\n-- \ngitgitgadget\n"},{"id":"434417","messageId":"8da29d539fc2c9700630d5ec4a80cacf64d44aa0.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 1/7] t5520: do not use `pull.rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:08Z","receivedAt":"2021-09-01T11:57:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nEven if those tests try to override that setting, let's not use it\nbecause it is deprecated: let's use `merges` instead.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t5520-pull.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex e2c0c510222..bb9b6b900eb 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -598,7 +598,7 @@ test_expect_success '--rebase=false create a new merge commit' '\n \n test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase=true . copy &&\n \ttest_cmp_rev HEAD^^ copy &&\n \techo file3 >expect &&\n@@ -620,9 +620,9 @@ test_expect_success '--rebase=invalid fails' '\n \ttest_must_fail git pull --rebase=invalid . copy\n '\n \n-test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '\n+test_expect_success '--rebase overrides pull.rebase=merges and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase . copy &&\n \ttest_cmp_rev HEAD^^ copy &&\n \techo file3 >expect &&\n-- \ngitgitgadget\n\n"},{"id":"434418","messageId":"acda0f599475c07c6c1a5e75384e0cff98d2c19f.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 2/7] remote: warn about unhandled branch.<name>.rebase values","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:09Z","receivedAt":"2021-09-01T11:57:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe ignore them silently, but it actually makes sense to warn the users\nthat their config setting has no effect.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/remote.c | 3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..5705e088e5b 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -318,6 +318,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t * truth value with >= REBASE_TRUE.\n \t\t */\n \t\tinfo->rebase = rebase_parse_value(value);\n+\t\tif (info->rebase == REBASE_INVALID)\n+\t\t\twarning(_(\"unhandled branch.%s.rebase=%s; assuming \"\n+\t\t\t\t  \"'true'\"), name, value);\n \t\tbreak;\n \tcase PUSH_REMOTE:\n \t\tif (info->push_remote_name)\n-- \ngitgitgadget\n\n"},{"id":"434421","messageId":"b493046134d2e593df689ede62d037eaac8ac8e0.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 4/7] pull: remove support for `--rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:11Z","receivedAt":"2021-09-01T11:57:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn preparation for `git-rebase--preserve-merges.sh` entering its after\nlife, we remove this (deprecated) option that would still rely on it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config/branch.txt        | 4 ----\n Documentation/config/pull.txt          | 4 ----\n Documentation/git-pull.txt             | 6 +-----\n builtin/pull.c                         | 9 +++------\n contrib/completion/git-completion.bash | 2 +-\n rebase.c                               | 2 --\n rebase.h                               | 1 -\n 7 files changed, 5 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt\nindex cc5f3249fc5..d323d7327f6 100644\n--- a/Documentation/config/branch.txt\n+++ b/Documentation/config/branch.txt\n@@ -85,10 +85,6 @@ When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive` (or just 'i'), the rebase is run in interactive\n mode.\n +\ndiff --git a/Documentation/config/pull.txt b/Documentation/config/pull.txt\nindex 54048306095..9349e09261b 100644\n--- a/Documentation/config/pull.txt\n+++ b/Documentation/config/pull.txt\n@@ -18,10 +18,6 @@ When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive` (or just 'i'), the rebase is run in interactive\n mode.\n +\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 7f4b2d1982e..7144690a0cb 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -102,7 +102,7 @@ Options related to merging\n include::merge-options.txt[]\n \n -r::\n---rebase[=false|true|merges|preserve|interactive]::\n+--rebase[=false|true|merges|interactive]::\n \tWhen true, rebase the current branch on top of the upstream\n \tbranch after fetching. If there is a remote-tracking branch\n \tcorresponding to the upstream branch and the upstream branch\n@@ -113,10 +113,6 @@ When set to `merges`, rebase using `git rebase --rebase-merges` so that\n the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When set to `preserve` (deprecated in favor of `merges`), rebase with the\n-`--preserve-merges` option passed to `git rebase` so that locally created\n-merge commits will not be flattened.\n-+\n When false, merge the upstream branch into the current branch.\n +\n When `interactive`, enable the interactive mode of rebase.\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 3e13f810843..bda5c32ab6f 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -30,9 +30,8 @@\n /**\n  * Parses the value of --rebase. If value is a false value, returns\n  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n- * \"merges\", returns REBASE_MERGES. If value is \"preserve\", returns\n- * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if\n- * fatal is true, otherwise returns REBASE_INVALID.\n+ * \"merges\", returns REBASE_MERGES. If value is a invalid value, dies with\n+ * a fatal error if fatal is true, otherwise returns REBASE_INVALID.\n  */\n static enum rebase_type parse_config_rebase(const char *key, const char *value,\n \t\tint fatal)\n@@ -126,7 +125,7 @@ static struct option pull_options[] = {\n \t/* Options passed to git-merge or git-rebase */\n \tOPT_GROUP(N_(\"Options related to merging\")),\n \tOPT_CALLBACK_F('r', \"rebase\", &opt_rebase,\n-\t\t\"(false|true|merges|preserve|interactive)\",\n+\t\t\"(false|true|merges|interactive)\",\n \t\tN_(\"incorporate changes by rebasing rather than merging\"),\n \t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n@@ -883,8 +882,6 @@ static int run_rebase(const struct object_id *newbase,\n \t/* Options passed to git-rebase */\n \tif (opt_rebase == REBASE_MERGES)\n \t\tstrvec_push(&args, \"--rebase-merges\");\n-\telse if (opt_rebase == REBASE_PRESERVE)\n-\t\tstrvec_push(&args, \"--preserve-merges\");\n \telse if (opt_rebase == REBASE_INTERACTIVE)\n \t\tstrvec_push(&args, \"--interactive\");\n \tif (opt_diffstat)\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc87..5dab8bd579e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2543,7 +2543,7 @@ __git_complete_config_variable_value ()\n \t\treturn\n \t\t;;\n \tbranch.*.rebase)\n-\t\t__gitcomp \"false true merges preserve interactive\" \"\" \"$cur_\"\n+\t\t__gitcomp \"false true merges interactive\" \"\" \"$cur_\"\n \t\treturn\n \t\t;;\n \tremote.pushdefault)\ndiff --git a/rebase.c b/rebase.c\nindex f8137d859b5..877c068687c 100644\n--- a/rebase.c\n+++ b/rebase.c\n@@ -20,8 +20,6 @@ enum rebase_type rebase_parse_value(const char *value)\n \t\treturn REBASE_FALSE;\n \telse if (v > 0)\n \t\treturn REBASE_TRUE;\n-\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n-\t\treturn REBASE_PRESERVE;\n \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n \t\treturn REBASE_MERGES;\n \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\ndiff --git a/rebase.h b/rebase.h\nindex cc723d47489..203b4372823 100644\n--- a/rebase.h\n+++ b/rebase.h\n@@ -5,7 +5,6 @@ enum rebase_type {\n \tREBASE_INVALID = -1,\n \tREBASE_FALSE = 0,\n \tREBASE_TRUE,\n-\tREBASE_PRESERVE,\n \tREBASE_MERGES,\n \tREBASE_INTERACTIVE\n };\n-- \ngitgitgadget\n\n"},{"id":"434420","messageId":"cdb9fae4b939d4ce81372c0a0d81458eeb9b6299.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 3/7] tests: stop testing `git rebase --preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:10Z","receivedAt":"2021-09-01T11:57:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis backend has been deprecated in favor of `git rebase\n--rebase-merges`.\n\nIn preparation for dropping it, let's remove all the regression tests\nthat would need it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .github/workflows/main.yml                |   1 -\n t/t3404-rebase-interactive.sh             |  76 -----------\n t/t3408-rebase-multi-line.sh              |  10 --\n t/t3409-rebase-preserve-merges.sh         | 130 -------------------\n t/t3410-rebase-preserve-dropped-merges.sh |  90 -------------\n t/t3411-rebase-preserve-around-merges.sh  |  80 ------------\n t/t3412-rebase-root.sh                    |  37 ------\n t/t3414-rebase-preserve-onto.sh           |  85 ------------\n t/t3418-rebase-continue.sh                |  15 ---\n t/t3421-rebase-topology-linear.sh         |  19 ---\n t/t3422-rebase-incompatible-options.sh    |  11 --\n t/t3425-rebase-topology-merges.sh         | 151 ----------------------\n t/t3427-rebase-subtree.sh                 |  19 ---\n t/t5520-pull.sh                           |  18 ---\n t/t7505-prepare-commit-msg-hook.sh        |   1 -\n t/t7517-per-repo-email.sh                 |  13 --\n t/test-lib.sh                             |   4 -\n 17 files changed, 760 deletions(-)\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex 47876a4f02e..6115755c4df 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -198,7 +198,6 @@ jobs:\n       shell: bash\n       env:\n         NO_SVN_TESTS: 1\n-        GIT_TEST_SKIP_REBASE_P: 1\n       run: ci/run-test-slice.sh ${{matrix.nr}} 10\n     - name: ci/print-test-failures.sh\n       if: failure()\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 66bcbbf9528..827b0450b9f 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -351,82 +351,6 @@ test_expect_success 'retain authorship when squashing' '\n \tgit show HEAD | grep \"^Author: Twerp Snog\"\n '\n \n-test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n-\tHEAD=$(git rev-parse HEAD) &&\n-\tgit rebase -i -p HEAD^ &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $HEAD = $(git rev-parse HEAD)\n-'\n-\n-test_expect_failure REBASE_P 'exchange two commits with -p' '\n-\tgit checkout H &&\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2\n-\t) &&\n-\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n-\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n-'\n-\n-test_expect_success REBASE_P 'preserve merges with -p' '\n-\tgit checkout -b to-be-preserved primary^ &&\n-\t: > unrelated-file &&\n-\tgit add unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m \"unrelated\" &&\n-\tgit checkout -b another-branch primary &&\n-\techo B > file1 &&\n-\ttest_tick &&\n-\tgit commit -m J file1 &&\n-\ttest_tick &&\n-\tgit merge to-be-preserved &&\n-\techo C > file1 &&\n-\ttest_tick &&\n-\tgit commit -m K file1 &&\n-\techo D > file1 &&\n-\ttest_tick &&\n-\tgit commit -m L1 file1 &&\n-\tgit checkout HEAD^ &&\n-\techo 1 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2 unrelated-file &&\n-\ttest_tick &&\n-\tgit merge another-branch &&\n-\techo E > file1 &&\n-\ttest_tick &&\n-\tgit commit -m M file1 &&\n-\tgit checkout -b to-be-rebased &&\n-\ttest_tick &&\n-\tgit rebase -i -p --onto branch1 primary &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest_cmp_rev HEAD~6 branch1 &&\n-\ttest_cmp_rev HEAD~4^2 to-be-preserved &&\n-\ttest_cmp_rev HEAD^^2^ HEAD^^^ &&\n-\ttest $(git show HEAD~5:file1) = B &&\n-\ttest $(git show HEAD~3:file1) = C &&\n-\ttest $(git show HEAD:file1) = E &&\n-\ttest $(git show HEAD:unrelated-file) = 1\n-'\n-\n-test_expect_success REBASE_P 'edit ancestor with -p' '\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3\n-\t) &&\n-\techo 2 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2-modified --amend unrelated-file &&\n-\tgit rebase --continue &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $(git show HEAD:unrelated-file) = 2\n-'\n-\n test_expect_success '--continue tries to commit' '\n \tgit reset --hard D &&\n \ttest_tick &&\ndiff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh\nindex ab0960e6d99..cde3562e3a6 100755\n--- a/t/t3408-rebase-multi-line.sh\n+++ b/t/t3408-rebase-multi-line.sh\n@@ -55,14 +55,4 @@ test_expect_success rebase '\n \ttest_cmp expect actual\n \n '\n-test_expect_success REBASE_P rebasep '\n-\n-\tgit checkout side-merge &&\n-\tgit rebase -p side &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual &&\n-\tgit cat-file commit side-merge-original | sed -e \"1,/^\\$/d\" >expect &&\n-\ttest_cmp expect actual\n-\n-'\n-\n test_done\ndiff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh\ndeleted file mode 100755\nindex ec8062a66ac..00000000000\n--- a/t/t3409-rebase-preserve-merges.sh\n+++ /dev/null\n@@ -1,130 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright(C) 2008 Stephen Habermann & Andreas Ericsson\n-#\n-test_description='git rebase -p should preserve merges\n-\n-Run \"git rebase -p\" and check that merges are properly carried along\n-'\n-GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n-export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-GIT_AUTHOR_EMAIL=bogus_email_address\n-export GIT_AUTHOR_EMAIL\n-\n-# Clone 2 (conflicting merge):\n-#\n-# A1--A2--B3   <-- origin/main\n-#  \\       \\\n-#   B1------M  <-- topic\n-#    \\\n-#     B2       <-- origin/topic\n-#\n-# Clone 3 (no-ff merge):\n-#\n-# A1--A2--B3   <-- origin/main\n-#  \\\n-#   B1------M  <-- topic\n-#    \\     /\n-#     \\--A3    <-- topic2\n-#      \\\n-#       B2     <-- origin/topic\n-#\n-# Clone 4 (same as Clone 3)\n-\n-test_expect_success 'setup for merge-preserving rebase' \\\n-\t'echo First > A &&\n-\tgit add A &&\n-\tgit commit -m \"Add A1\" &&\n-\tgit checkout -b topic &&\n-\techo Second > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add B1\" &&\n-\tgit checkout -f main &&\n-\techo Third >> A &&\n-\tgit commit -a -m \"Modify A2\" &&\n-\techo Fifth > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add different B\" &&\n-\n-\tgit clone ./. clone2 &&\n-\t(\n-\t\tcd clone2 &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\ttest_must_fail git merge origin/main &&\n-\t\techo Resolved >B &&\n-\t\tgit add B &&\n-\t\tgit commit -m \"Merge origin/main into topic\"\n-\t) &&\n-\n-\tgit clone ./. clone3 &&\n-\t(\n-\t\tcd clone3 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit clone ./. clone4 &&\n-\t(\n-\t\tcd clone4 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit checkout topic &&\n-\techo Fourth >> B &&\n-\tgit commit -a -m \"Modify B2\"\n-'\n-\n-test_expect_success '--continue works after a conflict' '\n-\t(\n-\tcd clone2 &&\n-\tgit fetch &&\n-\ttest_must_fail git rebase -p origin/topic &&\n-\ttest 2 = $(git ls-files B | wc -l) &&\n-\techo Resolved again > B &&\n-\ttest_must_fail git rebase --continue &&\n-\tgrep \"^@@@ \" .git/rebase-merge/patch &&\n-\tgit add B &&\n-\tgit rebase --continue &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Add different\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge origin\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p preserves no-ff merges' '\n-\t(\n-\tcd clone3 &&\n-\tgit fetch &&\n-\tgit rebase -p origin/topic &&\n-\ttest 3 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge branch\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p ignores merge.log config' '\n-\t(\n-\tcd clone4 &&\n-\tgit fetch &&\n-\tgit -c merge.log=1 rebase -p origin/topic &&\n-\techo >expected &&\n-\tgit log --format=\"%b\" -1 >current &&\n-\ttest_cmp expected current\n-\t)\n-'\n-\n-test_done\ndiff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh\ndeleted file mode 100755\nindex 2e29866993c..00000000000\n--- a/t/t3410-rebase-preserve-dropped-merges.sh\n+++ /dev/null\n@@ -1,90 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with preserve merges and ensures commits\n-dropped by the --cherry-pick flag have their childrens parents\n-rewritten.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-# set up two branches like this:\n-#\n-# A - B - C - D - E\n-#   \\\n-#     F - G - H\n-#       \\\n-#         I\n-#\n-# where B, D and G touch the same file.\n-\n-test_expect_success 'setup' '\n-\ttest_commit A file1 &&\n-\ttest_commit B file1 1 &&\n-\ttest_commit C file2 &&\n-\ttest_commit D file1 2 &&\n-\ttest_commit E file3 &&\n-\tgit checkout A &&\n-\ttest_commit F file4 &&\n-\ttest_commit G file1 3 &&\n-\ttest_commit H file5 &&\n-\tgit checkout F &&\n-\ttest_commit I file6\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L \\        -->   L\n-#       \\            |               \\\n-#         I -- G2 -- J -- K           I -- K\n-# G2 = same changes as G\n-test_expect_success 'skip same-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G2 file1 3 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J file1 23 &&\n-\ttest_commit K file7 file7 &&\n-\tgit rebase -i -p L &&\n-\ttest $(git rev-parse HEAD^^) = $(git rev-parse L) &&\n-\ttest \"23\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L2 \\        -->   L2\n-#       \\             |                \\\n-#         I -- G3 --- J2 -- K2           I -- G3 -- K2\n-# G2 = different changes as G\n-test_expect_success 'keep different-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L2 file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G3 file1 4 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J2 file1 24 &&\n-\ttest_commit K2 file7 file7 &&\n-\ttest_must_fail git rebase -i -p L2 &&\n-\techo 234 > file1 &&\n-\tgit add file1 &&\n-\tgit rebase --continue &&\n-\ttest $(git rev-parse HEAD^^^) = $(git rev-parse L2) &&\n-\ttest \"234\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-test_done\ndiff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh\ndeleted file mode 100755\nindex fb45e7bf7bd..00000000000\n--- a/t/t3411-rebase-preserve-around-merges.sh\n+++ /dev/null\n@@ -1,80 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with -p and tries to squash a commit from after\n-a merge to before the merge.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-set_fake_editor\n-\n-# set up two branches like this:\n-#\n-# A1 - B1 - D1 - E1 - F1\n-#       \\        /\n-#        -- C1 --\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit D1 &&\n-\ttest_merge E1 C1 &&\n-\ttest_commit F1\n-'\n-\n-# Should result in:\n-#\n-# A1 - B1 - D2 - E2\n-#       \\        /\n-#        -- C1 --\n-#\n-test_expect_success 'squash F1 into D1' '\n-\tFAKE_LINES=\"1 squash 4 2 3\" git rebase -i -p B1 &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse C1)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse B1)\" &&\n-\tgit tag E2\n-'\n-\n-# Start with:\n-#\n-# A1 - B1 - D2 - E2\n-#  \\\n-#   G1 ---- L1 ---- M1\n-#    \\             /\n-#     H1 -- J1 -- K1\n-#      \\         /\n-#        -- I1 --\n-#\n-# And rebase G1..M1 onto E2\n-\n-test_expect_success 'rebase two levels of merge' '\n-\tgit checkout A1 &&\n-\ttest_commit G1 &&\n-\ttest_commit H1 &&\n-\ttest_commit I1 &&\n-\tgit checkout -b branch3 H1 &&\n-\ttest_commit J1 &&\n-\ttest_merge K1 I1 &&\n-\tgit checkout -b branch2 G1 &&\n-\ttest_commit L1 &&\n-\ttest_merge M1 K1 &&\n-\tGIT_EDITOR=: git rebase -i -p E2 &&\n-\ttest \"$(git rev-parse HEAD~3)\" = \"$(git rev-parse E2)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse HEAD^2^2~2)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse HEAD^2^2^1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh\nindex fda62c65bd5..19c6f4acbf6 100755\n--- a/t/t3412-rebase-root.sh\n+++ b/t/t3412-rebase-root.sh\n@@ -89,17 +89,6 @@ test_expect_success 'pre-rebase got correct input (4)' '\n \ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,work4\n '\n \n-test_expect_success REBASE_P 'rebase -i -p with linear history' '\n-\tgit checkout -b work5 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tgit log --pretty=tformat:\"%s\" > rebased5 &&\n-\ttest_cmp expect rebased5\n-'\n-\n-test_expect_success REBASE_P 'pre-rebase got correct input (5)' '\n-\ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,\n-'\n-\n test_expect_success 'set up merge history' '\n \tgit checkout other^ &&\n \tgit checkout -b side &&\n@@ -123,13 +112,6 @@ commit work6~4\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with merge' '\n-\tgit checkout -b work6 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tlog_with_names work6 > rebased6 &&\n-\ttest_cmp expect-side rebased6\n-'\n-\n test_expect_success 'set up second root and merge' '\n \tgit symbolic-ref HEAD refs/heads/third &&\n \trm .git/index &&\n@@ -158,13 +140,6 @@ commit work7~5\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with two roots' '\n-\tgit checkout -b work7 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tlog_with_names work7 > rebased7 &&\n-\ttest_cmp expect-third rebased7\n-'\n-\n test_expect_success 'setup pre-rebase hook that fails' '\n \tmkdir -p .git/hooks &&\n \tcat >.git/hooks/pre-rebase <<EOF &&\n@@ -264,21 +239,9 @@ commit conflict3~6\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' '\n-\tgit checkout -b conflict3 other &&\n-\ttest_must_fail git rebase -i -p --root --onto main &&\n-\tgit ls-files -u | grep \"B$\"\n-'\n-\n test_expect_success 'fix the conflict' '\n \techo 3 > B &&\n \tgit add B\n '\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (second part)' '\n-\tgit rebase --continue &&\n-\tlog_with_names conflict3 >out &&\n-\ttest_cmp expect-conflict-p out\n-'\n-\n test_done\ndiff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh\ndeleted file mode 100755\nindex 72e04b5386a..00000000000\n--- a/t/t3414-rebase-preserve-onto.sh\n+++ /dev/null\n@@ -1,85 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2009 Greg Price\n-#\n-\n-test_description='git rebase -p should respect --onto\n-\n-In a rebase with --onto, we should rewrite all the commits that\n-aren'\"'\"'t on top of $ONTO, even if they are on top of $UPSTREAM.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-# Set up branches like this:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    H1\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\ttest_commit D1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit E1 &&\n-\ttest_commit F1 &&\n-\ttest_merge G1 D1 &&\n-\tgit reset --hard A1 &&\n-\ttest_commit H1\n-'\n-\n-# Now rebase merge G1 from both branches' base B1, both should move:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\\n-#     H1---E2---F2---G2\n-#      \\             /\n-#       \\--C2---D2--/\n-\n-test_expect_success 'rebase from B1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 B1 &&\n-\ttest \"$(git rev-parse HEAD^1^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse H1)\"\n-'\n-\n-# On the other hand if rebase from E1 which is within one branch,\n-# then the other branch stays:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\             \\\n-#     H1-----F3-----G3\n-\n-test_expect_success 'rebase from E1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 E1 &&\n-\ttest \"$(git rev-parse HEAD^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse D1)\"\n-'\n-\n-# And the same if we rebase from a commit in the second-parent branch.\n-# A1---B1---E1---F1----G1\n-#  \\    \\          \\   /\n-#   \\    \\--C1---D1-\\-/\n-#    \\               \\\n-#     H1------D3------G4\n-\n-test_expect_success 'rebase from C1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rev-list --first-parent --pretty=oneline C1..G1 &&\n-\tgit rebase -p --onto H1 C1 &&\n-\ttest \"$(git rev-parse HEAD^2^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^1)\" = \"$(git rev-parse F1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex f4c2ee02bc9..b62c16026fc 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -109,20 +109,6 @@ test_expect_success 'rebase -i --continue handles merge strategy and options' '\n \ttest -f funny.was.run\n '\n \n-test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '\n-\trm -fr .git/rebase-* &&\n-\tgit reset --hard commit-new-file-F3-on-topic-branch &&\n-\ttest_commit theirs-to-merge &&\n-\tgit reset --hard HEAD^ &&\n-\ttest_commit some-commit &&\n-\ttest_tick &&\n-\tgit merge --no-ff theirs-to-merge &&\n-\tFAKE_LINES=\"1 edit 2 3\" git rebase -i -f -p -m \\\n-\t\t-s recursive --strategy-option=theirs HEAD~2 &&\n-\ttest_commit force-change &&\n-\tgit rebase --continue\n-'\n-\n test_expect_success 'rebase -r passes merge strategy options correctly' '\n \trm -fr .git/rebase-* &&\n \tgit reset --hard commit-new-file-F3-on-topic-branch &&\n@@ -258,7 +244,6 @@ test_rerere_autoupdate\n test_rerere_autoupdate -m\n GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR\n test_rerere_autoupdate -i\n-test_have_prereq !REBASE_P || test_rerere_autoupdate --preserve-merges\n unset GIT_SEQUENCE_EDITOR\n \n test_expect_success 'the todo command \"break\" works' '\ndiff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh\nindex 4a9204b4b64..62d86d557da 100755\n--- a/t/t3421-rebase-topology-linear.sh\n+++ b/t/t3421-rebase-topology-linear.sh\n@@ -29,7 +29,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_expect_success 'setup branches and remote tracking' '\n \tgit tag -l >tags &&\n@@ -53,7 +52,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -70,7 +68,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -87,7 +84,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -102,7 +98,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n #       f\n #      /\n@@ -142,7 +137,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -157,7 +151,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -172,7 +165,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -187,7 +179,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n # a---b---c---j!\n #      \\\n@@ -215,7 +206,6 @@ test_run_rebase () {\n test_run_rebase failure --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -229,7 +219,6 @@ test_run_rebase () {\n }\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -243,7 +232,6 @@ test_run_rebase () {\n }\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n test_run_rebase success --rebase-merges\n \n #       m\n@@ -283,7 +271,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -298,7 +285,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -313,7 +299,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -329,7 +314,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -344,7 +328,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -358,7 +341,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -373,6 +355,5 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_done\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex c8234062c6c..eb0a3d9d487 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -63,15 +63,4 @@ test_rebase_am_only () {\n test_rebase_am_only --whitespace=fix\n test_rebase_am_only -C4\n \n-test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --signoff A\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'--preserve-merges incompatible with --rebase-merges' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --rebase-merges A\n-'\n-\n test_done\ndiff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh\nindex e42faa44e74..63acc1ea4da 100755\n--- a/t/t3425-rebase-topology-merges.sh\n+++ b/t/t3425-rebase-topology-merges.sh\n@@ -106,155 +106,4 @@ test_run_rebase success 'd n o e' --apply\n test_run_rebase success 'd n o e' -m\n test_run_rebase success 'd n o e' -i\n \n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-test_expect_success \"rebase -p is no-op in non-linear history\" \"\n-\treset_rebase &&\n-\tgit rebase -p d w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p is no-op when base inside second parent\" \"\n-\treset_rebase &&\n-\tgit rebase -p e w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_failure \"rebase -p --root on non-linear history is a no-op\" \"\n-\treset_rebase &&\n-\tgit rebase -p --root w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates merge from side branch\" \"\n-\treset_rebase &&\n-\tgit rebase -p z w &&\n-\ttest_cmp_rev z HEAD^ &&\n-\ttest_cmp_rev w^2 HEAD^2\n-\"\n-\n-test_expect_success \"rebase -p re-creates internal merge\" \"\n-\treset_rebase &&\n-\tgit rebase -p c w &&\n-\ttest_cmp_rev c HEAD~4 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~3 &&\n-\ttest_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p can re-create two branches on onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto c d w &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev c HEAD^2^ &&\n-\ttest_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-#       f\n-#      /\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--i\n-#        \\       \\\n-#         e-------u\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for patch-equivalence tests' '\n-\tgit checkout e &&\n-\ttest_merge u i\n-'\n-\n-test_expect_success \"rebase -p re-creates history around dropped commit matching upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p h u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history drops patches in upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto f h u &&\n-\ttest_cmp_rev f HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history does not drop patches in onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto h f u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2~2 HEAD~2 &&\n-\ttest_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD\n-\"\n-\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--s\n-#        \\   \\ /\n-#         \\   X\n-#          \\ / \\\n-#           e---t\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for dropping whole side' '\n-\tgit checkout gp &&\n-\ttest_merge s e &&\n-\tgit checkout e &&\n-\ttest_merge t gp\n-'\n-\n-test_expect_failure \"rebase -p drops merge commit when entire first-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h s &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-test_expect_success \"rebase -p drops merge commit when entire second-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h t &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-# a---b---c\n-#      \\\n-#       d---e\n-#        \\   \\\n-#         n---r\n-#          \\\n-#           o\n-#\n-# r = tree-same with n\n-test_expect_success 'setup of non-linear-history for empty commits' '\n-\tgit checkout n &&\n-\tgit merge --no-commit e &&\n-\tgit reset n . &&\n-\tgit commit -m r &&\n-\tgit reset --hard &&\n-\tgit clean -f &&\n-\tgit tag r\n-'\n-\n-test_expect_success \"rebase -p re-creates empty internal merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p c r &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates empty merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p o r &&\n-\ttest_cmp_rev e HEAD^2 &&\n-\ttest_cmp_rev o HEAD^ &&\n-\ttest_revision_subjects 'r' HEAD\n-\"\n-\n test_done\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex e78c7e37969..3bb023d7669 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -69,25 +69,6 @@ test_expect_success 'setup' '\n \tgit commit -m \"Empty commit\" --allow-empty\n '\n \n-# FAILURE: Does not preserve topic_4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-main main &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"topic_4\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"files_subtree/topic_5\"\n-'\n-\n-# FAILURE: Does not preserve topic_4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-main main &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"topic_4\" &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/topic_5\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n-'\n-\n test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex bb9b6b900eb..a2924036ad4 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -546,15 +546,6 @@ test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success REBASE_P \\\n-\t'pull.rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n-\tgit pull . copy &&\n-\ttest_cmp_rev HEAD^^ copy &&\n-\ttest_cmp_rev HEAD^2 keep-merge\n-'\n-\n test_expect_success 'pull.rebase=interactive' '\n \twrite_script \"$TRASH_DIRECTORY/fake-editor\" <<-\\EOF &&\n \techo I was here >fake.out &&\n@@ -606,15 +597,6 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success REBASE_P \\\n-\t'--rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n-\tgit pull --rebase=preserve . copy &&\n-\ttest_cmp_rev HEAD^^ copy &&\n-\ttest_cmp_rev HEAD^2 keep-merge\n-'\n-\n test_expect_success '--rebase=invalid fails' '\n \tgit reset --hard before-preserve-rebase &&\n \ttest_must_fail git pull --rebase=invalid . copy\ndiff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh\nindex 7a8194ce720..2a07c708679 100755\n--- a/t/t7505-prepare-commit-msg-hook.sh\n+++ b/t/t7505-prepare-commit-msg-hook.sh\n@@ -250,7 +250,6 @@ test_rebase () {\n }\n \n test_rebase success\n-test_have_prereq !REBASE_P || test_rebase success -p\n \n test_expect_success 'with hook (cherry-pick)' '\n \ttest_when_finished \"git checkout -f main\" &&\ndiff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\nindex 405420ae4d8..163ae804685 100755\n--- a/t/t7517-per-repo-email.sh\n+++ b/t/t7517-per-repo-email.sh\n@@ -75,19 +75,6 @@ test_expect_success 'noop interactive rebase does not care about ident' '\n \tgit rebase -i HEAD^\n '\n \n-test_expect_success REBASE_P \\\n-\t'fast-forward rebase does not care about ident (preserve)' '\n-\tgit checkout -B tmp side-without-commit &&\n-\tgit rebase -p main\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'non-fast-forward rebase refuses to write commits (preserve)' '\n-\ttest_when_finished \"git rebase --abort || true\" &&\n-\tgit checkout -B tmp side-with-commit &&\n-\ttest_must_fail git rebase -p main\n-'\n-\n test_expect_success 'author.name overrides user.name' '\n \ttest_config user.name user &&\n \ttest_config user.email user@example.com &&\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex abcfbed6d61..11a9c8a6516 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -1708,10 +1708,6 @@ test_lazy_prereq SHA1 '\n \tesac\n '\n \n-test_lazy_prereq REBASE_P '\n-\ttest -z \"$GIT_TEST_SKIP_REBASE_P\"\n-'\n-\n # Ensure that no test accidentally triggers a Git command\n # that runs the actual maintenance scheduler, affecting a user's\n # system permanently.\n-- \ngitgitgadget\n\n"},{"id":"434419","messageId":"a987e9439af6335e15a3d41b82832e9a8824317b.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 6/7] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:13Z","receivedAt":"2021-09-01T11:57:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe already passed the `--rebase-merges` option to `git rebase` instead,\nnow we make this move permanent.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-svn.txt | 1 -\n git-svn.perl              | 1 -\n 2 files changed, 2 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex d5776ffcfd5..222b556d7a9 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -678,7 +678,6 @@ config key: svn.authorsProg\n --strategy=<strategy>::\n -p::\n --rebase-merges::\n---preserve-merges (DEPRECATED)::\n \tThese are only used with the 'dcommit' and 'rebase' commands.\n +\n Passed directly to 'git rebase' when using 'dcommit' if a\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 70cb5e2a83b..be987e316f9 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -273,7 +273,6 @@ my %cmd = (\n \t\t\t  'fetch-all|all' => \\$_fetch_all,\n \t\t\t  'dry-run|n' => \\$_dry_run,\n \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n-\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n \t\t\t  %fc_opts } ],\n \t'commit-diff' => [ \\&cmd_commit_diff,\n \t                   'Commit a diff between two trees',\n-- \ngitgitgadget\n\n"},{"id":"434423","messageId":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:12Z","receivedAt":"2021-09-01T11:57:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis option was deprecated in favor of `--rebase-merges` some time ago,\nand now we retire it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .gitignore                     |    1 -\n Documentation/git-rebase.txt   |   51 --\n Makefile                       |    2 -\n builtin/rebase.c               |  133 +---\n git-rebase--preserve-merges.sh | 1057 --------------------------------\n 5 files changed, 6 insertions(+), 1238 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 311841f9bed..98d6275b20d 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -125,7 +125,6 @@\n /git-range-diff\n /git-read-tree\n /git-rebase\n-/git-rebase--preserve-merges\n /git-receive-pack\n /git-reflog\n /git-remote\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 55af6fd24e2..1382dc6f005 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -525,29 +525,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s\n the `rebase-cousins` mode is turned on, such commits are instead rebased\n onto `<upstream>` (or `<onto>`, if specified).\n +\n-The `--rebase-merges` mode is similar in spirit to the deprecated\n-`--preserve-merges` but works with interactive rebases,\n-where commits can be reordered, inserted and dropped at will.\n-+\n It is currently only possible to recreate the merge commits using the\n `recursive` merge strategy; Different merge strategies can be used only via\n explicit `exec git merge -s <strategy> [...]` commands.\n +\n See also REBASING MERGES and INCOMPATIBLE OPTIONS below.\n \n--p::\n---preserve-merges::\n-\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n-\tinstead of flattening the history by replaying commits a merge commit\n-\tintroduces. Merge conflict resolutions or manual amendments to merge\n-\tcommits are not preserved.\n-+\n-This uses the `--interactive` machinery internally, but combining it\n-with the `--interactive` option explicitly is generally not a good\n-idea unless you know what you are doing (see BUGS below).\n-+\n-See also INCOMPATIBLE OPTIONS below.\n-\n -x <cmd>::\n --exec <cmd>::\n \tAppend \"exec <cmd>\" after each line creating a commit in the\n@@ -579,9 +562,6 @@ See also INCOMPATIBLE OPTIONS below.\n \tthe root commit(s) on a branch.  When used with --onto, it\n \twill skip changes already contained in <newbase> (instead of\n \t<upstream>) whereas without --onto it will operate on every change.\n-\tWhen used together with both --onto and --preserve-merges,\n-\t'all' root commits will be rewritten to have <newbase> as parent\n-\tinstead.\n +\n See also INCOMPATIBLE OPTIONS below.\n \n@@ -643,7 +623,6 @@ are incompatible with the following options:\n  * --allow-empty-message\n  * --[no-]autosquash\n  * --rebase-merges\n- * --preserve-merges\n  * --interactive\n  * --exec\n  * --no-keep-empty\n@@ -654,13 +633,6 @@ are incompatible with the following options:\n \n In addition, the following pairs of options are incompatible:\n \n- * --preserve-merges and --interactive\n- * --preserve-merges and --signoff\n- * --preserve-merges and --rebase-merges\n- * --preserve-merges and --empty=\n- * --preserve-merges and --ignore-whitespace\n- * --preserve-merges and --committer-date-is-author-date\n- * --preserve-merges and --ignore-date\n  * --keep-base and --onto\n  * --keep-base and --root\n  * --fork-point and --root\n@@ -1274,29 +1246,6 @@ CONFIGURATION\n include::config/rebase.txt[]\n include::config/sequencer.txt[]\n \n-BUGS\n-----\n-The todo list presented by the deprecated `--preserve-merges --interactive`\n-does not represent the topology of the revision graph (use `--rebase-merges`\n-instead).  Editing commits and rewording their commit messages should work\n-fine, but attempts to reorder commits tend to produce counterintuitive results.\n-Use `--rebase-merges` in such scenarios instead.\n-\n-For example, an attempt to rearrange\n-------------\n-1 --- 2 --- 3 --- 4 --- 5\n-------------\n-to\n-------------\n-1 --- 2 --- 4 --- 3 --- 5\n-------------\n-by moving the \"pick 4\" line will result in the following history:\n-------------\n-\t3\n-       /\n-1 --- 2 --- 4 --- 5\n-------------\n-\n GIT\n ---\n Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex 9573190f1d7..43f93f61660 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -616,7 +616,6 @@ SCRIPT_SH += git-submodule.sh\n SCRIPT_SH += git-web--browse.sh\n \n SCRIPT_LIB += git-mergetool--lib\n-SCRIPT_LIB += git-rebase--preserve-merges\n SCRIPT_LIB += git-sh-i18n\n SCRIPT_LIB += git-sh-setup\n \n@@ -2649,7 +2648,6 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \\\n \t--keyword=__ --keyword=N__ --keyword=\"__n:1,2\"\n LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)\n LOCALIZED_SH = $(SCRIPT_SH)\n-LOCALIZED_SH += git-rebase--preserve-merges.sh\n LOCALIZED_SH += git-sh-setup.sh\n LOCALIZED_PERL = $(SCRIPT_PERL)\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 33e09619005..5af6aff9c5e 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, \"rebase-merge\")\n enum rebase_type {\n \tREBASE_UNSPECIFIED = -1,\n \tREBASE_APPLY,\n-\tREBASE_MERGE,\n-\tREBASE_PRESERVE_MERGES\n+\tREBASE_MERGE\n };\n \n enum empty_type {\n@@ -571,8 +570,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \n static int is_merge(struct rebase_options *opts)\n {\n-\treturn opts->type == REBASE_MERGE ||\n-\t\topts->type == REBASE_PRESERVE_MERGES;\n+\treturn opts->type == REBASE_MERGE;\n }\n \n static void imply_merge(struct rebase_options *opts, const char *option)\n@@ -582,7 +580,6 @@ static void imply_merge(struct rebase_options *opts, const char *option)\n \t\tdie(_(\"%s requires the merge backend\"), option);\n \t\tbreak;\n \tcase REBASE_MERGE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\tbreak;\n \tdefault:\n \t\topts->type = REBASE_MERGE; /* implied */\n@@ -773,17 +770,6 @@ static struct commit *peel_committish(const char *name)\n \treturn (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);\n }\n \n-static void add_var(struct strbuf *buf, const char *name, const char *value)\n-{\n-\tif (!value)\n-\t\tstrbuf_addf(buf, \"unset %s; \", name);\n-\telse {\n-\t\tstrbuf_addf(buf, \"%s=\", name);\n-\t\tsq_quote_buf(buf, value);\n-\t\tstrbuf_addstr(buf, \"; \");\n-\t}\n-}\n-\n static int move_to_original_branch(struct rebase_options *opts)\n {\n \tstruct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;\n@@ -940,10 +926,8 @@ static int run_am(struct rebase_options *opts)\n \n static int run_specific_rebase(struct rebase_options *opts, enum action action)\n {\n-\tconst char *argv[] = { NULL, NULL };\n-\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n+\tstruct strbuf script_snippet = STRBUF_INIT;\n \tint status;\n-\tconst char *backend, *backend_func;\n \n \tif (opts->type == REBASE_MERGE) {\n \t\t/* Run sequencer-based rebase */\n@@ -960,87 +944,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t}\n \n \t\tstatus = run_sequencer_rebase(opts, action);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tif (opts->type == REBASE_APPLY) {\n+\t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tadd_var(&script_snippet, \"GIT_DIR\", absolute_path(get_git_dir()));\n-\tadd_var(&script_snippet, \"state_dir\", opts->state_dir);\n-\n-\tadd_var(&script_snippet, \"upstream_name\", opts->upstream_name);\n-\tadd_var(&script_snippet, \"upstream\", opts->upstream ?\n-\t\toid_to_hex(&opts->upstream->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"head_name\",\n-\t\topts->head_name ? opts->head_name : \"detached HEAD\");\n-\tadd_var(&script_snippet, \"orig_head\", oid_to_hex(&opts->orig_head));\n-\tadd_var(&script_snippet, \"onto\", opts->onto ?\n-\t\toid_to_hex(&opts->onto->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"onto_name\", opts->onto_name);\n-\tadd_var(&script_snippet, \"revisions\", opts->revisions);\n-\tadd_var(&script_snippet, \"restrict_revision\", opts->restrict_revision ?\n-\t\toid_to_hex(&opts->restrict_revision->object.oid) : NULL);\n-\tsq_quote_argv_pretty(&buf, opts->git_am_opts.v);\n-\tadd_var(&script_snippet, \"git_am_opt\", buf.buf);\n-\tstrbuf_release(&buf);\n-\tadd_var(&script_snippet, \"verbose\",\n-\t\topts->flags & REBASE_VERBOSE ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"diffstat\",\n-\t\topts->flags & REBASE_DIFFSTAT ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"force_rebase\",\n-\t\topts->flags & REBASE_FORCE ? \"t\" : \"\");\n-\tif (opts->switch_to)\n-\t\tadd_var(&script_snippet, \"switch_to\", opts->switch_to);\n-\tadd_var(&script_snippet, \"action\", opts->action ? opts->action : \"\");\n-\tadd_var(&script_snippet, \"signoff\", opts->signoff ? \"--signoff\" : \"\");\n-\tadd_var(&script_snippet, \"allow_rerere_autoupdate\",\n-\t\topts->allow_rerere_autoupdate ?\n-\t\t\topts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?\n-\t\t\t\"--rerere-autoupdate\" : \"--no-rerere-autoupdate\" : \"\");\n-\tadd_var(&script_snippet, \"keep_empty\", opts->keep_empty ? \"yes\" : \"\");\n-\tadd_var(&script_snippet, \"autosquash\", opts->autosquash ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"gpg_sign_opt\", opts->gpg_sign_opt);\n-\tadd_var(&script_snippet, \"cmd\", opts->cmd);\n-\tadd_var(&script_snippet, \"allow_empty_message\",\n-\t\topts->allow_empty_message ?  \"--allow-empty-message\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_merges\",\n-\t\topts->rebase_merges ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_cousins\",\n-\t\topts->rebase_cousins ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"strategy\", opts->strategy);\n-\tadd_var(&script_snippet, \"strategy_opts\", opts->strategy_opts);\n-\tadd_var(&script_snippet, \"rebase_root\", opts->root ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"squash_onto\",\n-\t\topts->squash_onto ? oid_to_hex(opts->squash_onto) : \"\");\n-\tadd_var(&script_snippet, \"git_format_patch_opt\",\n-\t\topts->git_format_patch_opt.buf);\n-\n-\tif (is_merge(opts) &&\n-\t    !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n-\t\tstrbuf_addstr(&script_snippet,\n-\t\t\t      \"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; \");\n-\t\topts->autosquash = 0;\n-\t}\n-\n-\tswitch (opts->type) {\n-\tcase REBASE_PRESERVE_MERGES:\n-\t\tbackend = \"git-rebase--preserve-merges\";\n-\t\tbackend_func = \"git_rebase__preserve_merges\";\n-\t\tbreak;\n-\tdefault:\n+\telse\n \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n-\t\tbreak;\n-\t}\n \n-\tstrbuf_addf(&script_snippet,\n-\t\t    \". git-sh-setup && . %s && %s\", backend, backend_func);\n-\targv[0] = script_snippet.buf;\n-\n-\tstatus = run_command_v_opt(argv, RUN_USING_SHELL);\n-finished_rebase:\n \tif (opts->dont_finish_rebase)\n \t\t; /* do nothing */\n \telse if (opts->type == REBASE_MERGE)\n@@ -1377,10 +1285,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\tparse_opt_interactive),\n-\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n-\t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n-\t\t\t\t \"ignoring them\"),\n-\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n \t\tOPT_CALLBACK_F(0, \"empty\", &options, \"{drop,keep,ask}\",\n \t\t\t       N_(\"how to handle commits that become empty\"),\n@@ -1448,8 +1352,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n \t\tif (is_directory(buf.buf)) {\n-\t\t\toptions.type = REBASE_PRESERVE_MERGES;\n-\t\t\toptions.flags |= REBASE_INTERACTIVE_EXPLICIT;\n+\t\t\tdie(\"`rebase -p` is no longer supported\");\n \t\t} else {\n \t\t\tstrbuf_reset(&buf);\n \t\t\tstrbuf_addf(&buf, \"%s/interactive\", merge_dir());\n@@ -1479,10 +1382,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \n-\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\twarning(_(\"git rebase --preserve-merges is deprecated. \"\n-\t\t\t  \"Use --rebase-merges instead.\"));\n-\n \tif (keep_base) {\n \t\tif (options.onto_name)\n \t\t\tdie(_(\"cannot combine '--keep-base' with '--onto'\"));\n@@ -1728,7 +1627,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tcase REBASE_APPLY:\n \t\t\tdie(_(\"--strategy requires --merge or --interactive\"));\n \t\tcase REBASE_MERGE:\n-\t\tcase REBASE_PRESERVE_MERGES:\n \t\t\t/* compatible */\n \t\t\tbreak;\n \t\tcase REBASE_UNSPECIFIED:\n@@ -1780,7 +1678,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \n \tswitch (options.type) {\n \tcase REBASE_MERGE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\toptions.state_dir = merge_dir();\n \t\tbreak;\n \tcase REBASE_APPLY:\n@@ -1805,28 +1702,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\toptions.reschedule_failed_exec = reschedule_failed_exec;\n \n \tif (options.signoff) {\n-\t\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\t\tdie(\"cannot combine '--signoff' with \"\n-\t\t\t    \"'--preserve-merges'\");\n \t\tstrvec_push(&options.git_am_opts, \"--signoff\");\n \t\toptions.flags |= REBASE_FORCE;\n \t}\n \n-\tif (options.type == REBASE_PRESERVE_MERGES) {\n-\t\t/*\n-\t\t * Note: incompatibility with --signoff handled in signoff block above\n-\t\t * Note: incompatibility with --interactive is just a strong warning;\n-\t\t *       git-rebase.txt caveats with \"unless you know what you are doing\"\n-\t\t */\n-\t\tif (options.rebase_merges)\n-\t\t\tdie(_(\"cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--rebase-merges'\"));\n-\n-\t\tif (options.reschedule_failed_exec)\n-\t\t\tdie(_(\"error: cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--reschedule-failed-exec'\"));\n-\t}\n-\n \tif (!options.root) {\n \t\tif (argc < 1) {\n \t\t\tstruct branch *branch;\ndiff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh\ndeleted file mode 100644\nindex b9c71d2a71b..00000000000\n--- a/git-rebase--preserve-merges.sh\n+++ /dev/null\n@@ -1,1057 +0,0 @@\n-# This shell script fragment is sourced by git-rebase to implement its\n-# preserve-merges mode.\n-#\n-# Copyright (c) 2006 Johannes E. Schindelin\n-#\n-# The file containing rebase commands, comments, and empty lines.\n-# This file is created by \"git rebase -i\" then edited by the user.  As\n-# the lines are processed, they are removed from the front of this\n-# file and written to the tail of $done.\n-todo=\"$state_dir\"/git-rebase-todo\n-\n-# The rebase command lines that have already been processed.  A line\n-# is moved here when it is first handled, before any associated user\n-# actions.\n-done=\"$state_dir\"/done\n-\n-# The commit message that is planned to be used for any changes that\n-# need to be committed following a user interaction.\n-msg=\"$state_dir\"/message\n-\n-# The file into which is accumulated the suggested commit message for\n-# squash/fixup commands.  When the first of a series of squash/fixups\n-# is seen, the file is created and the commit message from the\n-# previous commit and from the first squash/fixup commit are written\n-# to it.  The commit message for each subsequent squash/fixup commit\n-# is appended to the file as it is processed.\n-#\n-# The first line of the file is of the form\n-#     # This is a combination of $count commits.\n-# where $count is the number of commits whose messages have been\n-# written to the file so far (including the initial \"pick\" commit).\n-# Each time that a commit message is processed, this line is read and\n-# updated.  It is deleted just before the combined commit is made.\n-squash_msg=\"$state_dir\"/message-squash\n-\n-# If the current series of squash/fixups has not yet included a squash\n-# command, then this file exists and holds the commit message of the\n-# original \"pick\" commit.  (If the series ends without a \"squash\"\n-# command, then this can be used as the commit message of the combined\n-# commit without opening the editor.)\n-fixup_msg=\"$state_dir\"/message-fixup\n-\n-# $rewritten is the name of a directory containing files for each\n-# commit that is reachable by at least one merge base of $head and\n-# $upstream. They are not necessarily rewritten, but their children\n-# might be.  This ensures that commits on merged, but otherwise\n-# unrelated side branches are left alone. (Think \"X\" in the man page's\n-# example.)\n-rewritten=\"$state_dir\"/rewritten\n-\n-dropped=\"$state_dir\"/dropped\n-\n-end=\"$state_dir\"/end\n-msgnum=\"$state_dir\"/msgnum\n-\n-# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE that will be used for the commit that is currently\n-# being rebased.\n-author_script=\"$state_dir\"/author-script\n-\n-# When an \"edit\" rebase command is being processed, the SHA1 of the\n-# commit to be edited is recorded in this file.  When \"git rebase\n-# --continue\" is executed, if there are any staged changes then they\n-# will be amended to the HEAD commit, but only provided the HEAD\n-# commit is still the commit to be edited.  When any other rebase\n-# command is processed, this file is deleted.\n-amend=\"$state_dir\"/amend\n-\n-# For the post-rewrite hook, we make a list of rewritten commits and\n-# their new sha1s.  The rewritten-pending list keeps the sha1s of\n-# commits that have been processed, but not committed yet,\n-# e.g. because they are waiting for a 'squash' command.\n-rewritten_list=\"$state_dir\"/rewritten-list\n-rewritten_pending=\"$state_dir\"/rewritten-pending\n-\n-# Work around Git for Windows' Bash whose \"read\" does not strip CRLF\n-# and leaves CR at the end instead.\n-cr=$(printf \"\\015\")\n-\n-resolvemsg=\"\n-$(gettext 'Resolve all conflicts manually, mark them as resolved with\n-\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n-You can instead skip this commit: run \"git rebase --skip\".\n-To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".')\n-\"\n-\n-write_basic_state () {\n-\techo \"$head_name\" > \"$state_dir\"/head-name &&\n-\techo \"$onto\" > \"$state_dir\"/onto &&\n-\techo \"$orig_head\" > \"$state_dir\"/orig-head &&\n-\ttest t = \"$GIT_QUIET\" && : > \"$state_dir\"/quiet\n-\ttest t = \"$verbose\" && : > \"$state_dir\"/verbose\n-\ttest -n \"$strategy\" && echo \"$strategy\" > \"$state_dir\"/strategy\n-\ttest -n \"$strategy_opts\" && echo \"$strategy_opts\" > \\\n-\t\t\"$state_dir\"/strategy_opts\n-\ttest -n \"$allow_rerere_autoupdate\" && echo \"$allow_rerere_autoupdate\" > \\\n-\t\t\"$state_dir\"/allow_rerere_autoupdate\n-\ttest -n \"$gpg_sign_opt\" && echo \"$gpg_sign_opt\" > \"$state_dir\"/gpg_sign_opt\n-\ttest -n \"$signoff\" && echo \"$signoff\" >\"$state_dir\"/signoff\n-\ttest -n \"$reschedule_failed_exec\" && : > \"$state_dir\"/reschedule-failed-exec\n-}\n-\n-apply_autostash () {\n-\tif test -f \"$state_dir/autostash\"\n-\tthen\n-\t\tstash_sha1=$(cat \"$state_dir/autostash\")\n-\t\tif git stash apply $stash_sha1 >/dev/null 2>&1\n-\t\tthen\n-\t\t\techo \"$(gettext 'Applied autostash.')\" >&2\n-\t\telse\n-\t\t\tgit stash store -m \"autostash\" -q $stash_sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot store \\$stash_sha1\")\"\n-\t\t\tgettext 'Applying autostash resulted in conflicts.\n-Your changes are safe in the stash.\n-You can run \"git stash pop\" or \"git stash drop\" at any time.\n-' >&2\n-\t\tfi\n-\tfi\n-}\n-\n-output () {\n-\tcase \"$verbose\" in\n-\t'')\n-\t\toutput=$(\"$@\" 2>&1 )\n-\t\tstatus=$?\n-\t\ttest $status != 0 && printf \"%s\\n\" \"$output\"\n-\t\treturn $status\n-\t\t;;\n-\t*)\n-\t\t\"$@\"\n-\t\t;;\n-\tesac\n-}\n-\n-strategy_args=${strategy:+--strategy=$strategy}\n-test -n \"$strategy_opts\" &&\n-eval '\n-\tfor strategy_opt in '\"$strategy_opts\"'\n-\tdo\n-\t\tstrategy_args=\"$strategy_args -X$(git rev-parse --sq-quote \"${strategy_opt#--}\")\"\n-\tdone\n-'\n-\n-GIT_CHERRY_PICK_HELP=\"$resolvemsg\"\n-export GIT_CHERRY_PICK_HELP\n-\n-comment_char=$(git config --get core.commentchar 2>/dev/null)\n-case \"$comment_char\" in\n-'' | auto)\n-\tcomment_char=\"#\"\n-\t;;\n-?)\n-\t;;\n-*)\n-\tcomment_char=$(echo \"$comment_char\" | cut -c1)\n-\t;;\n-esac\n-\n-warn () {\n-\tprintf '%s\\n' \"$*\" >&2\n-}\n-\n-# Output the commit message for the specified commit.\n-commit_message () {\n-\tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n-}\n-\n-orig_reflog_action=\"$GIT_REFLOG_ACTION\"\n-\n-comment_for_reflog () {\n-\tcase \"$orig_reflog_action\" in\n-\t''|rebase*)\n-\t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n-\t\texport GIT_REFLOG_ACTION\n-\t\t;;\n-\tesac\n-}\n-\n-last_count=\n-mark_action_done () {\n-\tsed -e 1q < \"$todo\" >> \"$done\"\n-\tsed -e 1d < \"$todo\" >> \"$todo\".new\n-\tmv -f \"$todo\".new \"$todo\"\n-\tnew_count=$(( $(git stripspace --strip-comments <\"$done\" | wc -l) ))\n-\techo $new_count >\"$msgnum\"\n-\ttotal=$(($new_count + $(git stripspace --strip-comments <\"$todo\" | wc -l)))\n-\techo $total >\"$end\"\n-\tif test \"$last_count\" != \"$new_count\"\n-\tthen\n-\t\tlast_count=$new_count\n-\t\teval_gettext \"Rebasing (\\$new_count/\\$total)\"; printf \"\\r\"\n-\t\ttest -z \"$verbose\" || echo\n-\tfi\n-}\n-\n-append_todo_help () {\n-\tgettext \"\n-Commands:\n-p, pick <commit> = use commit\n-r, reword <commit> = use commit, but edit the commit message\n-e, edit <commit> = use commit, but stop for amending\n-s, squash <commit> = use commit, but meld into previous commit\n-f, fixup <commit> = like \\\"squash\\\", but discard this commit's log message\n-x, exec <commit> = run command (the rest of the line) using shell\n-d, drop <commit> = remove commit\n-l, label <label> = label current HEAD with a name\n-t, reset <label> = reset HEAD to a label\n-m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n-.       create a merge commit using the original merge commit's\n-.       message (or the oneline, if no original merge commit was\n-.       specified). Use -c <commit> to reword the commit message.\n-\n-These lines can be re-ordered; they are executed from top to bottom.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test $(get_missing_commit_check_level) = error\n-\tthen\n-\t\tgettext \"\n-Do not remove any line. Use 'drop' explicitly to remove a commit.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\telse\n-\t\tgettext \"\n-If you remove a line here THAT COMMIT WILL BE LOST.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\tfi\n-}\n-\n-make_patch () {\n-\tsha1_and_parents=\"$(git rev-list --parents -1 \"$1\")\"\n-\tcase \"$sha1_and_parents\" in\n-\t?*' '?*' '?*)\n-\t\tgit diff --cc $sha1_and_parents\n-\t\t;;\n-\t?*' '?*)\n-\t\tgit diff-tree -p \"$1^!\"\n-\t\t;;\n-\t*)\n-\t\techo \"Root commit\"\n-\t\t;;\n-\tesac > \"$state_dir\"/patch\n-\ttest -f \"$msg\" ||\n-\t\tcommit_message \"$1\" > \"$msg\"\n-\ttest -f \"$author_script\" ||\n-\t\tget_author_ident_from_commit \"$1\" > \"$author_script\"\n-}\n-\n-die_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch \"$1\"\n-\tdie \"$2\"\n-}\n-\n-exit_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch $1\n-\tgit rev-parse --verify HEAD > \"$amend\"\n-\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\twarn \"$(eval_gettext \"\\\n-You can amend the commit now, with\n-\n-\tgit commit --amend \\$gpg_sign_opt_quoted\n-\n-Once you are satisfied with your changes, run\n-\n-\tgit rebase --continue\")\"\n-\twarn\n-\texit $2\n-}\n-\n-die_abort () {\n-\tapply_autostash\n-\trm -rf \"$state_dir\"\n-\tdie \"$1\"\n-}\n-\n-has_action () {\n-\ttest -n \"$(git stripspace --strip-comments <\"$1\")\"\n-}\n-\n-is_empty_commit() {\n-\ttree=$(git rev-parse -q --verify \"$1\"^{tree} 2>/dev/null) || {\n-\t\tsha1=$1\n-\t\tdie \"$(eval_gettext \"\\$sha1: not a commit that can be picked\")\"\n-\t}\n-\tptree=$(git rev-parse -q --verify \"$1\"^^{tree} 2>/dev/null) ||\n-\t\tptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904\n-\ttest \"$tree\" = \"$ptree\"\n-}\n-\n-is_merge_commit()\n-{\n-\tgit rev-parse --verify --quiet \"$1\"^2 >/dev/null 2>&1\n-}\n-\n-# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE exported from the current environment.\n-do_with_author () {\n-\t(\n-\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE\n-\t\t\"$@\"\n-\t)\n-}\n-\n-git_sequence_editor () {\n-\tif test -z \"$GIT_SEQUENCE_EDITOR\"\n-\tthen\n-\t\tGIT_SEQUENCE_EDITOR=\"$(git config sequence.editor)\"\n-\t\tif [ -z \"$GIT_SEQUENCE_EDITOR\" ]\n-\t\tthen\n-\t\t\tGIT_SEQUENCE_EDITOR=\"$(git var GIT_EDITOR)\" || return $?\n-\t\tfi\n-\tfi\n-\n-\teval \"$GIT_SEQUENCE_EDITOR\" '\"$@\"'\n-}\n-\n-pick_one () {\n-\tff=--ff\n-\n-\tcase \"$1\" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac\n-\tcase \"$force_rebase\" in '') ;; ?*) ff= ;; esac\n-\toutput git rev-parse --verify $sha1 || die \"$(eval_gettext \"Invalid commit name: \\$sha1\")\"\n-\n-\tif is_empty_commit \"$sha1\"\n-\tthen\n-\t\tempty_args=\"--allow-empty\"\n-\tfi\n-\n-\tpick_one_preserving_merges \"$@\"\n-}\n-\n-pick_one_preserving_merges () {\n-\tfast_forward=t\n-\tcase \"$1\" in\n-\t-n)\n-\t\tfast_forward=f\n-\t\tsha1=$2\n-\t\t;;\n-\t*)\n-\t\tsha1=$1\n-\t\t;;\n-\tesac\n-\tsha1=$(git rev-parse $sha1)\n-\n-\tif test -f \"$state_dir\"/current-commit && test \"$fast_forward\" = t\n-\tthen\n-\t\twhile read current_commit\n-\t\tdo\n-\t\t\tgit rev-parse HEAD > \"$rewritten\"/$current_commit\n-\t\tdone <\"$state_dir\"/current-commit\n-\t\trm \"$state_dir\"/current-commit ||\n-\t\t\tdie \"$(gettext \"Cannot write current commit's replacement sha1\")\"\n-\tfi\n-\n-\techo $sha1 >> \"$state_dir\"/current-commit\n-\n-\t# rewrite parents; if none were rewritten, we can fast-forward.\n-\tnew_parents=\n-\tpend=\" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\"\n-\tif test \"$pend\" = \" \"\n-\tthen\n-\t\tpend=\" root\"\n-\tfi\n-\twhile [ \"$pend\" != \"\" ]\n-\tdo\n-\t\tp=$(expr \"$pend\" : ' \\([^ ]*\\)')\n-\t\tpend=\"${pend# $p}\"\n-\n-\t\tif test -f \"$rewritten\"/$p\n-\t\tthen\n-\t\t\tnew_p=$(cat \"$rewritten\"/$p)\n-\n-\t\t\t# If the todo reordered commits, and our parent is marked for\n-\t\t\t# rewriting, but hasn't been gotten to yet, assume the user meant to\n-\t\t\t# drop it on top of the current HEAD\n-\t\t\tif test -z \"$new_p\"\n-\t\t\tthen\n-\t\t\t\tnew_p=$(git rev-parse HEAD)\n-\t\t\tfi\n-\n-\t\t\ttest $p != $new_p && fast_forward=f\n-\t\t\tcase \"$new_parents\" in\n-\t\t\t*$new_p*)\n-\t\t\t\t;; # do nothing; that parent is already there\n-\t\t\t*)\n-\t\t\t\tnew_parents=\"$new_parents $new_p\"\n-\t\t\t\t;;\n-\t\t\tesac\n-\t\telse\n-\t\t\tif test -f \"$dropped\"/$p\n-\t\t\tthen\n-\t\t\t\tfast_forward=f\n-\t\t\t\treplacement=\"$(cat \"$dropped\"/$p)\"\n-\t\t\t\ttest -z \"$replacement\" && replacement=root\n-\t\t\t\tpend=\" $replacement$pend\"\n-\t\t\telse\n-\t\t\t\tnew_parents=\"$new_parents $p\"\n-\t\t\tfi\n-\t\tfi\n-\tdone\n-\tcase $fast_forward in\n-\tt)\n-\t\toutput warn \"$(eval_gettext \"Fast-forward to \\$sha1\")\"\n-\t\toutput git reset --hard $sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot fast-forward to \\$sha1\")\"\n-\t\t;;\n-\tf)\n-\t\tfirst_parent=$(expr \"$new_parents\" : ' \\([^ ]*\\)')\n-\n-\t\tif [ \"$1\" != \"-n\" ]\n-\t\tthen\n-\t\t\t# detach HEAD to current parent\n-\t\t\toutput git checkout $first_parent 2> /dev/null ||\n-\t\t\t\tdie \"$(eval_gettext \"Cannot move HEAD to \\$first_parent\")\"\n-\t\tfi\n-\n-\t\tcase \"$new_parents\" in\n-\t\t' '*' '*)\n-\t\t\ttest \"a$1\" = a-n && die \"$(eval_gettext \"Refusing to squash a merge: \\$sha1\")\"\n-\n-\t\t\t# redo merge\n-\t\t\tauthor_script_content=$(get_author_ident_from_commit $sha1)\n-\t\t\teval \"$author_script_content\"\n-\t\t\tmsg_content=\"$(commit_message $sha1)\"\n-\t\t\t# No point in merging the first parent, that's HEAD\n-\t\t\tnew_parents=${new_parents# $first_parent}\n-\t\t\tmerge_args=\"--no-log --no-ff\"\n-\t\t\tif ! do_with_author output eval \\\n-\t\t\t\tgit merge ${gpg_sign_opt:+$(git rev-parse \\\n-\t\t\t\t\t--sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t$allow_rerere_autoupdate \"$merge_args\" \\\n-\t\t\t\t\"$strategy_args\" \\\n-\t\t\t\t-m \"$(git rev-parse --sq-quote \"$msg_content\")\" \\\n-\t\t\t\t\"$new_parents\"\n-\t\t\tthen\n-\t\t\t\tprintf \"%s\\n\" \"$msg_content\" > \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Error redoing merge \\$sha1\")\"\n-\t\t\tfi\n-\t\t\techo \"$sha1 $(git rev-parse HEAD^0)\" >> \"$rewritten_list\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\toutput eval git cherry-pick $allow_rerere_autoupdate \\\n-\t\t\t\t$allow_empty_message \\\n-\t\t\t\t${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t\"$strategy_args\" \"$@\" ||\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not pick \\$sha1\")\"\n-\t\t\t;;\n-\t\tesac\n-\t\t;;\n-\tesac\n-}\n-\n-this_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"This is the commit message #\\${n}:\"\n-}\n-\n-skip_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"The commit message #\\${n} will be skipped:\"\n-}\n-\n-update_squash_messages () {\n-\tif test -f \"$squash_msg\"; then\n-\t\tmv \"$squash_msg\" \"$squash_msg\".bak || exit\n-\t\tcount=$(($(sed -n \\\n-\t\t\t-e \"1s/^$comment_char[^0-9]*\\([0-9][0-9]*\\).*/\\1/p\" \\\n-\t\t\t-e \"q\" < \"$squash_msg\".bak)+1))\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(eval_ngettext \\\n-\t\t\t\t\"This is a combination of \\$count commit.\" \\\n-\t\t\t\t\"This is a combination of \\$count commits.\" \\\n-\t\t\t\t$count)\"\n-\t\t\tsed -e 1d -e '2,/^./{\n-\t\t\t\t/^$/d\n-\t\t\t}' <\"$squash_msg\".bak\n-\t\t} >\"$squash_msg\"\n-\telse\n-\t\tcommit_message HEAD >\"$fixup_msg\" ||\n-\t\tdie \"$(eval_gettext \"Cannot write \\$fixup_msg\")\"\n-\t\tcount=2\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is a combination of 2 commits.\")\"\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is the 1st commit message:\")\"\n-\t\t\techo\n-\t\t\tcat \"$fixup_msg\"\n-\t\t} >\"$squash_msg\"\n-\tfi\n-\tcase $1 in\n-\tsquash)\n-\t\trm -f \"$fixup_msg\"\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(this_nth_commit_message $count)\"\n-\t\techo\n-\t\tcommit_message $2\n-\t\t;;\n-\tfixup)\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(skip_nth_commit_message $count)\"\n-\t\techo\n-\t\t# Change the space after the comment character to TAB:\n-\t\tcommit_message $2 | git stripspace --comment-lines | sed -e 's/ /\t/'\n-\t\t;;\n-\tesac >>\"$squash_msg\"\n-}\n-\n-peek_next_command () {\n-\tgit stripspace --strip-comments <\"$todo\" | sed -n -e 's/ .*//p' -e q\n-}\n-\n-# A squash/fixup has failed.  Prepare the long version of the squash\n-# commit message, then die_with_patch.  This code path requires the\n-# user to edit the combined commit message for all commits that have\n-# been squashed/fixedup so far.  So also erase the old squash\n-# messages, effectively causing the combined commit to be used as the\n-# new basis for any further squash/fixups.  Args: sha1 rest\n-die_failed_squash() {\n-\tsha1=$1\n-\trest=$2\n-\tmv \"$squash_msg\" \"$msg\" || exit\n-\trm -f \"$fixup_msg\"\n-\tcp \"$msg\" \"$GIT_DIR\"/MERGE_MSG || exit\n-\twarn\n-\twarn \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tdie_with_patch $sha1 \"\"\n-}\n-\n-flush_rewritten_pending() {\n-\ttest -s \"$rewritten_pending\" || return\n-\tnewsha1=\"$(git rev-parse HEAD^0)\"\n-\tsed \"s/$/ $newsha1/\" < \"$rewritten_pending\" >> \"$rewritten_list\"\n-\trm -f \"$rewritten_pending\"\n-}\n-\n-record_in_rewritten() {\n-\toldsha1=\"$(git rev-parse $1)\"\n-\techo \"$oldsha1\" >> \"$rewritten_pending\"\n-\n-\tcase \"$(peek_next_command)\" in\n-\tsquash|s|fixup|f)\n-\t\t;;\n-\t*)\n-\t\tflush_rewritten_pending\n-\t\t;;\n-\tesac\n-}\n-\n-do_pick () {\n-\tsha1=$1\n-\trest=$2\n-\tif test \"$(git rev-parse HEAD)\" = \"$squash_onto\"\n-\tthen\n-\t\t# Set the correct commit message and author info on the\n-\t\t# sentinel root before cherry-picking the original changes\n-\t\t# without committing (-n).  Finally, update the sentinel again\n-\t\t# to include these changes.  If the cherry-pick results in a\n-\t\t# conflict, this means our behaviour is similar to a standard\n-\t\t# failed cherry-pick during rebase, with a dirty index to\n-\t\t# resolve before manually running git commit --amend then git\n-\t\t# rebase --continue.\n-\t\tgit commit --allow-empty --allow-empty-message --amend \\\n-\t\t\t   --no-post-rewrite -n -q -C $sha1 $signoff &&\n-\t\t\tpick_one -n $sha1 &&\n-\t\t\tgit commit --allow-empty --allow-empty-message \\\n-\t\t\t\t   --amend --no-post-rewrite -n -q -C $sha1 $signoff \\\n-\t\t\t\t   ${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n-\t\t\t\t   die_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\telse\n-\t\tpick_one $sha1 ||\n-\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tfi\n-}\n-\n-do_next () {\n-\trm -f \"$msg\" \"$author_script\" \"$amend\" \"$state_dir\"/stopped-sha || exit\n-\tread -r command sha1 rest < \"$todo\"\n-\tcase \"$command\" in\n-\t\"$comment_char\"*|''|noop|drop|d)\n-\t\tmark_action_done\n-\t\t;;\n-\t\"$cr\")\n-\t\t# Work around CR left by \"read\" (e.g. with Git for Windows' Bash).\n-\t\tmark_action_done\n-\t\t;;\n-\tpick|p)\n-\t\tcomment_for_reflog pick\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\treword|r)\n-\t\tcomment_for_reflog reword\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tgit commit --amend --no-post-rewrite ${gpg_sign_opt:+\"$gpg_sign_opt\"} \\\n-\t\t\t$allow_empty_message || {\n-\t\t\twarn \"$(eval_gettext \"\\\n-Could not amend commit after successfully picking \\$sha1... \\$rest\n-This is most likely due to an empty commit message, or the pre-commit hook\n-failed. If the pre-commit hook failed, you may need to resolve the issue before\n-you are able to reword the commit.\")\"\n-\t\t\texit_with_patch $sha1 1\n-\t\t}\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tedit|e)\n-\t\tcomment_for_reflog edit\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tsha1_abbrev=$(git rev-parse --short $sha1)\n-\t\twarn \"$(eval_gettext \"Stopped at \\$sha1_abbrev... \\$rest\")\"\n-\t\texit_with_patch $sha1 0\n-\t\t;;\n-\tsquash|s|fixup|f)\n-\t\tcase \"$command\" in\n-\t\tsquash|s)\n-\t\t\tsquash_style=squash\n-\t\t\t;;\n-\t\tfixup|f)\n-\t\t\tsquash_style=fixup\n-\t\t\t;;\n-\t\tesac\n-\t\tcomment_for_reflog $squash_style\n-\n-\t\ttest -f \"$done\" && has_action \"$done\" ||\n-\t\t\tdie \"$(eval_gettext \"Cannot '\\$squash_style' without a previous commit\")\"\n-\n-\t\tmark_action_done\n-\t\tupdate_squash_messages $squash_style $sha1\n-\t\tauthor_script_content=$(get_author_ident_from_commit HEAD)\n-\t\techo \"$author_script_content\" > \"$author_script\"\n-\t\teval \"$author_script_content\"\n-\t\tif ! pick_one -n $sha1\n-\t\tthen\n-\t\t\tgit rev-parse --verify HEAD >\"$amend\"\n-\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\tfi\n-\t\tcase \"$(peek_next_command)\" in\n-\t\tsquash|s|fixup|f)\n-\t\t\t# This is an intermediate commit; its message will only be\n-\t\t\t# used in case of trouble.  So use the long version:\n-\t\t\tdo_with_author output git commit --amend --no-verify -F \"$squash_msg\" \\\n-\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t# This is the final command of this squash/fixup group\n-\t\t\tif test -f \"$fixup_msg\"\n-\t\t\tthen\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$fixup_msg\" \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\telse\n-\t\t\t\tcp \"$squash_msg\" \"$GIT_DIR\"/SQUASH_MSG || exit\n-\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$GIT_DIR\"/SQUASH_MSG -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\tfi\n-\t\t\trm -f \"$squash_msg\" \"$fixup_msg\"\n-\t\t\t;;\n-\t\tesac\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tx|\"exec\")\n-\t\tread -r command rest < \"$todo\"\n-\t\tmark_action_done\n-\t\teval_gettextln \"Executing: \\$rest\"\n-\t\t\"${SHELL:-@SHELL_PATH@}\" -c \"$rest\" # Actual execution\n-\t\tstatus=$?\n-\t\t# Run in subshell because require_clean_work_tree can die.\n-\t\tdirty=f\n-\t\t(require_clean_work_tree \"rebase\" 2>/dev/null) || dirty=t\n-\t\tif test \"$status\" -ne 0\n-\t\tthen\n-\t\t\twarn \"$(eval_gettext \"Execution failed: \\$rest\")\"\n-\t\t\ttest \"$dirty\" = f ||\n-\t\t\t\twarn \"$(gettext \"and made changes to the index and/or the working tree\")\"\n-\n-\t\t\twarn \"$(gettext \"\\\n-You can fix the problem, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\tif test $status -eq 127\t\t# command not found\n-\t\t\tthen\n-\t\t\t\tstatus=1\n-\t\t\tfi\n-\t\t\texit \"$status\"\n-\t\telif test \"$dirty\" = t\n-\t\tthen\n-\t\t\t# TRANSLATORS: after these lines is a command to be issued by the user\n-\t\t\twarn \"$(eval_gettext \"\\\n-Execution succeeded: \\$rest\n-but left changes to the index and/or the working tree\n-Commit or stash your changes, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\texit 1\n-\t\tfi\n-\t\t;;\n-\t*)\n-\t\twarn \"$(eval_gettext \"Unknown command: \\$command \\$sha1 \\$rest\")\"\n-\t\tfixtodo=\"$(gettext \"Please fix this using 'git rebase --edit-todo'.\")\"\n-\t\tif git rev-parse --verify -q \"$sha1\" >/dev/null\n-\t\tthen\n-\t\t\tdie_with_patch $sha1 \"$fixtodo\"\n-\t\telse\n-\t\t\tdie \"$fixtodo\"\n-\t\tfi\n-\t\t;;\n-\tesac\n-\ttest -s \"$todo\" && return\n-\n-\tcomment_for_reflog finish &&\n-\tnewhead=$(git rev-parse HEAD) &&\n-\tcase $head_name in\n-\trefs/*)\n-\t\tmessage=\"$GIT_REFLOG_ACTION: $head_name onto $onto\" &&\n-\t\tgit update-ref -m \"$message\" $head_name $newhead $orig_head &&\n-\t\tgit symbolic-ref \\\n-\t\t  -m \"$GIT_REFLOG_ACTION: returning to $head_name\" \\\n-\t\t  HEAD $head_name\n-\t\t;;\n-\tesac && {\n-\t\ttest ! -f \"$state_dir\"/verbose ||\n-\t\t\tgit diff-tree --stat $orig_head..HEAD\n-\t} &&\n-\t{\n-\t\ttest -s \"$rewritten_list\" &&\n-\t\tgit notes copy --for-rewrite=rebase < \"$rewritten_list\" ||\n-\t\ttrue # we don't care if this copying failed\n-\t} &&\n-\thook=\"$(git rev-parse --git-path hooks/post-rewrite)\"\n-\tif test -x \"$hook\" && test -s \"$rewritten_list\"; then\n-\t\t\"$hook\" rebase < \"$rewritten_list\"\n-\t\ttrue # we don't care if this hook failed\n-\tfi &&\n-\t\twarn \"$(eval_gettext \"Successfully rebased and updated \\$head_name.\")\"\n-\n-\treturn 1 # not failure; just to break the do_rest loop\n-}\n-\n-# can only return 0, when the infinite loop breaks\n-do_rest () {\n-\twhile :\n-\tdo\n-\t\tdo_next || break\n-\tdone\n-}\n-\n-expand_todo_ids() {\n-\tgit rebase--interactive --expand-ids\n-}\n-\n-collapse_todo_ids() {\n-\tgit rebase--interactive --shorten-ids\n-}\n-\n-# Switch to the branch in $into and notify it in the reflog\n-checkout_onto () {\n-\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $onto_name\"\n-\toutput git checkout $onto || die_abort \"$(gettext \"could not detach HEAD\")\"\n-\tgit update-ref ORIG_HEAD $orig_head\n-}\n-\n-get_missing_commit_check_level () {\n-\tcheck_level=$(git config --get rebase.missingCommitsCheck)\n-\tcheck_level=${check_level:-ignore}\n-\t# Don't be case sensitive\n-\tprintf '%s' \"$check_level\" | tr 'A-Z' 'a-z'\n-}\n-\n-# Initiate an action. If the cannot be any\n-# further action it  may exec a command\n-# or exit and not return.\n-#\n-# TODO: Consider a cleaner return model so it\n-# never exits and always return 0 if process\n-# is complete.\n-#\n-# Parameter 1 is the action to initiate.\n-#\n-# Returns 0 if the action was able to complete\n-# and if 1 if further processing is required.\n-initiate_action () {\n-\tcase \"$1\" in\n-\tcontinue)\n-\t\t# do we have anything to commit?\n-\t\tif git diff-index --cached --quiet HEAD --\n-\t\tthen\n-\t\t\t# Nothing to commit -- skip this commit\n-\n-\t\t\ttest ! -f \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\trm \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\tdie \"$(gettext \"Could not remove CHERRY_PICK_HEAD\")\"\n-\t\telse\n-\t\t\tif ! test -f \"$author_script\"\n-\t\t\tthen\n-\t\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\t\t\t\tdie \"$(eval_gettext \"\\\n-You have staged changes in your working tree.\n-If these changes are meant to be\n-squashed into the previous commit, run:\n-\n-  git commit --amend \\$gpg_sign_opt_quoted\n-\n-If they are meant to go into a new commit, run:\n-\n-  git commit \\$gpg_sign_opt_quoted\n-\n-In both cases, once you're done, continue with:\n-\n-  git rebase --continue\n-\")\"\n-\t\t\tfi\n-\t\t\t. \"$author_script\" ||\n-\t\t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n-\t\t\tif test -f \"$amend\"\n-\t\t\tthen\n-\t\t\t\tcurrent_head=$(git rev-parse --verify HEAD)\n-\t\t\t\ttest \"$current_head\" = $(cat \"$amend\") ||\n-\t\t\t\tdie \"$(gettext \"\\\n-You have uncommitted changes in your working tree. Please commit them\n-first and then run 'git rebase --continue' again.\")\"\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\telse\n-\t\t\t\tdo_with_author git commit --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\tfi\n-\t\tfi\n-\n-\t\tif test -r \"$state_dir\"/stopped-sha\n-\t\tthen\n-\t\t\trecord_in_rewritten \"$(cat \"$state_dir\"/stopped-sha)\"\n-\t\tfi\n-\n-\t\trequire_clean_work_tree \"rebase\"\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tskip)\n-\t\tgit rerere clear\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tedit-todo)\n-\t\tgit stripspace --strip-comments <\"$todo\" >\"$todo\".new\n-\t\tmv -f \"$todo\".new \"$todo\"\n-\t\tcollapse_todo_ids\n-\t\tappend_todo_help\n-\t\tgettext \"\n-You are editing the todo file of an ongoing interactive rebase.\n-To continue rebase after editing, run:\n-    git rebase --continue\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\t\tgit_sequence_editor \"$todo\" ||\n-\t\t\tdie \"$(gettext \"Could not execute editor\")\"\n-\t\texpand_todo_ids\n-\n-\t\texit\n-\t\t;;\n-\tshow-current-patch)\n-\t\texec git show REBASE_HEAD --\n-\t\t;;\n-\t*)\n-\t\treturn 1 # continue\n-\t\t;;\n-\tesac\n-}\n-\n-setup_reflog_action () {\n-\tcomment_for_reflog start\n-\n-\tif test ! -z \"$switch_to\"\n-\tthen\n-\t\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $switch_to\"\n-\t\toutput git checkout \"$switch_to\" -- ||\n-\t\t\tdie \"$(eval_gettext \"Could not checkout \\$switch_to\")\"\n-\n-\t\tcomment_for_reflog start\n-\tfi\n-}\n-\n-init_basic_state () {\n-\torig_head=$(git rev-parse --verify HEAD) || die \"$(gettext \"No HEAD?\")\"\n-\tmkdir -p \"$state_dir\" || die \"$(eval_gettext \"Could not create temporary \\$state_dir\")\"\n-\trm -f \"$(git rev-parse --git-path REBASE_HEAD)\"\n-\n-\t: > \"$state_dir\"/interactive || die \"$(gettext \"Could not mark as interactive\")\"\n-\twrite_basic_state\n-}\n-\n-init_revisions_and_shortrevisions () {\n-\tshorthead=$(git rev-parse --short $orig_head)\n-\tshortonto=$(git rev-parse --short $onto)\n-\tif test -z \"$rebase_root\"\n-\t\t# this is now equivalent to ! -z \"$upstream\"\n-\tthen\n-\t\tshortupstream=$(git rev-parse --short $upstream)\n-\t\trevisions=$upstream...$orig_head\n-\t\tshortrevisions=$shortupstream..$shorthead\n-\telse\n-\t\trevisions=$onto...$orig_head\n-\t\tshortrevisions=$shorthead\n-\t\ttest -z \"$squash_onto\" ||\n-\t\techo \"$squash_onto\" >\"$state_dir\"/squash-onto\n-\tfi\n-}\n-\n-complete_action() {\n-\ttest -s \"$todo\" || echo noop >> \"$todo\"\n-\ttest -z \"$autosquash\" || git rebase--interactive --rearrange-squash || exit\n-\ttest -n \"$cmd\" && git rebase--interactive --add-exec-commands --cmd \"$cmd\"\n-\n-\ttodocount=$(git stripspace --strip-comments <\"$todo\" | wc -l)\n-\ttodocount=${todocount##* }\n-\n-cat >>\"$todo\" <<EOF\n-\n-$comment_char $(eval_ngettext \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount command)\" \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount commands)\" \\\n-\t\"$todocount\")\n-EOF\n-\tappend_todo_help\n-\tgettext \"\n-However, if you remove everything, the rebase will be aborted.\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test -z \"$keep_empty\"\n-\tthen\n-\t\tprintf '%s\\n' \"$comment_char $(gettext \"Note that empty commits are commented out\")\" >>\"$todo\"\n-\tfi\n-\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tcp \"$todo\" \"$todo\".backup\n-\tcollapse_todo_ids\n-\tgit_sequence_editor \"$todo\" ||\n-\t\tdie_abort \"$(gettext \"Could not execute editor\")\"\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tgit rebase--interactive --check-todo-list || {\n-\t\tret=$?\n-\t\tcheckout_onto\n-\t\texit $ret\n-\t}\n-\n-\texpand_todo_ids\n-\tcheckout_onto\n-\tdo_rest\n-}\n-\n-git_rebase__preserve_merges () {\n-\tinitiate_action \"$action\"\n-\tret=$?\n-\tif test $ret = 0; then\n-\t\treturn 0\n-\tfi\n-\n-\tsetup_reflog_action\n-\tinit_basic_state\n-\n-\tif test -z \"$rebase_root\"\n-\tthen\n-\t\tmkdir \"$rewritten\" &&\n-\t\tfor c in $(git merge-base --all $orig_head $upstream)\n-\t\tdo\n-\t\t\techo $onto > \"$rewritten\"/$c ||\n-\t\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\t\tdone\n-\telse\n-\t\tmkdir \"$rewritten\" &&\n-\t\techo $onto > \"$rewritten\"/root ||\n-\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\tfi\n-\n-\tinit_revisions_and_shortrevisions\n-\n-\tformat=$(git config --get rebase.instructionFormat)\n-\t# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse\n-\tgit rev-list --format=\"%m%H ${format:-%s}\" \\\n-\t\t--reverse --left-right --topo-order \\\n-\t\t$revisions ${restrict_revision+^$restrict_revision} | \\\n-\t\tsed -n \"s/^>//p\" |\n-\twhile read -r sha1 rest\n-\tdo\n-\t\tif test -z \"$keep_empty\" && is_empty_commit $sha1 && ! is_merge_commit $sha1\n-\t\tthen\n-\t\t\tcomment_out=\"$comment_char \"\n-\t\telse\n-\t\t\tcomment_out=\n-\t\tfi\n-\n-\t\tif test -z \"$rebase_root\"\n-\t\tthen\n-\t\t\tpreserve=t\n-\t\t\tfor p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\n-\t\t\tdo\n-\t\t\t\tif test -f \"$rewritten\"/$p\n-\t\t\t\tthen\n-\t\t\t\t\tpreserve=f\n-\t\t\t\tfi\n-\t\t\tdone\n-\t\telse\n-\t\t\tpreserve=f\n-\t\tfi\n-\t\tif test f = \"$preserve\"\n-\t\tthen\n-\t\t\ttouch \"$rewritten\"/$sha1\n-\t\t\tprintf '%s\\n' \"${comment_out}pick $sha1 $rest\" >>\"$todo\"\n-\t\tfi\n-\tdone\n-\n-\t# Watch for commits that been dropped by --cherry-pick\n-\tmkdir \"$dropped\"\n-\t# Save all non-cherry-picked changes\n-\tgit rev-list $revisions --left-right --cherry-pick | \\\n-\t\tsed -n \"s/^>//p\" > \"$state_dir\"/not-cherry-picks\n-\t# Now all commits and note which ones are missing in\n-\t# not-cherry-picks and hence being dropped\n-\tgit rev-list $revisions |\n-\twhile read rev\n-\tdo\n-\t\tif test -f \"$rewritten\"/$rev &&\n-\t\t   ! sane_grep \"$rev\" \"$state_dir\"/not-cherry-picks >/dev/null\n-\t\tthen\n-\t\t\t# Use -f2 because if rev-list is telling us this commit is\n-\t\t\t# not worthwhile, we don't want to track its multiple heads,\n-\t\t\t# just the history of its first-parent for others that will\n-\t\t\t# be rebasing on top of it\n-\t\t\tgit rev-list --parents -1 $rev | cut -d' ' -s -f2 > \"$dropped\"/$rev\n-\t\t\tsha1=$(git rev-list -1 $rev)\n-\t\t\tsane_grep -v \"^[a-z][a-z]* $sha1\" <\"$todo\" > \"${todo}2\" ; mv \"${todo}2\" \"$todo\"\n-\t\t\trm \"$rewritten\"/$rev\n-\t\tfi\n-\tdone\n-\n-\tcomplete_action\n-}\n-- \ngitgitgadget\n\n"},{"id":"434422","messageId":"4492cca369cdc0c8cd39b3dafab86d798cfbaa8f.1630497435.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v2 7/7] rebase: drop the internal `rebase--interactive` command","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-01T11:57:14Z","receivedAt":"2021-09-01T11:57:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIt was only used by the `--preserve-merges` backend, which we just\nremoved.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c | 185 -----------------------------------------------\n git.c            |   1 -\n 2 files changed, 186 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 5af6aff9c5e..d707e3604e7 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -178,81 +178,6 @@ static const char *action_names[] = { \"undefined\",\n \t\t\t\t      \"edit_todo\",\n \t\t\t\t      \"show_current_patch\" };\n \n-static int add_exec_commands(struct string_list *commands)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\ttodo_list_add_exec_commands(&todo_list, commands);\n-\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int rearrange_squash_in_todo_file(void)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res = 0;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_rearrange_squash(&todo_list);\n-\tif (!res)\n-\t\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int transform_todo_file(unsigned flags)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_write_to_file(the_repository, &todo_list, todo_file,\n-\t\t\t\t      NULL, NULL, -1, flags);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -437,24 +362,6 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \n \t\tbreak;\n \t}\n-\tcase ACTION_SHORTEN_OIDS:\n-\tcase ACTION_EXPAND_OIDS:\n-\t\tret = transform_todo_file(flags);\n-\t\tbreak;\n-\tcase ACTION_CHECK_TODO_LIST:\n-\t\tret = check_todo_list_from_file(the_repository);\n-\t\tbreak;\n-\tcase ACTION_REARRANGE_SQUASH:\n-\t\tret = rearrange_squash_in_todo_file();\n-\t\tbreak;\n-\tcase ACTION_ADD_EXEC: {\n-\t\tstruct string_list commands = STRING_LIST_INIT_DUP;\n-\n-\t\tsplit_exec_commands(opts->cmd, &commands);\n-\t\tret = add_exec_commands(&commands);\n-\t\tstring_list_clear(&commands, 0);\n-\t\tbreak;\n-\t}\n \tdefault:\n \t\tBUG(\"invalid command '%d'\", command);\n \t}\n@@ -476,98 +383,6 @@ static int parse_opt_keep_empty(const struct option *opt, const char *arg,\n \treturn 0;\n }\n \n-static const char * const builtin_rebase_interactive_usage[] = {\n-\tN_(\"git rebase--interactive [<options>]\"),\n-\tNULL\n-};\n-\n-int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n-{\n-\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n-\tstruct object_id squash_onto = *null_oid();\n-\tenum action command = ACTION_NONE;\n-\tstruct option options[] = {\n-\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n-\t\t\t   REBASE_FORCE),\n-\t\tOPT_CALLBACK_F('k', \"keep-empty\", &options, NULL,\n-\t\t\tN_(\"keep commits which start empty\"),\n-\t\t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN,\n-\t\t\tparse_opt_keep_empty),\n-\t\tOPT_BOOL_F(0, \"allow-empty-message\", &opts.allow_empty_message,\n-\t\t\t   N_(\"allow commits with empty messages\"),\n-\t\t\t   PARSE_OPT_HIDDEN),\n-\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase merge commits\")),\n-\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n-\t\t\t N_(\"keep original branch points of cousins\")),\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_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-\t\tOPT_CMDMODE(0, \"continue\", &command, N_(\"continue rebase\"),\n-\t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &command, N_(\"skip commit\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &command, N_(\"edit the todo list\"),\n-\t\t\t    ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &command, N_(\"show the current patch\"),\n-\t\t\t    ACTION_SHOW_CURRENT_PATCH),\n-\t\tOPT_CMDMODE(0, \"shorten-ids\", &command,\n-\t\t\tN_(\"shorten commit ids in the todo list\"), ACTION_SHORTEN_OIDS),\n-\t\tOPT_CMDMODE(0, \"expand-ids\", &command,\n-\t\t\tN_(\"expand commit ids in the todo list\"), ACTION_EXPAND_OIDS),\n-\t\tOPT_CMDMODE(0, \"check-todo-list\", &command,\n-\t\t\tN_(\"check the todo list\"), ACTION_CHECK_TODO_LIST),\n-\t\tOPT_CMDMODE(0, \"rearrange-squash\", &command,\n-\t\t\tN_(\"rearrange fixup/squash lines\"), ACTION_REARRANGE_SQUASH),\n-\t\tOPT_CMDMODE(0, \"add-exec-commands\", &command,\n-\t\t\tN_(\"insert exec commands in todo list\"), ACTION_ADD_EXEC),\n-\t\t{ OPTION_CALLBACK, 0, \"onto\", &opts.onto, N_(\"onto\"), N_(\"onto\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"restrict-revision\", &opts.restrict_revision,\n-\t\t  N_(\"restrict-revision\"), N_(\"restrict revision\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"squash-onto\", &squash_onto, N_(\"squash-onto\"),\n-\t\t  N_(\"squash onto\"), PARSE_OPT_NONEG, parse_opt_object_id, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"upstream\", &opts.upstream, N_(\"upstream\"),\n-\t\t  N_(\"the upstream commit\"), PARSE_OPT_NONEG, parse_opt_commit,\n-\t\t  0 },\n-\t\tOPT_STRING(0, \"head-name\", &opts.head_name, N_(\"head-name\"), N_(\"head name\")),\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_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-\t\t\t   N_(\"strategy options\")),\n-\t\tOPT_STRING(0, \"switch-to\", &opts.switch_to, N_(\"switch-to\"),\n-\t\t\t   N_(\"the branch or commit to checkout\")),\n-\t\tOPT_STRING(0, \"onto-name\", &opts.onto_name, N_(\"onto-name\"), N_(\"onto name\")),\n-\t\tOPT_STRING(0, \"cmd\", &opts.cmd, N_(\"cmd\"), N_(\"the command to run\")),\n-\t\tOPT_RERERE_AUTOUPDATE(&opts.allow_rerere_autoupdate),\n-\t\tOPT_BOOL(0, \"reschedule-failed-exec\", &opts.reschedule_failed_exec,\n-\t\t\t N_(\"automatically re-schedule any `exec` that fails\")),\n-\t\tOPT_END()\n-\t};\n-\n-\topts.rebase_cousins = -1;\n-\n-\tif (argc == 1)\n-\t\tusage_with_options(builtin_rebase_interactive_usage, options);\n-\n-\targc = parse_options(argc, argv, prefix, options,\n-\t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n-\n-\tif (!is_null_oid(&squash_onto))\n-\t\topts.squash_onto = &squash_onto;\n-\n-\tif (opts.rebase_cousins >= 0 && !opts.rebase_merges)\n-\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n-\t\t\t  \"--rebase-merges\"));\n-\n-\treturn !!run_sequencer_rebase(&opts, command);\n-}\n-\n static int is_merge(struct rebase_options *opts)\n {\n \treturn opts->type == REBASE_MERGE;\ndiff --git a/git.c b/git.c\nindex 18bed9a9964..268cdd82cfc 100644\n--- a/git.c\n+++ b/git.c\n@@ -577,7 +577,6 @@ static struct cmd_struct commands[] = {\n \t{ \"range-diff\", cmd_range_diff, RUN_SETUP | USE_PAGER },\n \t{ \"read-tree\", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},\n \t{ \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n-\t{ \"rebase--interactive\", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"receive-pack\", cmd_receive_pack },\n \t{ \"reflog\", cmd_reflog, RUN_SETUP },\n \t{ \"remote\", cmd_remote, RUN_SETUP },\n-- \ngitgitgadget\n"},{"id":"434427","messageId":"8735qowknu.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-01T12:21:30Z","receivedAt":"2021-09-01T12:22:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> -\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n> +\tstruct strbuf script_snippet = STRBUF_INIT;\n\nYou end up removing all uses of script_snippet except the\nstrbuf_release() for it, so this & that can be removed too.\n"},{"id":"434441","messageId":"87zgswv34e.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"a987e9439af6335e15a3d41b82832e9a8824317b.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 6/7] git-svn: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-01T13:25:07Z","receivedAt":"2021-09-01T13:26:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>\n> We already passed the `--rebase-merges` option to `git rebase` instead,\n> now we make this move permanent.\n\nUnlike the cover letter's claim of deprecated since v2.22, this in\nparticular has only been deprecated since v2.25, i.e. your follow-up\nea8b7be1476 (git svn: stop using `rebase --preserve-merges`,\n2019-11-22).\n\nI think it's fine to do this, but at least updating the commit message\nto note the difference would be good.\n"},{"id":"434442","messageId":"87wno0v31k.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"cdb9fae4b939d4ce81372c0a0d81458eeb9b6299.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 3/7] tests: stop testing `git rebase --preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-01T13:26:38Z","receivedAt":"2021-09-01T13:27:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n\n> diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\n> index e78c7e37969..3bb023d7669 100755\n> --- a/t/t3427-rebase-subtree.sh\n> +++ b/t/t3427-rebase-subtree.sh\n> @@ -69,25 +69,6 @@ test_expect_success 'setup' '\n>  \tgit commit -m \"Empty commit\" --allow-empty\n>  '\n\nThe comment at the start should be changed too, e.g. something like this\nto squash in:\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex e78c7e37969..74e67b817f6 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -36,11 +36,8 @@ commit_message() {\n # where the root commit adds three files: topic_1.t, topic_2.t and topic_3.t.\n #\n # This commit history is then rebased onto `topic_3` with the\n-# `-Xsubtree=files_subtree` option in three different ways:\n-#\n-# 1. using `--preserve-merges`\n-# 2. using `--preserve-merges` and --keep-empty\n-# 3. without specifying a rebase backend\n+# `-Xsubtree=files_subtree` option, both with and without\n+# specifying a rebase backend\n \n test_expect_success 'setup' '\n        test_commit README &&\n"},{"id":"434447","messageId":"87tuj4v2q5.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-01T13:33:05Z","receivedAt":"2021-09-01T13:34:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>\n> This option was deprecated in favor of `--rebase-merges` some time ago,\n> and now we retire it.\n\n>  static int is_merge(struct rebase_options *opts)\n>  {\n> -\treturn opts->type == REBASE_MERGE ||\n> -\t\topts->type == REBASE_PRESERVE_MERGES;\n> +\treturn opts->type == REBASE_MERGE;\n>  }\n\nThis leaves us with a rather pointless is_merge() function and\nnonsensical control flow in parse_opt_merge(). Let's squash this in:\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 4e19f64b91b..043933ab771 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -383,11 +383,6 @@ static int parse_opt_keep_empty(const struct option *opt, const char *arg,\n \treturn 0;\n }\n \n-static int is_merge(struct rebase_options *opts)\n-{\n-\treturn opts->type == REBASE_MERGE;\n-}\n-\n static void imply_merge(struct rebase_options *opts, const char *option)\n {\n \tswitch (opts->type) {\n@@ -909,8 +904,7 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset)\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n-\tif (!is_merge(opts))\n-\t\topts->type = REBASE_MERGE;\n+\topts->type = REBASE_MERGE;\n \n \treturn 0;\n }\n@@ -988,7 +982,7 @@ static void set_reflog_action(struct rebase_options *options)\n \tconst char *env;\n \tstruct strbuf buf = STRBUF_INIT;\n \n-\tif (!is_merge(options))\n+\tif (options->type != REBASE_MERGE)\n \t\treturn;\n \n \tenv = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);\n@@ -1208,12 +1202,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"No rebase in progress?\"));\n \tsetenv(GIT_REFLOG_ACTION_ENVIRONMENT, \"rebase\", 0);\n \n-\tif (action == ACTION_EDIT_TODO && !is_merge(&options))\n+\tif (action == ACTION_EDIT_TODO && options.type != REBASE_MERGE)\n \t\tdie(_(\"The --edit-todo action can only be used during \"\n \t\t      \"interactive rebase.\"));\n \n \tif (trace2_is_enabled()) {\n-\t\tif (is_merge(&options))\n+\t\tif (options.type == REBASE_MERGE)\n \t\t\ttrace2_cmd_mode(\"interactive\");\n \t\telse if (exec.nr)\n \t\t\ttrace2_cmd_mode(\"interactive-exec\");\n@@ -1465,7 +1459,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t\tbreak;\n \n \t\tif (i >= 0) {\n-\t\t\tif (is_merge(&options))\n+\t\t\tif (options.type == REBASE_MERGE)\n \t\t\t\tdie(_(\"cannot combine apply options with \"\n \t\t\t\t      \"merge options\"));\n \t\t\telse\n@@ -1507,7 +1501,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\telse\n \t\t\toptions.empty = EMPTY_DROP;\n \t}\n-\tif (reschedule_failed_exec > 0 && !is_merge(&options))\n+\tif (reschedule_failed_exec > 0 && options.type != REBASE_MERGE)\n \t\tdie(_(\"--reschedule-failed-exec requires \"\n \t\t      \"--exec or --interactive\"));\n \tif (reschedule_failed_exec >= 0)\n@@ -1746,7 +1740,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tdiff_flush(&opts);\n \t}\n \n-\tif (is_merge(&options))\n+\tif (options.type == REBASE_MERGE)\n \t\tgoto run_rebase;\n \n \t/* Detach HEAD and reset the tree */\n"},{"id":"434448","messageId":"87r1e8v26x.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-01T13:37:06Z","receivedAt":"2021-09-01T13:46:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> included in v2.22.0), we officially deprecated the --preserve-merges\n> backend. Over two years later, it is time to drop that backend, and here is\n> a patch series that does just that.\n>\n> Changes since v1:\n>\n>  * Rebased onto v2.33.0\n\nI'm very much in favor if this series.\n\nI independently came up with pretty much the same at the beginning of\nlast month before finding your v1 in the list archive. The comments I\nleft inline are based on the diff between our two versions, i.e. I found\nsome spots you missed (and your version has spots I missed).\n\nYou're also leaving behind a comment in builtin/rebase.c referring to\nPRESERVE_MERGES. Perhaps we should just turn that into an \"else if\"\nwhile we're at it (the \"ignore-space-change\" argument won't need\nwrapping anymore then):\n\nbuiltin/rebase.c-       } else {\nbuiltin/rebase.c:               /* REBASE_MERGE and PRESERVE_MERGES */\nbuiltin/rebase.c-               if (ignore_whitespace) {\nbuiltin/rebase.c-                       string_list_append(&strategy_options,\nbuiltin/rebase.c-                                          \"ignore-space-change\");\nbuiltin/rebase.c-               }\nbuiltin/rebase.c-       }\n\nI do find the left-behind \"enum rebase_type\" rather unpleasant, i.e. we\nhave a REBASE_UNSPECIFIED during the initial parse_options() phase, and\nafter that just REBASE_{APPLY,MERGE}, but some of those codepaths use\nswitch(), some just check on or the other, and it's not immediately\nobvious where we are in the control flow. Ideally we'd take care of\nparsing out the option(s) early, and could just have an \"int\nrebase_apply\" in the struct to clearly indicate the rarer cases where we\ntake the REBASE_APPLY path.\n\nBut I wasn't able to make that work with some quick hacking, and in any\ncase that can be left as a cleanup for later.\n\nIdeally with the code comments I left addressed, but either way the\ncorrectness of the end result isn't affected in terms of what the\nprogram ends up doing:\n\nReviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n"},{"id":"434478","messageId":"xmqqk0k0ndbq.fsf@gitster.g","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-01T22:25:13Z","receivedAt":"2021-09-01T22:25:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\nwrites:\n\n> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> included in v2.22.0), we officially deprecated the --preserve-merges\n> backend. Over two years later, it is time to drop that backend, and here is\n> a patch series that does just that.\n\nA good goal.  There is no remaining use case where (a fictitious and\nproperly working version of) \"--preserve-merges\" option cannot be\nreplaced by \"--rebase-merges\", is it?  I somehow had a feeling that\nthe other Johannes (sorry if it weren't you, j6t) had cases that the\nformer worked better, but perhaps I am mis-remembering things.\n\nThanks.\n\n"},{"id":"434562","messageId":"nycvar.QRO.7.76.6.2109021553510.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"8735qowknu.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T13:54:30Z","receivedAt":"2021-09-02T13:54:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n>\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> > -\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n> > +\tstruct strbuf script_snippet = STRBUF_INIT;\n>\n> You end up removing all uses of script_snippet except the\n> strbuf_release() for it, so this & that can be removed too.\n\nValid point, I missed it because compiling with `DEVELOPER=1` did not\ncomplain (because `strbuf_release()` \"uses\" the variable).\n\nCiao,\nDscho\n"},{"id":"434563","messageId":"nycvar.QRO.7.76.6.2109021555050.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"87tuj4v2q5.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T13:59:39Z","receivedAt":"2021-09-02T13:59:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n>\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > This option was deprecated in favor of `--rebase-merges` some time ago,\n> > and now we retire it.\n>\n> >  static int is_merge(struct rebase_options *opts)\n> >  {\n> > -\treturn opts->type == REBASE_MERGE ||\n> > -\t\topts->type == REBASE_PRESERVE_MERGES;\n> > +\treturn opts->type == REBASE_MERGE;\n> >  }\n>\n> This leaves us with a rather pointless is_merge() function and\n> nonsensical control flow in parse_opt_merge().\n\nThank you for offering your perspective.\n\nFrom a readability point of view, I disagree with your assessment. Just\nbecause it can be written shorter does not mean that it is clearer. Quite\nthe contrary, if you ask me. And since _I_ am contributing this patch\nseries, I will respectfully disagree and keep the version I find more\nintuitive.\n\nYou could potentially talk me into adding a patch that renames that\nfunction to `is_merge_backend()`, but that's as far as I would go. And I\nam not really certain that that would improve things, either.\n\nCiao,\nDscho\n"},{"id":"434564","messageId":"nycvar.QRO.7.76.6.2109021600070.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"87zgswv34e.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 6/7] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T14:00:25Z","receivedAt":"2021-09-02T14:00:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n>\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > We already passed the `--rebase-merges` option to `git rebase` instead,\n> > now we make this move permanent.\n>\n> Unlike the cover letter's claim of deprecated since v2.22, this in\n> particular has only been deprecated since v2.25, i.e. your follow-up\n> ea8b7be1476 (git svn: stop using `rebase --preserve-merges`,\n> 2019-11-22).\n>\n> I think it's fine to do this, but at least updating the commit message\n> to note the difference would be good.\n\nI will update the commit message.\n\nCiao,\nDscho\n"},{"id":"434565","messageId":"nycvar.QRO.7.76.6.2109021607110.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"87zgswv34e.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 6/7] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T14:08:16Z","receivedAt":"2021-09-02T14:08:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n>\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > We already passed the `--rebase-merges` option to `git rebase` instead,\n> > now we make this move permanent.\n>\n> Unlike the cover letter's claim of deprecated since v2.22, this in\n> particular has only been deprecated since v2.25, i.e. your follow-up\n> ea8b7be1476 (git svn: stop using `rebase --preserve-merges`,\n> 2019-11-22).\n>\n> I think it's fine to do this, but at least updating the commit message\n> to note the difference would be good.\n\nThank you for being super rigorous.\n\nCiao,\nDscho\n"},{"id":"434566","messageId":"87y28f9ic8.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109021553510.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:11:09Z","receivedAt":"2021-09-02T14:13:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 02 2021, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n>\n>>\n>> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>>\n>> > -\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n>> > +\tstruct strbuf script_snippet = STRBUF_INIT;\n>>\n>> You end up removing all uses of script_snippet except the\n>> strbuf_release() for it, so this & that can be removed too.\n>\n> Valid point, I missed it because compiling with `DEVELOPER=1` did not\n> complain (because `strbuf_release()` \"uses\" the variable).\n\nAs an aside I was looking the other day to see if some variant of\n-Wunused was smart enough to exclude (preferably a configurable) list of\nfunctions. E.g.:\n\n    void *some_var = malloc(123);\n    free(some_var);\n\nCould be unused if something was smart to see that a thing only\ninteracting with \"malloc\" and \"free\" wasn't otherwise used, and likewise\nwe could add \"strbuf_release\" and other such free() functions to such a\nlist.\n\nBut I didn't find anything...\n"},{"id":"434567","messageId":"nycvar.QRO.7.76.6.2109021609220.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"87r1e8v26x.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T14:16:06Z","receivedAt":"2021-09-02T14:16:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n>\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> > In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> > included in v2.22.0), we officially deprecated the --preserve-merges\n> > backend. Over two years later, it is time to drop that backend, and here is\n> > a patch series that does just that.\n> >\n> > Changes since v1:\n> >\n> >  * Rebased onto v2.33.0\n>\n> I'm very much in favor if this series.\n>\n> I independently came up with pretty much the same at the beginning of\n> last month before finding your v1 in the list archive. The comments I\n> left inline are based on the diff between our two versions, i.e. I found\n> some spots you missed (and your version has spots I missed).\n>\n> You're also leaving behind a comment in builtin/rebase.c referring to\n> PRESERVE_MERGES. Perhaps we should just turn that into an \"else if\"\n> while we're at it (the \"ignore-space-change\" argument won't need\n> wrapping anymore then):\n>\n> builtin/rebase.c-       } else {\n> builtin/rebase.c:               /* REBASE_MERGE and PRESERVE_MERGES */\n> builtin/rebase.c-               if (ignore_whitespace) {\n> builtin/rebase.c-                       string_list_append(&strategy_options,\n> builtin/rebase.c-                                          \"ignore-space-change\");\n> builtin/rebase.c-               }\n> builtin/rebase.c-       }\n\nWhile it would be technically correct to turn this into an `else if`, by\nall other standards it would be incorrect. As I commented on your earlier\ncomment: just because it uses less lines does not make the intention\nclearer. In this instance, I am actually quite certain that it dilutes the\nintention. The `if (options.type == REBASE_APPLY)` clearly indicates a\ntop-level decision on the rebase backend, and an `else if\n(ignore_whitespace)` would disrupt that idea to be about distinguishing\nbetween completely unrelated concerns.\n\nIn other words: while I accept that your taste would prefer the suggested\nchange, my taste prefers the opposite, and since I am the owner of this\npatch series contribution, I go with my taste.\n\n> I do find the left-behind \"enum rebase_type\" rather unpleasant, i.e. we\n> have a REBASE_UNSPECIFIED during the initial parse_options() phase, and\n> after that just REBASE_{APPLY,MERGE}, but some of those codepaths use\n> switch(), some just check on or the other, and it's not immediately\n> obvious where we are in the control flow. Ideally we'd take care of\n> parsing out the option(s) early, and could just have an \"int\n> rebase_apply\" in the struct to clearly indicate the rarer cases where we\n> take the REBASE_APPLY path.\n\nThank you for offering your opinion.\n\nThis encourages me to offer my (differing) opinion to keep the `enum\nrebase_type` to clarify that we have multiple rebase backends, and even\nleave Git's source code open to future contributions of other rebase\nbackends.\n\nCiao,\nDscho\n"},{"id":"434569","messageId":"nycvar.QRO.7.76.6.2109021616300.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"xmqqk0k0ndbq.fsf@gitster.g","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-02T14:18:40Z","receivedAt":"2021-09-02T14:19:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 1 Sep 2021, Junio C Hamano wrote:\n\n> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n> writes:\n>\n> > In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> > included in v2.22.0), we officially deprecated the --preserve-merges\n> > backend. Over two years later, it is time to drop that backend, and here is\n> > a patch series that does just that.\n>\n> A good goal.  There is no remaining use case where (a fictitious and\n> properly working version of) \"--preserve-merges\" option cannot be\n> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n> the other Johannes (sorry if it weren't you, j6t) had cases that the\n> former worked better, but perhaps I am mis-remembering things.\n\nI think that I managed to address whatever concerns there were about the\n`--rebase-merges` backend in the meantime.\n\nTo be honest, I developed one (minor) concern in the meantime... Should we\nmaybe try to be nicer to our users and keep handling the\n`--preserve-merges` option by explicitly erroring out with the suggestion\nto use `--rebase-merges` instead? Not everybody reads release notes, after\nall. In fact, it is my experience that preciously few users have the time\nto even skim release notes...\n\nCiao,\nDscho\n"},{"id":"434570","messageId":"87tuj39hqd.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109021555050.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:16:22Z","receivedAt":"2021-09-02T14:26:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 02 2021, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n>\n>>\n>> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>>\n>> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>> >\n>> > This option was deprecated in favor of `--rebase-merges` some time ago,\n>> > and now we retire it.\n>>\n>> >  static int is_merge(struct rebase_options *opts)\n>> >  {\n>> > -\treturn opts->type == REBASE_MERGE ||\n>> > -\t\topts->type == REBASE_PRESERVE_MERGES;\n>> > +\treturn opts->type == REBASE_MERGE;\n>> >  }\n>>\n>> This leaves us with a rather pointless is_merge() function and\n>> nonsensical control flow in parse_opt_merge().\n>\n> Thank you for offering your perspective.\n>\n> From a readability point of view, I disagree with your assessment. Just\n> because it can be written shorter does not mean that it is clearer. Quite\n> the contrary, if you ask me. And since _I_ am contributing this patch\n> series, I will respectfully disagree and keep the version I find more\n> intuitive.\n>\n> You could potentially talk me into adding a patch that renames that\n> function to `is_merge_backend()`, but that's as far as I would go. And I\n> am not really certain that that would improve things, either.\n\nI should have phrased that \"Let's squash this in\" less forcefully, to be\nclear it was just a suggestion. I'm fine with you not taking that\nsquash. This series is good either way.\n\nBut just to poke a bit at the rationale: I'd be totally on-board with\nkeeping it because we'd like the smallest possible diff here, even if\nthat ends up including this oddity.\n\nBut in terms of making the end-result more readable I don't really see\nthat.\n\nWe're left with a mismatch of some things comparing the enum label\ndirectly, and some using this function, and then there's\nREBASE_APPLY. To make it consistent we could alternatively have the diff\nhere at the end, but having some mixture of both seems like the worst\nend-result, shouldn't we pick one way of inspecting these flags and use\nthat consistently?\n\n(I did not convert the few REBASE_UNSPECIFIED, but those comparisons\ncould similarly be is_unspecified(), and all three could be named\nis_*_backend() per your suggestion).\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex d707e3604e7..ef82a5f1668 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -388,6 +388,11 @@ static int is_merge(struct rebase_options *opts)\n \treturn opts->type == REBASE_MERGE;\n }\n \n+static int is_apply(struct rebase_options *opts)\n+{\n+\treturn opts->type == REBASE_APPLY;\n+}\n+\n static void imply_merge(struct rebase_options *opts, const char *option)\n {\n \tswitch (opts->type) {\n@@ -558,7 +563,7 @@ static int finish_rebase(struct rebase_options *opts)\n \t * user should see them.\n \t */\n \trun_auto_maintenance(!(opts->flags & (REBASE_NO_QUIET|REBASE_VERBOSE)));\n-\tif (opts->type == REBASE_MERGE) {\n+\tif (is_merge(opts)) {\n \t\tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \n \t\treplay.action = REPLAY_INTERACTIVE_REBASE;\n@@ -744,7 +749,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \tstruct strbuf script_snippet = STRBUF_INIT;\n \tint status;\n \n-\tif (opts->type == REBASE_MERGE) {\n+\tif (is_merge(opts)) {\n \t\t/* Run sequencer-based rebase */\n \t\tsetenv(\"GIT_CHERRY_PICK_HELP\", resolvemsg, 1);\n \t\tif (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n@@ -759,14 +764,14 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t}\n \n \t\tstatus = run_sequencer_rebase(opts, action);\n-\t} else if (opts->type == REBASE_APPLY)\n+\t} else if (is_apply(opts))\n \t\tstatus = run_am(opts);\n \telse\n \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n \n \tif (opts->dont_finish_rebase)\n \t\t; /* do nothing */\n-\telse if (opts->type == REBASE_MERGE)\n+\telse if (is_merge(opts))\n \t\t; /* merge backend cleans up after itself */\n \telse if (status == 0) {\n \t\tif (!file_exists(state_dir_path(\"stopped-sha\", opts)))\n@@ -1293,7 +1298,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t}\n \tcase ACTION_QUIT: {\n \t\tsave_autostash(state_dir_path(\"autostash\", &options));\n-\t\tif (options.type == REBASE_MERGE) {\n+\t\tif (is_merge(&options)) {\n \t\t\tstruct replay_opts replay = REPLAY_OPTS_INIT;\n \n \t\t\treplay.action = REPLAY_INTERACTIVE_REBASE;\n@@ -1406,7 +1411,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\timply_merge(&options, \"--rebase-merges\");\n \t}\n \n-\tif (options.type == REBASE_APPLY) {\n+\tif (is_apply(&options)) {\n \t\tif (ignore_whitespace)\n \t\t\tstrvec_push(&options.git_am_opts,\n \t\t\t\t    \"--ignore-whitespace\");\n@@ -1452,7 +1457,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t}\n \t}\n \n-\tif (options.type == REBASE_MERGE)\n+\tif (is_merge(&options))\n \t\timply_merge(&options, \"--merge\");\n \n \tif (options.root && !options.onto_name)\n@@ -1461,7 +1466,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (isatty(2) && options.flags & REBASE_NO_QUIET)\n \t\tstrbuf_addstr(&options.git_format_patch_opt, \" --progress\");\n \n-\tif (options.git_am_opts.nr || options.type == REBASE_APPLY) {\n+\tif (options.git_am_opts.nr || is_apply(&options)) {\n \t\t/* all am options except -q are compatible only with --apply */\n \t\tfor (i = options.git_am_opts.nr - 1; i >= 0; i--)\n \t\t\tif (strcmp(options.git_am_opts.v[i], \"-q\"))\n@@ -1486,7 +1491,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t    options.default_backend);\n \t}\n \n-\tif (options.type == REBASE_MERGE &&\n+\tif (is_merge(&options) &&\n \t    !options.strategy &&\n \t    getenv(\"GIT_TEST_MERGE_ALGORITHM\"))\n \t\toptions.strategy = xstrdup(getenv(\"GIT_TEST_MERGE_ALGORITHM\"));\n"},{"id":"434571","messageId":"87pmtr9hd5.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:28:16Z","receivedAt":"2021-09-02T14:34:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>\n> This option was deprecated in favor of `--rebase-merges` some time ago,\n> and now we retire it.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  .gitignore                     |    1 -\n>  Documentation/git-rebase.txt   |   51 --\n>  Makefile                       |    2 -\n>  builtin/rebase.c               |  133 +---\n>  git-rebase--preserve-merges.sh | 1057 --------------------------------\n>  5 files changed, 6 insertions(+), 1238 deletions(-)\n>  delete mode 100644 git-rebase--preserve-merges.sh\n>\n> diff --git a/.gitignore b/.gitignore\n> index 311841f9bed..98d6275b20d 100644\n> --- a/.gitignore\n> +++ b/.gitignore\n> @@ -125,7 +125,6 @@\n>  /git-range-diff\n>  /git-read-tree\n>  /git-rebase\n> -/git-rebase--preserve-merges\n>  /git-receive-pack\n>  /git-reflog\n>  /git-remote\n> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\n> index 55af6fd24e2..1382dc6f005 100644\n> --- a/Documentation/git-rebase.txt\n> +++ b/Documentation/git-rebase.txt\n> @@ -525,29 +525,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s\n>  the `rebase-cousins` mode is turned on, such commits are instead rebased\n>  onto `<upstream>` (or `<onto>`, if specified).\n>  +\n> -The `--rebase-merges` mode is similar in spirit to the deprecated\n> -`--preserve-merges` but works with interactive rebases,\n> -where commits can be reordered, inserted and dropped at will.\n> -+\n>  It is currently only possible to recreate the merge commits using the\n>  `recursive` merge strategy; Different merge strategies can be used only via\n>  explicit `exec git merge -s <strategy> [...]` commands.\n>  +\n>  See also REBASING MERGES and INCOMPATIBLE OPTIONS below.\n>  \n> --p::\n> ---preserve-merges::\n> -\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n> -\tinstead of flattening the history by replaying commits a merge commit\n> -\tintroduces. Merge conflict resolutions or manual amendments to merge\n> -\tcommits are not preserved.\n> -+\n> -This uses the `--interactive` machinery internally, but combining it\n> -with the `--interactive` option explicitly is generally not a good\n> -idea unless you know what you are doing (see BUGS below).\n> -+\n> -See also INCOMPATIBLE OPTIONS below.\n> -\n\nI wonder if we should leave some variant of this in, just as a last\nresort to help users who have some ancient version / finger memory &\nwonder why it doesn't work, something like;\n\n-p::\n--preserve-merges:\n\tThese options were used by the long-deprecated and now removed\n\t\"rebase merges\" backend. The `--rebase-merges` option is the\n\tsimilar in spirit replacement mode.\n\nAlso, per your ea8b7be1476 (git svn: stop using `rebase\n--preserve-merges`, 2019-11-22) the use in \"git svn\" couldn't really be\ndirectly compared to this, but there we usurped the \"-p\" flag for\n--rebase-merges. Perhaps we could/should do the same here (eventually,\ndoesn't need to be in this series).\n"},{"id":"434572","messageId":"87lf4f9gre.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:34:43Z","receivedAt":"2021-09-02T14:47:08Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n\n>  git-rebase--preserve-merges.sh | 1057 --------------------------------\n\nYou could, but certainly don't have to, squash in the below. I.e. this\nis the last user of eval_ngettext!\n\nI mentioned in <87r1e8v26x.fsf@evledraar.gmail.com> that I'd recently\ncome up with pretty much the same diff, that was because I was seeing\nhow much of the shellscript gettext support I could rip out.\n\nThis is a major step to getting a whole section of git's shellscript\nsupport infrastructure out-of-tree, i.e. git-sh-i18n.sh, and the\nsh-i18n--envsubst built-in helper.\n\nIf I then merge mirucam/git-bisect-work-part4-v6 &\ngitster/ar/submodule-run-update-procedure along with this we'll have a\nrelatively small amount of gettext-in-sh code left, which should be\nentirely gone before too long. Yay!\n\ndiff --git a/git-sh-i18n.sh b/git-sh-i18n.sh\nindex e3d9f4836db..a15c0620db6 100644\n--- a/git-sh-i18n.sh\n+++ b/git-sh-i18n.sh\n@@ -51,12 +51,6 @@ gettext_without_eval_gettext)\n \t\t)\n \t}\n \n-\teval_ngettext () {\n-\t\tngettext \"$1\" \"$2\" \"$3\" | (\n-\t\t\texport PATH $(git sh-i18n--envsubst --variables \"$2\");\n-\t\t\tgit sh-i18n--envsubst \"$2\"\n-\t\t)\n-\t}\n \t;;\n *)\n \tgettext () {\n@@ -70,12 +64,6 @@ gettext_without_eval_gettext)\n \t\t)\n \t}\n \n-\teval_ngettext () {\n-\t\t(test \"$3\" = 1 && printf \"%s\" \"$1\" || printf \"%s\" \"$2\") | (\n-\t\t\texport PATH $(git sh-i18n--envsubst --variables \"$2\");\n-\t\t\tgit sh-i18n--envsubst \"$2\"\n-\t\t)\n-\t}\n \t;;\n esac\n \n\n"},{"id":"434573","messageId":"87h7f39gcr.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109021609220.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:51:28Z","receivedAt":"2021-09-02T14:55:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 02 2021, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Wed, 1 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n>\n>>\n>> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>>\n>> > In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n>> > included in v2.22.0), we officially deprecated the --preserve-merges\n>> > backend. Over two years later, it is time to drop that backend, and here is\n>> > a patch series that does just that.\n>> >\n>> > Changes since v1:\n>> >\n>> >  * Rebased onto v2.33.0\n>>\n>> I'm very much in favor if this series.\n>>\n>> I independently came up with pretty much the same at the beginning of\n>> last month before finding your v1 in the list archive. The comments I\n>> left inline are based on the diff between our two versions, i.e. I found\n>> some spots you missed (and your version has spots I missed).\n>>\n>> You're also leaving behind a comment in builtin/rebase.c referring to\n>> PRESERVE_MERGES. Perhaps we should just turn that into an \"else if\"\n>> while we're at it (the \"ignore-space-change\" argument won't need\n>> wrapping anymore then):\n>>\n>> builtin/rebase.c-       } else {\n>> builtin/rebase.c:               /* REBASE_MERGE and PRESERVE_MERGES */\n>> builtin/rebase.c-               if (ignore_whitespace) {\n>> builtin/rebase.c-                       string_list_append(&strategy_options,\n>> builtin/rebase.c-                                          \"ignore-space-change\");\n>> builtin/rebase.c-               }\n>> builtin/rebase.c-       }\n>\n> While it would be technically correct to turn this into an `else if`, by\n> all other standards it would be incorrect. As I commented on your earlier\n> comment: just because it uses less lines does not make the intention\n> clearer. In this instance, I am actually quite certain that it dilutes the\n> intention. The `if (options.type == REBASE_APPLY)` clearly indicates a\n> top-level decision on the rebase backend, and an `else if\n> (ignore_whitespace)` would disrupt that idea to be about distinguishing\n> between completely unrelated concerns.\n>\n> In other words: while I accept that your taste would prefer the suggested\n> change, my taste prefers the opposite, and since I am the owner of this\n> patch series contribution, I go with my taste.\n\nSounds good.\n\n>> I do find the left-behind \"enum rebase_type\" rather unpleasant, i.e. we\n>> have a REBASE_UNSPECIFIED during the initial parse_options() phase, and\n>> after that just REBASE_{APPLY,MERGE}, but some of those codepaths use\n>> switch(), some just check on or the other, and it's not immediately\n>> obvious where we are in the control flow. Ideally we'd take care of\n>> parsing out the option(s) early, and could just have an \"int\n>> rebase_apply\" in the struct to clearly indicate the rarer cases where we\n>> take the REBASE_APPLY path.\n>\n> Thank you for offering your opinion.\n>\n> This encourages me to offer my (differing) opinion to keep the `enum\n> rebase_type` to clarify that we have multiple rebase backends, and even\n> leave Git's source code open to future contributions of other rebase\n> backends.\n\nJust to clarify this isn't a comment describing the suggested is_merge()\nchanges I had elsewhere, or that we should get rid of \"enum\nrebase_type\".\n\nBut rather that if we were to split up the \"we haven't decided on the\ntype yet\" from \"we know the rebase type, let's act on it\" which only\nhappens around the option/config/directory introspection etc. from the\nrest of the code, we could stick on the \"real\" rebase types in the enum.\n\nWe could then have just two enum arms for switches (less verbosity) and\nno \"default: BUG(...)\" case.\n\nSuch a change should make it easier for contributors to add new\nbackends, as they'd get the compiler helping them to see where they'd\nneed to add their code. Now you need to hunt around for various\nis_merge, \"opts.type == \" etc, switches with \"default\" etc. comparisons.\n\nOf course such a change might not be worth it, i.e. maybe it's too\npainful to untangle REBASE_UNSPECIFIED from the existing enum. I just\nwanted to clarify what it was that I was suggesting here.\n"},{"id":"434574","messageId":"87czpr9fwz.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"87lf4f9gre.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T14:56:18Z","receivedAt":"2021-09-02T15:05:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 02 2021, Ævar Arnfjörð Bjarmason wrote:\n\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n>>  git-rebase--preserve-merges.sh | 1057 --------------------------------\n>\n> You could, but certainly don't have to, squash in the below. I.e. this\n> is the last user of eval_ngettext!\n\nAlso get_author_ident_from_commit() in git-sh-setup.sh and\nDocumentation/git-sh-setup.txt can be removed,\ngit-rebase--preserve-merges.sh is the last user of it.\n\nI looked over the other git-sh-setup functions, it seems that's the only\none that could be removed along with git-rebase--preserve-merges.sh.\n"},{"id":"434576","messageId":"878s0f9ei8.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"87czpr9fwz.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-02T15:34:56Z","receivedAt":"2021-09-02T15:35:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 02 2021, Ævar Arnfjörð Bjarmason wrote:\n\n> On Thu, Sep 02 2021, Ævar Arnfjörð Bjarmason wrote:\n>\n>> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>>\n>>>  git-rebase--preserve-merges.sh | 1057 --------------------------------\n>>\n>> You could, but certainly don't have to, squash in the below. I.e. this\n>> is the last user of eval_ngettext!\n>\n> Also get_author_ident_from_commit() in git-sh-setup.sh and\n> Documentation/git-sh-setup.txt can be removed,\n> git-rebase--preserve-merges.sh is the last user of it.\n>\n> I looked over the other git-sh-setup functions, it seems that's the only\n> one that could be removed along with git-rebase--preserve-merges.sh.\n\nAlthough with git-rebase--preserve-merges.sh gone the\nget_author_ident_from_commit(), parse_ident_from_commit() and\npick_ident_script() can all be moved to its last user:\ngit-filter-branch.sh\n"},{"id":"434593","messageId":"4e998676-4975-8ac2-35a0-34416938b62e@kdbg.org","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109021616300.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2021-09-02T20:06:05Z","receivedAt":"2021-09-02T20:06:10Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 02.09.21 um 16:18 schrieb Johannes Schindelin:\n> On Wed, 1 Sep 2021, Junio C Hamano wrote:\n>> A good goal.  There is no remaining use case where (a fictitious and\n>> properly working version of) \"--preserve-merges\" option cannot be\n>> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n>> the other Johannes (sorry if it weren't you, j6t) had cases that the\n>> former worked better, but perhaps I am mis-remembering things.\n> \n> I think that I managed to address whatever concerns there were about the\n> `--rebase-merges` backend in the meantime.\n\nThat was either my suggestion/desire to make no-rebase-cousins the\ndefault. That has been settled.\n\nOr my wish not to redo the merge, but to replay the first-parent\ndifference. The idea never got traction, and I've long since abandoned\nmy implementation of it.\n\n> To be honest, I developed one (minor) concern in the meantime... Should we\n> maybe try to be nicer to our users and keep handling the\n> `--preserve-merges` option by explicitly erroring out with the suggestion\n> to use `--rebase-merges` instead? Not everybody reads release notes, after\n> all. In fact, it is my experience that preciously few users have the time\n> to even skim release notes...\n\nA valid concern, I would think.\n\n-- Hannes\n"},{"id":"434704","messageId":"nycvar.QRO.7.76.6.2109042138410.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"87lf4f9gre.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-04T19:41:52Z","receivedAt":"2021-09-04T19:59:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ævar,\n\nOn Thu, 2 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n\n> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n> >  git-rebase--preserve-merges.sh | 1057 --------------------------------\n>\n> You could, but certainly don't have to, squash in the below. I.e. this\n> is the last user of eval_ngettext!\n\ns/last user/last in-tree user/\n\nSince we install `git-sh-i18n` and semi-advertised it as something to use\nin user scripts (which makes removing it somewhat questionable a goal,\ncertainly when you do not even offer a deprecation period), and since the\nremoval of such things is completely orthogonal to the intention of this\npatch series, I will not include this patch, let alone squash it into a\ncommit whose purpose has nothing to do with gettext whatsoever.\n\nCiao,\nJohannes\n"},{"id":"434709","messageId":"62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Alban Gruin","fromEmail":"alban.gruin@gmail.com","sentAt":"2021-09-04T22:30:53Z","receivedAt":"2021-09-04T22:32:22Z","isPatch":true,"sender":{"key":"alban.gruin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6310153?v=4"},"body":"Hi Johannes,\n\nLe 01/09/2021 à 13:57, Johannes Schindelin via GitGitGadget a écrit :\n> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> included in v2.22.0), we officially deprecated the --preserve-merges\n> backend. Over two years later, it is time to drop that backend, and here is\n> a patch series that does just that.\n> \n> Changes since v1:\n> \n>  * Rebased onto v2.33.0\n> \n> Johannes Schindelin (7):\n>   t5520: do not use `pull.rebase=preserve`\n>   remote: warn about unhandled branch.<name>.rebase values\n>   tests: stop testing `git rebase --preserve-merges`\n>   pull: remove support for `--rebase=preserve`\n>   rebase: drop support for `--preserve-merges`\n>   git-svn: drop support for `--preserve-merges`\n>   rebase: drop the internal `rebase--interactive` command\n> \n\nThis is good.\n\npreserve-merge is the only user of `rebase--interactive'.  In\nbuiltin/rebase.c, it is the only producer of the following actions:\n\n - ACTION_SHORTEN_OIDS\n - ACTION_EXPAND_OIDS\n - ACTION_CHECK_TODO_LIST\n - ACTION_REARRANGE_SQUASH\n - ACTION_ADD_EXEC\n\nWhich in turn, are the only reason for these functions to exist:\n\n - transform_todo_file()\n - check_todo_list_from_file() (from the sequencer)\n - rearrange_squash_in_todo_file()\n - add_exec_commands()\n\nThis is from a cursory glance, it may go a bit deeper.\n\nShould we remove these as well?\n\nAlban\n\n"},{"id":"434716","messageId":"87wnnvpiyj.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109042138410.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-05T07:32:28Z","receivedAt":"2021-09-05T07:44:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Sat, Sep 04 2021, Johannes Schindelin wrote:\n\n> Hi Ævar,\n>\n> On Thu, 2 Sep 2021, Ævar Arnfjörð Bjarmason wrote:\n>\n>> On Wed, Sep 01 2021, Johannes Schindelin via GitGitGadget wrote:\n>>\n>> >  git-rebase--preserve-merges.sh | 1057 --------------------------------\n>>\n>> You could, but certainly don't have to, squash in the below. I.e. this\n>> is the last user of eval_ngettext!\n>\n> s/last user/last in-tree user/\n>\n> Since we install `git-sh-i18n` and semi-advertised it as something to use\n> in user scripts (which makes removing it somewhat questionable a goal,\n> certainly when you do not even offer a deprecation period), and since the\n> removal of such things is completely orthogonal to the intention of this\n> patch series, I will not include this patch, let alone squash it into a\n> commit whose purpose has nothing to do with gettext whatsoever.\n\nUnlike whatever controversy we're having over git-sh-setup being removed\n(see <cover-0.9-00000000000-20210902T155758Z-avarab@gmail.com>[1]), the\ngit-sh-i18n's gettext() and eval_gettext() can't be useful to anyone out\nof git.git's tree, since they accept strings that are expected to be\nfound in git.git's generated *.mo files.\n\nSo it's certainly possible that someone's used out out-of-tree, but that\nuse of eval_gettext() won't have been doing anything useful in terms of\ntranslation, and if it did that would have been because someone copied a\nto-be-translated string as-is, and expected git.git to keep it\nbyte-for-byte the same as their sources.\n\nAnyway, if you don't want to squash this in I can submit it as some sort\nof follow-up, perhaps along with some of the suggestions in\n<62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com>[2] if you're generally\naiming to keep the changes here to the depth of the first callstack,\ni.e. remove the --preserve-merges use of a foo(), but not a foo()\nfunction itself if that foo() then becomes orphaned as a result.\n\n1. https://lore.kernel.org/git/cover-0.9-00000000000-20210902T155758Z-avarab@gmail.com/\n2. https://lore.kernel.org/git/62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com/\n"},{"id":"434738","messageId":"xmqqlf4aejko.fsf@gitster.g","threadId":"52325","inReplyTo":"87wnnvpiyj.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-05T22:36:23Z","receivedAt":"2021-09-05T22:36:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> ... the\n> git-sh-i18n's gettext() and eval_gettext() can't be useful to anyone out\n> of git.git's tree, since they accept strings that are expected to be\n> found in git.git's generated *.mo files.\n\nTrue but removing it is probably outside the scope of this series.\nRemoval of helper functions from sh-i18n can be discussed once the\ndust from this topic settles (\"now the last caller of the helper is\ngone from 'master', we can remove X, Y and Z\").\n"},{"id":"434766","messageId":"87y28anq98.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"xmqqk0k0ndbq.fsf@gitster.g","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-06T06:58:13Z","receivedAt":"2021-09-06T06:59:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Sep 01 2021, Junio C Hamano wrote:\n\n> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n> writes:\n>\n>> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n>> included in v2.22.0), we officially deprecated the --preserve-merges\n>> backend. Over two years later, it is time to drop that backend, and here is\n>> a patch series that does just that.\n>\n> A good goal.  There is no remaining use case where (a fictitious and\n> properly working version of) \"--preserve-merges\" option cannot be\n> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n> the other Johannes (sorry if it weren't you, j6t) had cases that the\n> former worked better, but perhaps I am mis-remembering things.\n\nFair enough. To be clear I think this series is fine as-is, we've just\nusually done \"now that this function is dead, rm it\" as part of the\nseries that makes it dead, so I figured fixups/squashes to change those\nparts would be welcome & integrated, likewise Alban Gruin's suggestions\nin <62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com>.\n\nBut the git-sh-i18n.sh change and/or his suggestions can be done after\nthis lands...\n"},{"id":"434783","messageId":"cf76b707-bd59-26f8-f257-02d773294495@gmail.com","threadId":"52325","inReplyTo":"4492cca369cdc0c8cd39b3dafab86d798cfbaa8f.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 7/7] rebase: drop the internal `rebase--interactive` command","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2021-09-06T10:10:15Z","receivedAt":"2021-09-06T10:10:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi dscho\n\nThanks for working on this, it opens up the possibility of future \ncleanups now we're not constrained by supporting cmd_rebase__interactive()\n\nOn 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> [...]\n> @@ -437,24 +362,6 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n>   \n>   \t\tbreak;\n>   \t}\n> -\tcase ACTION_SHORTEN_OIDS:\n> -\tcase ACTION_EXPAND_OIDS:\n> -\t\tret = transform_todo_file(flags);\n> -\t\tbreak;\n> -\tcase ACTION_CHECK_TODO_LIST:\n> -\t\tret = check_todo_list_from_file(the_repository);\n> -\t\tbreak;\n> -\tcase ACTION_REARRANGE_SQUASH:\n> -\t\tret = rearrange_squash_in_todo_file();\n> -\t\tbreak;\n> -\tcase ACTION_ADD_EXEC: {\n> -\t\tstruct string_list commands = STRING_LIST_INIT_DUP;\n> -\n> -\t\tsplit_exec_commands(opts->cmd, &commands);\n> -\t\tret = add_exec_commands(&commands);\n> -\t\tstring_list_clear(&commands, 0);\n> -\t\tbreak;\n> -\t}\n\nAs Alban mentioned, I think it would be worth removing the enum members \nas well as the case clauses here.\n\nBest Wishes\n\nPhillip\n\n>   \tdefault:\n>   \t\tBUG(\"invalid command '%d'\", command);\n>   \t}\n> @@ -476,98 +383,6 @@ static int parse_opt_keep_empty(const struct option *opt, const char *arg,\n>   \treturn 0;\n>   }\n>   \n> -static const char * const builtin_rebase_interactive_usage[] = {\n> -\tN_(\"git rebase--interactive [<options>]\"),\n> -\tNULL\n> -};\n> -\n> -int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n> -{\n> -\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n> -\tstruct object_id squash_onto = *null_oid();\n> -\tenum action command = ACTION_NONE;\n> -\tstruct option options[] = {\n> -\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n> -\t\t\t   REBASE_FORCE),\n> -\t\tOPT_CALLBACK_F('k', \"keep-empty\", &options, NULL,\n> -\t\t\tN_(\"keep commits which start empty\"),\n> -\t\t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN,\n> -\t\t\tparse_opt_keep_empty),\n> -\t\tOPT_BOOL_F(0, \"allow-empty-message\", &opts.allow_empty_message,\n> -\t\t\t   N_(\"allow commits with empty messages\"),\n> -\t\t\t   PARSE_OPT_HIDDEN),\n> -\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase merge commits\")),\n> -\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n> -\t\t\t N_(\"keep original branch points of cousins\")),\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_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> -\t\tOPT_CMDMODE(0, \"continue\", &command, N_(\"continue rebase\"),\n> -\t\t\t    ACTION_CONTINUE),\n> -\t\tOPT_CMDMODE(0, \"skip\", &command, N_(\"skip commit\"), ACTION_SKIP),\n> -\t\tOPT_CMDMODE(0, \"edit-todo\", &command, N_(\"edit the todo list\"),\n> -\t\t\t    ACTION_EDIT_TODO),\n> -\t\tOPT_CMDMODE(0, \"show-current-patch\", &command, N_(\"show the current patch\"),\n> -\t\t\t    ACTION_SHOW_CURRENT_PATCH),\n> -\t\tOPT_CMDMODE(0, \"shorten-ids\", &command,\n> -\t\t\tN_(\"shorten commit ids in the todo list\"), ACTION_SHORTEN_OIDS),\n> -\t\tOPT_CMDMODE(0, \"expand-ids\", &command,\n> -\t\t\tN_(\"expand commit ids in the todo list\"), ACTION_EXPAND_OIDS),\n> -\t\tOPT_CMDMODE(0, \"check-todo-list\", &command,\n> -\t\t\tN_(\"check the todo list\"), ACTION_CHECK_TODO_LIST),\n> -\t\tOPT_CMDMODE(0, \"rearrange-squash\", &command,\n> -\t\t\tN_(\"rearrange fixup/squash lines\"), ACTION_REARRANGE_SQUASH),\n> -\t\tOPT_CMDMODE(0, \"add-exec-commands\", &command,\n> -\t\t\tN_(\"insert exec commands in todo list\"), ACTION_ADD_EXEC),\n> -\t\t{ OPTION_CALLBACK, 0, \"onto\", &opts.onto, N_(\"onto\"), N_(\"onto\"),\n> -\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n> -\t\t{ OPTION_CALLBACK, 0, \"restrict-revision\", &opts.restrict_revision,\n> -\t\t  N_(\"restrict-revision\"), N_(\"restrict revision\"),\n> -\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n> -\t\t{ OPTION_CALLBACK, 0, \"squash-onto\", &squash_onto, N_(\"squash-onto\"),\n> -\t\t  N_(\"squash onto\"), PARSE_OPT_NONEG, parse_opt_object_id, 0 },\n> -\t\t{ OPTION_CALLBACK, 0, \"upstream\", &opts.upstream, N_(\"upstream\"),\n> -\t\t  N_(\"the upstream commit\"), PARSE_OPT_NONEG, parse_opt_commit,\n> -\t\t  0 },\n> -\t\tOPT_STRING(0, \"head-name\", &opts.head_name, N_(\"head-name\"), N_(\"head name\")),\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_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> -\t\t\t   N_(\"strategy options\")),\n> -\t\tOPT_STRING(0, \"switch-to\", &opts.switch_to, N_(\"switch-to\"),\n> -\t\t\t   N_(\"the branch or commit to checkout\")),\n> -\t\tOPT_STRING(0, \"onto-name\", &opts.onto_name, N_(\"onto-name\"), N_(\"onto name\")),\n> -\t\tOPT_STRING(0, \"cmd\", &opts.cmd, N_(\"cmd\"), N_(\"the command to run\")),\n> -\t\tOPT_RERERE_AUTOUPDATE(&opts.allow_rerere_autoupdate),\n> -\t\tOPT_BOOL(0, \"reschedule-failed-exec\", &opts.reschedule_failed_exec,\n> -\t\t\t N_(\"automatically re-schedule any `exec` that fails\")),\n> -\t\tOPT_END()\n> -\t};\n> -\n> -\topts.rebase_cousins = -1;\n> -\n> -\tif (argc == 1)\n> -\t\tusage_with_options(builtin_rebase_interactive_usage, options);\n> -\n> -\targc = parse_options(argc, argv, prefix, options,\n> -\t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n> -\n> -\tif (!is_null_oid(&squash_onto))\n> -\t\topts.squash_onto = &squash_onto;\n> -\n> -\tif (opts.rebase_cousins >= 0 && !opts.rebase_merges)\n> -\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n> -\t\t\t  \"--rebase-merges\"));\n> -\n> -\treturn !!run_sequencer_rebase(&opts, command);\n> -}\n> -\n>   static int is_merge(struct rebase_options *opts)\n>   {\n>   \treturn opts->type == REBASE_MERGE;\n> diff --git a/git.c b/git.c\n> index 18bed9a9964..268cdd82cfc 100644\n> --- a/git.c\n> +++ b/git.c\n> @@ -577,7 +577,6 @@ static struct cmd_struct commands[] = {\n>   \t{ \"range-diff\", cmd_range_diff, RUN_SETUP | USE_PAGER },\n>   \t{ \"read-tree\", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},\n>   \t{ \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n> -\t{ \"rebase--interactive\", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },\n>   \t{ \"receive-pack\", cmd_receive_pack },\n>   \t{ \"reflog\", cmd_reflog, RUN_SETUP },\n>   \t{ \"remote\", cmd_remote, RUN_SETUP },\n> \n\n"},{"id":"434784","messageId":"d93a750a-9faf-c91a-c9f7-e968c7ed40f5@gmail.com","threadId":"52325","inReplyTo":"eb738b1bf05dceb1d119e3adcd732d968407c757.1630497435.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2021-09-06T10:15:27Z","receivedAt":"2021-09-06T10:15:33Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi dscho\n\nOn 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> \n> This option was deprecated in favor of `--rebase-merges` some time ago,\n> and now we retire it.\n\nThis all looks good to me. I did see the comment below in \nbuiltin/rebase.c that could be tweaked if you reroll, but it is a very \nminor issue.\n\n/* -i followed by -p is still explicitly interactive, but -p alone is not */\nstatic int parse_opt_interactive(const struct option *opt, const char *arg,\n                                  int unset)\n\nI do wonder if we need these option parsing functions now but that is a \nquestion for another day.\n\nBest Wishes\n\nPhillip\n\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>   .gitignore                     |    1 -\n>   Documentation/git-rebase.txt   |   51 --\n>   Makefile                       |    2 -\n>   builtin/rebase.c               |  133 +---\n>   git-rebase--preserve-merges.sh | 1057 --------------------------------\n>   5 files changed, 6 insertions(+), 1238 deletions(-)\n>   delete mode 100644 git-rebase--preserve-merges.sh\n> \n> diff --git a/.gitignore b/.gitignore\n> index 311841f9bed..98d6275b20d 100644\n> --- a/.gitignore\n> +++ b/.gitignore\n> @@ -125,7 +125,6 @@\n>   /git-range-diff\n>   /git-read-tree\n>   /git-rebase\n> -/git-rebase--preserve-merges\n>   /git-receive-pack\n>   /git-reflog\n>   /git-remote\n> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\n> index 55af6fd24e2..1382dc6f005 100644\n> --- a/Documentation/git-rebase.txt\n> +++ b/Documentation/git-rebase.txt\n> @@ -525,29 +525,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s\n>   the `rebase-cousins` mode is turned on, such commits are instead rebased\n>   onto `<upstream>` (or `<onto>`, if specified).\n>   +\n> -The `--rebase-merges` mode is similar in spirit to the deprecated\n> -`--preserve-merges` but works with interactive rebases,\n> -where commits can be reordered, inserted and dropped at will.\n> -+\n>   It is currently only possible to recreate the merge commits using the\n>   `recursive` merge strategy; Different merge strategies can be used only via\n>   explicit `exec git merge -s <strategy> [...]` commands.\n>   +\n>   See also REBASING MERGES and INCOMPATIBLE OPTIONS below.\n>   \n> --p::\n> ---preserve-merges::\n> -\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n> -\tinstead of flattening the history by replaying commits a merge commit\n> -\tintroduces. Merge conflict resolutions or manual amendments to merge\n> -\tcommits are not preserved.\n> -+\n> -This uses the `--interactive` machinery internally, but combining it\n> -with the `--interactive` option explicitly is generally not a good\n> -idea unless you know what you are doing (see BUGS below).\n> -+\n> -See also INCOMPATIBLE OPTIONS below.\n> -\n>   -x <cmd>::\n>   --exec <cmd>::\n>   \tAppend \"exec <cmd>\" after each line creating a commit in the\n> @@ -579,9 +562,6 @@ See also INCOMPATIBLE OPTIONS below.\n>   \tthe root commit(s) on a branch.  When used with --onto, it\n>   \twill skip changes already contained in <newbase> (instead of\n>   \t<upstream>) whereas without --onto it will operate on every change.\n> -\tWhen used together with both --onto and --preserve-merges,\n> -\t'all' root commits will be rewritten to have <newbase> as parent\n> -\tinstead.\n>   +\n>   See also INCOMPATIBLE OPTIONS below.\n>   \n> @@ -643,7 +623,6 @@ are incompatible with the following options:\n>    * --allow-empty-message\n>    * --[no-]autosquash\n>    * --rebase-merges\n> - * --preserve-merges\n>    * --interactive\n>    * --exec\n>    * --no-keep-empty\n> @@ -654,13 +633,6 @@ are incompatible with the following options:\n>   \n>   In addition, the following pairs of options are incompatible:\n>   \n> - * --preserve-merges and --interactive\n> - * --preserve-merges and --signoff\n> - * --preserve-merges and --rebase-merges\n> - * --preserve-merges and --empty=\n> - * --preserve-merges and --ignore-whitespace\n> - * --preserve-merges and --committer-date-is-author-date\n> - * --preserve-merges and --ignore-date\n>    * --keep-base and --onto\n>    * --keep-base and --root\n>    * --fork-point and --root\n> @@ -1274,29 +1246,6 @@ CONFIGURATION\n>   include::config/rebase.txt[]\n>   include::config/sequencer.txt[]\n>   \n> -BUGS\n> -----\n> -The todo list presented by the deprecated `--preserve-merges --interactive`\n> -does not represent the topology of the revision graph (use `--rebase-merges`\n> -instead).  Editing commits and rewording their commit messages should work\n> -fine, but attempts to reorder commits tend to produce counterintuitive results.\n> -Use `--rebase-merges` in such scenarios instead.\n> -\n> -For example, an attempt to rearrange\n> -------------\n> -1 --- 2 --- 3 --- 4 --- 5\n> -------------\n> -to\n> -------------\n> -1 --- 2 --- 4 --- 3 --- 5\n> -------------\n> -by moving the \"pick 4\" line will result in the following history:\n> -------------\n> -\t3\n> -       /\n> -1 --- 2 --- 4 --- 5\n> -------------\n> -\n>   GIT\n>   ---\n>   Part of the linkgit:git[1] suite\n> diff --git a/Makefile b/Makefile\n> index 9573190f1d7..43f93f61660 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -616,7 +616,6 @@ SCRIPT_SH += git-submodule.sh\n>   SCRIPT_SH += git-web--browse.sh\n>   \n>   SCRIPT_LIB += git-mergetool--lib\n> -SCRIPT_LIB += git-rebase--preserve-merges\n>   SCRIPT_LIB += git-sh-i18n\n>   SCRIPT_LIB += git-sh-setup\n>   \n> @@ -2649,7 +2648,6 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \\\n>   \t--keyword=__ --keyword=N__ --keyword=\"__n:1,2\"\n>   LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)\n>   LOCALIZED_SH = $(SCRIPT_SH)\n> -LOCALIZED_SH += git-rebase--preserve-merges.sh\n>   LOCALIZED_SH += git-sh-setup.sh\n>   LOCALIZED_PERL = $(SCRIPT_PERL)\n>   \n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index 33e09619005..5af6aff9c5e 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, \"rebase-merge\")\n>   enum rebase_type {\n>   \tREBASE_UNSPECIFIED = -1,\n>   \tREBASE_APPLY,\n> -\tREBASE_MERGE,\n> -\tREBASE_PRESERVE_MERGES\n> +\tREBASE_MERGE\n>   };\n>   \n>   enum empty_type {\n> @@ -571,8 +570,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n>   \n>   static int is_merge(struct rebase_options *opts)\n>   {\n> -\treturn opts->type == REBASE_MERGE ||\n> -\t\topts->type == REBASE_PRESERVE_MERGES;\n> +\treturn opts->type == REBASE_MERGE;\n>   }\n>   \n>   static void imply_merge(struct rebase_options *opts, const char *option)\n> @@ -582,7 +580,6 @@ static void imply_merge(struct rebase_options *opts, const char *option)\n>   \t\tdie(_(\"%s requires the merge backend\"), option);\n>   \t\tbreak;\n>   \tcase REBASE_MERGE:\n> -\tcase REBASE_PRESERVE_MERGES:\n>   \t\tbreak;\n>   \tdefault:\n>   \t\topts->type = REBASE_MERGE; /* implied */\n> @@ -773,17 +770,6 @@ static struct commit *peel_committish(const char *name)\n>   \treturn (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);\n>   }\n>   \n> -static void add_var(struct strbuf *buf, const char *name, const char *value)\n> -{\n> -\tif (!value)\n> -\t\tstrbuf_addf(buf, \"unset %s; \", name);\n> -\telse {\n> -\t\tstrbuf_addf(buf, \"%s=\", name);\n> -\t\tsq_quote_buf(buf, value);\n> -\t\tstrbuf_addstr(buf, \"; \");\n> -\t}\n> -}\n> -\n>   static int move_to_original_branch(struct rebase_options *opts)\n>   {\n>   \tstruct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;\n> @@ -940,10 +926,8 @@ static int run_am(struct rebase_options *opts)\n>   \n>   static int run_specific_rebase(struct rebase_options *opts, enum action action)\n>   {\n> -\tconst char *argv[] = { NULL, NULL };\n> -\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n> +\tstruct strbuf script_snippet = STRBUF_INIT;\n>   \tint status;\n> -\tconst char *backend, *backend_func;\n>   \n>   \tif (opts->type == REBASE_MERGE) {\n>   \t\t/* Run sequencer-based rebase */\n> @@ -960,87 +944,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n>   \t\t}\n>   \n>   \t\tstatus = run_sequencer_rebase(opts, action);\n> -\t\tgoto finished_rebase;\n> -\t}\n> -\n> -\tif (opts->type == REBASE_APPLY) {\n> +\t} else if (opts->type == REBASE_APPLY)\n>   \t\tstatus = run_am(opts);\n> -\t\tgoto finished_rebase;\n> -\t}\n> -\n> -\tadd_var(&script_snippet, \"GIT_DIR\", absolute_path(get_git_dir()));\n> -\tadd_var(&script_snippet, \"state_dir\", opts->state_dir);\n> -\n> -\tadd_var(&script_snippet, \"upstream_name\", opts->upstream_name);\n> -\tadd_var(&script_snippet, \"upstream\", opts->upstream ?\n> -\t\toid_to_hex(&opts->upstream->object.oid) : NULL);\n> -\tadd_var(&script_snippet, \"head_name\",\n> -\t\topts->head_name ? opts->head_name : \"detached HEAD\");\n> -\tadd_var(&script_snippet, \"orig_head\", oid_to_hex(&opts->orig_head));\n> -\tadd_var(&script_snippet, \"onto\", opts->onto ?\n> -\t\toid_to_hex(&opts->onto->object.oid) : NULL);\n> -\tadd_var(&script_snippet, \"onto_name\", opts->onto_name);\n> -\tadd_var(&script_snippet, \"revisions\", opts->revisions);\n> -\tadd_var(&script_snippet, \"restrict_revision\", opts->restrict_revision ?\n> -\t\toid_to_hex(&opts->restrict_revision->object.oid) : NULL);\n> -\tsq_quote_argv_pretty(&buf, opts->git_am_opts.v);\n> -\tadd_var(&script_snippet, \"git_am_opt\", buf.buf);\n> -\tstrbuf_release(&buf);\n> -\tadd_var(&script_snippet, \"verbose\",\n> -\t\topts->flags & REBASE_VERBOSE ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"diffstat\",\n> -\t\topts->flags & REBASE_DIFFSTAT ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"force_rebase\",\n> -\t\topts->flags & REBASE_FORCE ? \"t\" : \"\");\n> -\tif (opts->switch_to)\n> -\t\tadd_var(&script_snippet, \"switch_to\", opts->switch_to);\n> -\tadd_var(&script_snippet, \"action\", opts->action ? opts->action : \"\");\n> -\tadd_var(&script_snippet, \"signoff\", opts->signoff ? \"--signoff\" : \"\");\n> -\tadd_var(&script_snippet, \"allow_rerere_autoupdate\",\n> -\t\topts->allow_rerere_autoupdate ?\n> -\t\t\topts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?\n> -\t\t\t\"--rerere-autoupdate\" : \"--no-rerere-autoupdate\" : \"\");\n> -\tadd_var(&script_snippet, \"keep_empty\", opts->keep_empty ? \"yes\" : \"\");\n> -\tadd_var(&script_snippet, \"autosquash\", opts->autosquash ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"gpg_sign_opt\", opts->gpg_sign_opt);\n> -\tadd_var(&script_snippet, \"cmd\", opts->cmd);\n> -\tadd_var(&script_snippet, \"allow_empty_message\",\n> -\t\topts->allow_empty_message ?  \"--allow-empty-message\" : \"\");\n> -\tadd_var(&script_snippet, \"rebase_merges\",\n> -\t\topts->rebase_merges ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"rebase_cousins\",\n> -\t\topts->rebase_cousins ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"strategy\", opts->strategy);\n> -\tadd_var(&script_snippet, \"strategy_opts\", opts->strategy_opts);\n> -\tadd_var(&script_snippet, \"rebase_root\", opts->root ? \"t\" : \"\");\n> -\tadd_var(&script_snippet, \"squash_onto\",\n> -\t\topts->squash_onto ? oid_to_hex(opts->squash_onto) : \"\");\n> -\tadd_var(&script_snippet, \"git_format_patch_opt\",\n> -\t\topts->git_format_patch_opt.buf);\n> -\n> -\tif (is_merge(opts) &&\n> -\t    !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n> -\t\tstrbuf_addstr(&script_snippet,\n> -\t\t\t      \"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; \");\n> -\t\topts->autosquash = 0;\n> -\t}\n> -\n> -\tswitch (opts->type) {\n> -\tcase REBASE_PRESERVE_MERGES:\n> -\t\tbackend = \"git-rebase--preserve-merges\";\n> -\t\tbackend_func = \"git_rebase__preserve_merges\";\n> -\t\tbreak;\n> -\tdefault:\n> +\telse\n>   \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n> -\t\tbreak;\n> -\t}\n>   \n> -\tstrbuf_addf(&script_snippet,\n> -\t\t    \". git-sh-setup && . %s && %s\", backend, backend_func);\n> -\targv[0] = script_snippet.buf;\n> -\n> -\tstatus = run_command_v_opt(argv, RUN_USING_SHELL);\n> -finished_rebase:\n>   \tif (opts->dont_finish_rebase)\n>   \t\t; /* do nothing */\n>   \telse if (opts->type == REBASE_MERGE)\n> @@ -1377,10 +1285,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n>   \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n>   \t\t\tparse_opt_interactive),\n> -\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n> -\t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n> -\t\t\t\t \"ignoring them\"),\n> -\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n>   \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n>   \t\tOPT_CALLBACK_F(0, \"empty\", &options, \"{drop,keep,ask}\",\n>   \t\t\t       N_(\"how to handle commits that become empty\"),\n> @@ -1448,8 +1352,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\tstrbuf_reset(&buf);\n>   \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n>   \t\tif (is_directory(buf.buf)) {\n> -\t\t\toptions.type = REBASE_PRESERVE_MERGES;\n> -\t\t\toptions.flags |= REBASE_INTERACTIVE_EXPLICIT;\n> +\t\t\tdie(\"`rebase -p` is no longer supported\");\n>   \t\t} else {\n>   \t\t\tstrbuf_reset(&buf);\n>   \t\t\tstrbuf_addf(&buf, \"%s/interactive\", merge_dir());\n> @@ -1479,10 +1382,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\tusage_with_options(builtin_rebase_usage,\n>   \t\t\t\t   builtin_rebase_options);\n>   \n> -\tif (options.type == REBASE_PRESERVE_MERGES)\n> -\t\twarning(_(\"git rebase --preserve-merges is deprecated. \"\n> -\t\t\t  \"Use --rebase-merges instead.\"));\n> -\n>   \tif (keep_base) {\n>   \t\tif (options.onto_name)\n>   \t\t\tdie(_(\"cannot combine '--keep-base' with '--onto'\"));\n> @@ -1728,7 +1627,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\tcase REBASE_APPLY:\n>   \t\t\tdie(_(\"--strategy requires --merge or --interactive\"));\n>   \t\tcase REBASE_MERGE:\n> -\t\tcase REBASE_PRESERVE_MERGES:\n>   \t\t\t/* compatible */\n>   \t\t\tbreak;\n>   \t\tcase REBASE_UNSPECIFIED:\n> @@ -1780,7 +1678,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \n>   \tswitch (options.type) {\n>   \tcase REBASE_MERGE:\n> -\tcase REBASE_PRESERVE_MERGES:\n>   \t\toptions.state_dir = merge_dir();\n>   \t\tbreak;\n>   \tcase REBASE_APPLY:\n> @@ -1805,28 +1702,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n>   \t\toptions.reschedule_failed_exec = reschedule_failed_exec;\n>   \n>   \tif (options.signoff) {\n> -\t\tif (options.type == REBASE_PRESERVE_MERGES)\n> -\t\t\tdie(\"cannot combine '--signoff' with \"\n> -\t\t\t    \"'--preserve-merges'\");\n>   \t\tstrvec_push(&options.git_am_opts, \"--signoff\");\n>   \t\toptions.flags |= REBASE_FORCE;\n>   \t}\n>   \n> -\tif (options.type == REBASE_PRESERVE_MERGES) {\n> -\t\t/*\n> -\t\t * Note: incompatibility with --signoff handled in signoff block above\n> -\t\t * Note: incompatibility with --interactive is just a strong warning;\n> -\t\t *       git-rebase.txt caveats with \"unless you know what you are doing\"\n> -\t\t */\n> -\t\tif (options.rebase_merges)\n> -\t\t\tdie(_(\"cannot combine '--preserve-merges' with \"\n> -\t\t\t      \"'--rebase-merges'\"));\n> -\n> -\t\tif (options.reschedule_failed_exec)\n> -\t\t\tdie(_(\"error: cannot combine '--preserve-merges' with \"\n> -\t\t\t      \"'--reschedule-failed-exec'\"));\n> -\t}\n> -\n>   \tif (!options.root) {\n>   \t\tif (argc < 1) {\n>   \t\t\tstruct branch *branch;\n> diff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh\n> deleted file mode 100644\n> index b9c71d2a71b..00000000000\n> --- a/git-rebase--preserve-merges.sh\n> +++ /dev/null\n> @@ -1,1057 +0,0 @@\n> -# This shell script fragment is sourced by git-rebase to implement its\n> -# preserve-merges mode.\n> -#\n> -# Copyright (c) 2006 Johannes E. Schindelin\n> -#\n> -# The file containing rebase commands, comments, and empty lines.\n> -# This file is created by \"git rebase -i\" then edited by the user.  As\n> -# the lines are processed, they are removed from the front of this\n> -# file and written to the tail of $done.\n> -todo=\"$state_dir\"/git-rebase-todo\n> -\n> -# The rebase command lines that have already been processed.  A line\n> -# is moved here when it is first handled, before any associated user\n> -# actions.\n> -done=\"$state_dir\"/done\n> -\n> -# The commit message that is planned to be used for any changes that\n> -# need to be committed following a user interaction.\n> -msg=\"$state_dir\"/message\n> -\n> -# The file into which is accumulated the suggested commit message for\n> -# squash/fixup commands.  When the first of a series of squash/fixups\n> -# is seen, the file is created and the commit message from the\n> -# previous commit and from the first squash/fixup commit are written\n> -# to it.  The commit message for each subsequent squash/fixup commit\n> -# is appended to the file as it is processed.\n> -#\n> -# The first line of the file is of the form\n> -#     # This is a combination of $count commits.\n> -# where $count is the number of commits whose messages have been\n> -# written to the file so far (including the initial \"pick\" commit).\n> -# Each time that a commit message is processed, this line is read and\n> -# updated.  It is deleted just before the combined commit is made.\n> -squash_msg=\"$state_dir\"/message-squash\n> -\n> -# If the current series of squash/fixups has not yet included a squash\n> -# command, then this file exists and holds the commit message of the\n> -# original \"pick\" commit.  (If the series ends without a \"squash\"\n> -# command, then this can be used as the commit message of the combined\n> -# commit without opening the editor.)\n> -fixup_msg=\"$state_dir\"/message-fixup\n> -\n> -# $rewritten is the name of a directory containing files for each\n> -# commit that is reachable by at least one merge base of $head and\n> -# $upstream. They are not necessarily rewritten, but their children\n> -# might be.  This ensures that commits on merged, but otherwise\n> -# unrelated side branches are left alone. (Think \"X\" in the man page's\n> -# example.)\n> -rewritten=\"$state_dir\"/rewritten\n> -\n> -dropped=\"$state_dir\"/dropped\n> -\n> -end=\"$state_dir\"/end\n> -msgnum=\"$state_dir\"/msgnum\n> -\n> -# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n> -# GIT_AUTHOR_DATE that will be used for the commit that is currently\n> -# being rebased.\n> -author_script=\"$state_dir\"/author-script\n> -\n> -# When an \"edit\" rebase command is being processed, the SHA1 of the\n> -# commit to be edited is recorded in this file.  When \"git rebase\n> -# --continue\" is executed, if there are any staged changes then they\n> -# will be amended to the HEAD commit, but only provided the HEAD\n> -# commit is still the commit to be edited.  When any other rebase\n> -# command is processed, this file is deleted.\n> -amend=\"$state_dir\"/amend\n> -\n> -# For the post-rewrite hook, we make a list of rewritten commits and\n> -# their new sha1s.  The rewritten-pending list keeps the sha1s of\n> -# commits that have been processed, but not committed yet,\n> -# e.g. because they are waiting for a 'squash' command.\n> -rewritten_list=\"$state_dir\"/rewritten-list\n> -rewritten_pending=\"$state_dir\"/rewritten-pending\n> -\n> -# Work around Git for Windows' Bash whose \"read\" does not strip CRLF\n> -# and leaves CR at the end instead.\n> -cr=$(printf \"\\015\")\n> -\n> -resolvemsg=\"\n> -$(gettext 'Resolve all conflicts manually, mark them as resolved with\n> -\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n> -You can instead skip this commit: run \"git rebase --skip\".\n> -To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".')\n> -\"\n> -\n> -write_basic_state () {\n> -\techo \"$head_name\" > \"$state_dir\"/head-name &&\n> -\techo \"$onto\" > \"$state_dir\"/onto &&\n> -\techo \"$orig_head\" > \"$state_dir\"/orig-head &&\n> -\ttest t = \"$GIT_QUIET\" && : > \"$state_dir\"/quiet\n> -\ttest t = \"$verbose\" && : > \"$state_dir\"/verbose\n> -\ttest -n \"$strategy\" && echo \"$strategy\" > \"$state_dir\"/strategy\n> -\ttest -n \"$strategy_opts\" && echo \"$strategy_opts\" > \\\n> -\t\t\"$state_dir\"/strategy_opts\n> -\ttest -n \"$allow_rerere_autoupdate\" && echo \"$allow_rerere_autoupdate\" > \\\n> -\t\t\"$state_dir\"/allow_rerere_autoupdate\n> -\ttest -n \"$gpg_sign_opt\" && echo \"$gpg_sign_opt\" > \"$state_dir\"/gpg_sign_opt\n> -\ttest -n \"$signoff\" && echo \"$signoff\" >\"$state_dir\"/signoff\n> -\ttest -n \"$reschedule_failed_exec\" && : > \"$state_dir\"/reschedule-failed-exec\n> -}\n> -\n> -apply_autostash () {\n> -\tif test -f \"$state_dir/autostash\"\n> -\tthen\n> -\t\tstash_sha1=$(cat \"$state_dir/autostash\")\n> -\t\tif git stash apply $stash_sha1 >/dev/null 2>&1\n> -\t\tthen\n> -\t\t\techo \"$(gettext 'Applied autostash.')\" >&2\n> -\t\telse\n> -\t\t\tgit stash store -m \"autostash\" -q $stash_sha1 ||\n> -\t\t\tdie \"$(eval_gettext \"Cannot store \\$stash_sha1\")\"\n> -\t\t\tgettext 'Applying autostash resulted in conflicts.\n> -Your changes are safe in the stash.\n> -You can run \"git stash pop\" or \"git stash drop\" at any time.\n> -' >&2\n> -\t\tfi\n> -\tfi\n> -}\n> -\n> -output () {\n> -\tcase \"$verbose\" in\n> -\t'')\n> -\t\toutput=$(\"$@\" 2>&1 )\n> -\t\tstatus=$?\n> -\t\ttest $status != 0 && printf \"%s\\n\" \"$output\"\n> -\t\treturn $status\n> -\t\t;;\n> -\t*)\n> -\t\t\"$@\"\n> -\t\t;;\n> -\tesac\n> -}\n> -\n> -strategy_args=${strategy:+--strategy=$strategy}\n> -test -n \"$strategy_opts\" &&\n> -eval '\n> -\tfor strategy_opt in '\"$strategy_opts\"'\n> -\tdo\n> -\t\tstrategy_args=\"$strategy_args -X$(git rev-parse --sq-quote \"${strategy_opt#--}\")\"\n> -\tdone\n> -'\n> -\n> -GIT_CHERRY_PICK_HELP=\"$resolvemsg\"\n> -export GIT_CHERRY_PICK_HELP\n> -\n> -comment_char=$(git config --get core.commentchar 2>/dev/null)\n> -case \"$comment_char\" in\n> -'' | auto)\n> -\tcomment_char=\"#\"\n> -\t;;\n> -?)\n> -\t;;\n> -*)\n> -\tcomment_char=$(echo \"$comment_char\" | cut -c1)\n> -\t;;\n> -esac\n> -\n> -warn () {\n> -\tprintf '%s\\n' \"$*\" >&2\n> -}\n> -\n> -# Output the commit message for the specified commit.\n> -commit_message () {\n> -\tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n> -}\n> -\n> -orig_reflog_action=\"$GIT_REFLOG_ACTION\"\n> -\n> -comment_for_reflog () {\n> -\tcase \"$orig_reflog_action\" in\n> -\t''|rebase*)\n> -\t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n> -\t\texport GIT_REFLOG_ACTION\n> -\t\t;;\n> -\tesac\n> -}\n> -\n> -last_count=\n> -mark_action_done () {\n> -\tsed -e 1q < \"$todo\" >> \"$done\"\n> -\tsed -e 1d < \"$todo\" >> \"$todo\".new\n> -\tmv -f \"$todo\".new \"$todo\"\n> -\tnew_count=$(( $(git stripspace --strip-comments <\"$done\" | wc -l) ))\n> -\techo $new_count >\"$msgnum\"\n> -\ttotal=$(($new_count + $(git stripspace --strip-comments <\"$todo\" | wc -l)))\n> -\techo $total >\"$end\"\n> -\tif test \"$last_count\" != \"$new_count\"\n> -\tthen\n> -\t\tlast_count=$new_count\n> -\t\teval_gettext \"Rebasing (\\$new_count/\\$total)\"; printf \"\\r\"\n> -\t\ttest -z \"$verbose\" || echo\n> -\tfi\n> -}\n> -\n> -append_todo_help () {\n> -\tgettext \"\n> -Commands:\n> -p, pick <commit> = use commit\n> -r, reword <commit> = use commit, but edit the commit message\n> -e, edit <commit> = use commit, but stop for amending\n> -s, squash <commit> = use commit, but meld into previous commit\n> -f, fixup <commit> = like \\\"squash\\\", but discard this commit's log message\n> -x, exec <commit> = run command (the rest of the line) using shell\n> -d, drop <commit> = remove commit\n> -l, label <label> = label current HEAD with a name\n> -t, reset <label> = reset HEAD to a label\n> -m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n> -.       create a merge commit using the original merge commit's\n> -.       message (or the oneline, if no original merge commit was\n> -.       specified). Use -c <commit> to reword the commit message.\n> -\n> -These lines can be re-ordered; they are executed from top to bottom.\n> -\" | git stripspace --comment-lines >>\"$todo\"\n> -\n> -\tif test $(get_missing_commit_check_level) = error\n> -\tthen\n> -\t\tgettext \"\n> -Do not remove any line. Use 'drop' explicitly to remove a commit.\n> -\" | git stripspace --comment-lines >>\"$todo\"\n> -\telse\n> -\t\tgettext \"\n> -If you remove a line here THAT COMMIT WILL BE LOST.\n> -\" | git stripspace --comment-lines >>\"$todo\"\n> -\tfi\n> -}\n> -\n> -make_patch () {\n> -\tsha1_and_parents=\"$(git rev-list --parents -1 \"$1\")\"\n> -\tcase \"$sha1_and_parents\" in\n> -\t?*' '?*' '?*)\n> -\t\tgit diff --cc $sha1_and_parents\n> -\t\t;;\n> -\t?*' '?*)\n> -\t\tgit diff-tree -p \"$1^!\"\n> -\t\t;;\n> -\t*)\n> -\t\techo \"Root commit\"\n> -\t\t;;\n> -\tesac > \"$state_dir\"/patch\n> -\ttest -f \"$msg\" ||\n> -\t\tcommit_message \"$1\" > \"$msg\"\n> -\ttest -f \"$author_script\" ||\n> -\t\tget_author_ident_from_commit \"$1\" > \"$author_script\"\n> -}\n> -\n> -die_with_patch () {\n> -\techo \"$1\" > \"$state_dir\"/stopped-sha\n> -\tgit update-ref REBASE_HEAD \"$1\"\n> -\tmake_patch \"$1\"\n> -\tdie \"$2\"\n> -}\n> -\n> -exit_with_patch () {\n> -\techo \"$1\" > \"$state_dir\"/stopped-sha\n> -\tgit update-ref REBASE_HEAD \"$1\"\n> -\tmake_patch $1\n> -\tgit rev-parse --verify HEAD > \"$amend\"\n> -\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n> -\twarn \"$(eval_gettext \"\\\n> -You can amend the commit now, with\n> -\n> -\tgit commit --amend \\$gpg_sign_opt_quoted\n> -\n> -Once you are satisfied with your changes, run\n> -\n> -\tgit rebase --continue\")\"\n> -\twarn\n> -\texit $2\n> -}\n> -\n> -die_abort () {\n> -\tapply_autostash\n> -\trm -rf \"$state_dir\"\n> -\tdie \"$1\"\n> -}\n> -\n> -has_action () {\n> -\ttest -n \"$(git stripspace --strip-comments <\"$1\")\"\n> -}\n> -\n> -is_empty_commit() {\n> -\ttree=$(git rev-parse -q --verify \"$1\"^{tree} 2>/dev/null) || {\n> -\t\tsha1=$1\n> -\t\tdie \"$(eval_gettext \"\\$sha1: not a commit that can be picked\")\"\n> -\t}\n> -\tptree=$(git rev-parse -q --verify \"$1\"^^{tree} 2>/dev/null) ||\n> -\t\tptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904\n> -\ttest \"$tree\" = \"$ptree\"\n> -}\n> -\n> -is_merge_commit()\n> -{\n> -\tgit rev-parse --verify --quiet \"$1\"^2 >/dev/null 2>&1\n> -}\n> -\n> -# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n> -# GIT_AUTHOR_DATE exported from the current environment.\n> -do_with_author () {\n> -\t(\n> -\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE\n> -\t\t\"$@\"\n> -\t)\n> -}\n> -\n> -git_sequence_editor () {\n> -\tif test -z \"$GIT_SEQUENCE_EDITOR\"\n> -\tthen\n> -\t\tGIT_SEQUENCE_EDITOR=\"$(git config sequence.editor)\"\n> -\t\tif [ -z \"$GIT_SEQUENCE_EDITOR\" ]\n> -\t\tthen\n> -\t\t\tGIT_SEQUENCE_EDITOR=\"$(git var GIT_EDITOR)\" || return $?\n> -\t\tfi\n> -\tfi\n> -\n> -\teval \"$GIT_SEQUENCE_EDITOR\" '\"$@\"'\n> -}\n> -\n> -pick_one () {\n> -\tff=--ff\n> -\n> -\tcase \"$1\" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac\n> -\tcase \"$force_rebase\" in '') ;; ?*) ff= ;; esac\n> -\toutput git rev-parse --verify $sha1 || die \"$(eval_gettext \"Invalid commit name: \\$sha1\")\"\n> -\n> -\tif is_empty_commit \"$sha1\"\n> -\tthen\n> -\t\tempty_args=\"--allow-empty\"\n> -\tfi\n> -\n> -\tpick_one_preserving_merges \"$@\"\n> -}\n> -\n> -pick_one_preserving_merges () {\n> -\tfast_forward=t\n> -\tcase \"$1\" in\n> -\t-n)\n> -\t\tfast_forward=f\n> -\t\tsha1=$2\n> -\t\t;;\n> -\t*)\n> -\t\tsha1=$1\n> -\t\t;;\n> -\tesac\n> -\tsha1=$(git rev-parse $sha1)\n> -\n> -\tif test -f \"$state_dir\"/current-commit && test \"$fast_forward\" = t\n> -\tthen\n> -\t\twhile read current_commit\n> -\t\tdo\n> -\t\t\tgit rev-parse HEAD > \"$rewritten\"/$current_commit\n> -\t\tdone <\"$state_dir\"/current-commit\n> -\t\trm \"$state_dir\"/current-commit ||\n> -\t\t\tdie \"$(gettext \"Cannot write current commit's replacement sha1\")\"\n> -\tfi\n> -\n> -\techo $sha1 >> \"$state_dir\"/current-commit\n> -\n> -\t# rewrite parents; if none were rewritten, we can fast-forward.\n> -\tnew_parents=\n> -\tpend=\" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\"\n> -\tif test \"$pend\" = \" \"\n> -\tthen\n> -\t\tpend=\" root\"\n> -\tfi\n> -\twhile [ \"$pend\" != \"\" ]\n> -\tdo\n> -\t\tp=$(expr \"$pend\" : ' \\([^ ]*\\)')\n> -\t\tpend=\"${pend# $p}\"\n> -\n> -\t\tif test -f \"$rewritten\"/$p\n> -\t\tthen\n> -\t\t\tnew_p=$(cat \"$rewritten\"/$p)\n> -\n> -\t\t\t# If the todo reordered commits, and our parent is marked for\n> -\t\t\t# rewriting, but hasn't been gotten to yet, assume the user meant to\n> -\t\t\t# drop it on top of the current HEAD\n> -\t\t\tif test -z \"$new_p\"\n> -\t\t\tthen\n> -\t\t\t\tnew_p=$(git rev-parse HEAD)\n> -\t\t\tfi\n> -\n> -\t\t\ttest $p != $new_p && fast_forward=f\n> -\t\t\tcase \"$new_parents\" in\n> -\t\t\t*$new_p*)\n> -\t\t\t\t;; # do nothing; that parent is already there\n> -\t\t\t*)\n> -\t\t\t\tnew_parents=\"$new_parents $new_p\"\n> -\t\t\t\t;;\n> -\t\t\tesac\n> -\t\telse\n> -\t\t\tif test -f \"$dropped\"/$p\n> -\t\t\tthen\n> -\t\t\t\tfast_forward=f\n> -\t\t\t\treplacement=\"$(cat \"$dropped\"/$p)\"\n> -\t\t\t\ttest -z \"$replacement\" && replacement=root\n> -\t\t\t\tpend=\" $replacement$pend\"\n> -\t\t\telse\n> -\t\t\t\tnew_parents=\"$new_parents $p\"\n> -\t\t\tfi\n> -\t\tfi\n> -\tdone\n> -\tcase $fast_forward in\n> -\tt)\n> -\t\toutput warn \"$(eval_gettext \"Fast-forward to \\$sha1\")\"\n> -\t\toutput git reset --hard $sha1 ||\n> -\t\t\tdie \"$(eval_gettext \"Cannot fast-forward to \\$sha1\")\"\n> -\t\t;;\n> -\tf)\n> -\t\tfirst_parent=$(expr \"$new_parents\" : ' \\([^ ]*\\)')\n> -\n> -\t\tif [ \"$1\" != \"-n\" ]\n> -\t\tthen\n> -\t\t\t# detach HEAD to current parent\n> -\t\t\toutput git checkout $first_parent 2> /dev/null ||\n> -\t\t\t\tdie \"$(eval_gettext \"Cannot move HEAD to \\$first_parent\")\"\n> -\t\tfi\n> -\n> -\t\tcase \"$new_parents\" in\n> -\t\t' '*' '*)\n> -\t\t\ttest \"a$1\" = a-n && die \"$(eval_gettext \"Refusing to squash a merge: \\$sha1\")\"\n> -\n> -\t\t\t# redo merge\n> -\t\t\tauthor_script_content=$(get_author_ident_from_commit $sha1)\n> -\t\t\teval \"$author_script_content\"\n> -\t\t\tmsg_content=\"$(commit_message $sha1)\"\n> -\t\t\t# No point in merging the first parent, that's HEAD\n> -\t\t\tnew_parents=${new_parents# $first_parent}\n> -\t\t\tmerge_args=\"--no-log --no-ff\"\n> -\t\t\tif ! do_with_author output eval \\\n> -\t\t\t\tgit merge ${gpg_sign_opt:+$(git rev-parse \\\n> -\t\t\t\t\t--sq-quote \"$gpg_sign_opt\")} \\\n> -\t\t\t\t$allow_rerere_autoupdate \"$merge_args\" \\\n> -\t\t\t\t\"$strategy_args\" \\\n> -\t\t\t\t-m \"$(git rev-parse --sq-quote \"$msg_content\")\" \\\n> -\t\t\t\t\"$new_parents\"\n> -\t\t\tthen\n> -\t\t\t\tprintf \"%s\\n\" \"$msg_content\" > \"$GIT_DIR\"/MERGE_MSG\n> -\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Error redoing merge \\$sha1\")\"\n> -\t\t\tfi\n> -\t\t\techo \"$sha1 $(git rev-parse HEAD^0)\" >> \"$rewritten_list\"\n> -\t\t\t;;\n> -\t\t*)\n> -\t\t\toutput eval git cherry-pick $allow_rerere_autoupdate \\\n> -\t\t\t\t$allow_empty_message \\\n> -\t\t\t\t${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")} \\\n> -\t\t\t\t\"$strategy_args\" \"$@\" ||\n> -\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not pick \\$sha1\")\"\n> -\t\t\t;;\n> -\t\tesac\n> -\t\t;;\n> -\tesac\n> -}\n> -\n> -this_nth_commit_message () {\n> -\tn=$1\n> -\teval_gettext \"This is the commit message #\\${n}:\"\n> -}\n> -\n> -skip_nth_commit_message () {\n> -\tn=$1\n> -\teval_gettext \"The commit message #\\${n} will be skipped:\"\n> -}\n> -\n> -update_squash_messages () {\n> -\tif test -f \"$squash_msg\"; then\n> -\t\tmv \"$squash_msg\" \"$squash_msg\".bak || exit\n> -\t\tcount=$(($(sed -n \\\n> -\t\t\t-e \"1s/^$comment_char[^0-9]*\\([0-9][0-9]*\\).*/\\1/p\" \\\n> -\t\t\t-e \"q\" < \"$squash_msg\".bak)+1))\n> -\t\t{\n> -\t\t\tprintf '%s\\n' \"$comment_char $(eval_ngettext \\\n> -\t\t\t\t\"This is a combination of \\$count commit.\" \\\n> -\t\t\t\t\"This is a combination of \\$count commits.\" \\\n> -\t\t\t\t$count)\"\n> -\t\t\tsed -e 1d -e '2,/^./{\n> -\t\t\t\t/^$/d\n> -\t\t\t}' <\"$squash_msg\".bak\n> -\t\t} >\"$squash_msg\"\n> -\telse\n> -\t\tcommit_message HEAD >\"$fixup_msg\" ||\n> -\t\tdie \"$(eval_gettext \"Cannot write \\$fixup_msg\")\"\n> -\t\tcount=2\n> -\t\t{\n> -\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is a combination of 2 commits.\")\"\n> -\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is the 1st commit message:\")\"\n> -\t\t\techo\n> -\t\t\tcat \"$fixup_msg\"\n> -\t\t} >\"$squash_msg\"\n> -\tfi\n> -\tcase $1 in\n> -\tsquash)\n> -\t\trm -f \"$fixup_msg\"\n> -\t\techo\n> -\t\tprintf '%s\\n' \"$comment_char $(this_nth_commit_message $count)\"\n> -\t\techo\n> -\t\tcommit_message $2\n> -\t\t;;\n> -\tfixup)\n> -\t\techo\n> -\t\tprintf '%s\\n' \"$comment_char $(skip_nth_commit_message $count)\"\n> -\t\techo\n> -\t\t# Change the space after the comment character to TAB:\n> -\t\tcommit_message $2 | git stripspace --comment-lines | sed -e 's/ /\t/'\n> -\t\t;;\n> -\tesac >>\"$squash_msg\"\n> -}\n> -\n> -peek_next_command () {\n> -\tgit stripspace --strip-comments <\"$todo\" | sed -n -e 's/ .*//p' -e q\n> -}\n> -\n> -# A squash/fixup has failed.  Prepare the long version of the squash\n> -# commit message, then die_with_patch.  This code path requires the\n> -# user to edit the combined commit message for all commits that have\n> -# been squashed/fixedup so far.  So also erase the old squash\n> -# messages, effectively causing the combined commit to be used as the\n> -# new basis for any further squash/fixups.  Args: sha1 rest\n> -die_failed_squash() {\n> -\tsha1=$1\n> -\trest=$2\n> -\tmv \"$squash_msg\" \"$msg\" || exit\n> -\trm -f \"$fixup_msg\"\n> -\tcp \"$msg\" \"$GIT_DIR\"/MERGE_MSG || exit\n> -\twarn\n> -\twarn \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n> -\tdie_with_patch $sha1 \"\"\n> -}\n> -\n> -flush_rewritten_pending() {\n> -\ttest -s \"$rewritten_pending\" || return\n> -\tnewsha1=\"$(git rev-parse HEAD^0)\"\n> -\tsed \"s/$/ $newsha1/\" < \"$rewritten_pending\" >> \"$rewritten_list\"\n> -\trm -f \"$rewritten_pending\"\n> -}\n> -\n> -record_in_rewritten() {\n> -\toldsha1=\"$(git rev-parse $1)\"\n> -\techo \"$oldsha1\" >> \"$rewritten_pending\"\n> -\n> -\tcase \"$(peek_next_command)\" in\n> -\tsquash|s|fixup|f)\n> -\t\t;;\n> -\t*)\n> -\t\tflush_rewritten_pending\n> -\t\t;;\n> -\tesac\n> -}\n> -\n> -do_pick () {\n> -\tsha1=$1\n> -\trest=$2\n> -\tif test \"$(git rev-parse HEAD)\" = \"$squash_onto\"\n> -\tthen\n> -\t\t# Set the correct commit message and author info on the\n> -\t\t# sentinel root before cherry-picking the original changes\n> -\t\t# without committing (-n).  Finally, update the sentinel again\n> -\t\t# to include these changes.  If the cherry-pick results in a\n> -\t\t# conflict, this means our behaviour is similar to a standard\n> -\t\t# failed cherry-pick during rebase, with a dirty index to\n> -\t\t# resolve before manually running git commit --amend then git\n> -\t\t# rebase --continue.\n> -\t\tgit commit --allow-empty --allow-empty-message --amend \\\n> -\t\t\t   --no-post-rewrite -n -q -C $sha1 $signoff &&\n> -\t\t\tpick_one -n $sha1 &&\n> -\t\t\tgit commit --allow-empty --allow-empty-message \\\n> -\t\t\t\t   --amend --no-post-rewrite -n -q -C $sha1 $signoff \\\n> -\t\t\t\t   ${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n> -\t\t\t\t   die_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n> -\telse\n> -\t\tpick_one $sha1 ||\n> -\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n> -\tfi\n> -}\n> -\n> -do_next () {\n> -\trm -f \"$msg\" \"$author_script\" \"$amend\" \"$state_dir\"/stopped-sha || exit\n> -\tread -r command sha1 rest < \"$todo\"\n> -\tcase \"$command\" in\n> -\t\"$comment_char\"*|''|noop|drop|d)\n> -\t\tmark_action_done\n> -\t\t;;\n> -\t\"$cr\")\n> -\t\t# Work around CR left by \"read\" (e.g. with Git for Windows' Bash).\n> -\t\tmark_action_done\n> -\t\t;;\n> -\tpick|p)\n> -\t\tcomment_for_reflog pick\n> -\n> -\t\tmark_action_done\n> -\t\tdo_pick $sha1 \"$rest\"\n> -\t\trecord_in_rewritten $sha1\n> -\t\t;;\n> -\treword|r)\n> -\t\tcomment_for_reflog reword\n> -\n> -\t\tmark_action_done\n> -\t\tdo_pick $sha1 \"$rest\"\n> -\t\tgit commit --amend --no-post-rewrite ${gpg_sign_opt:+\"$gpg_sign_opt\"} \\\n> -\t\t\t$allow_empty_message || {\n> -\t\t\twarn \"$(eval_gettext \"\\\n> -Could not amend commit after successfully picking \\$sha1... \\$rest\n> -This is most likely due to an empty commit message, or the pre-commit hook\n> -failed. If the pre-commit hook failed, you may need to resolve the issue before\n> -you are able to reword the commit.\")\"\n> -\t\t\texit_with_patch $sha1 1\n> -\t\t}\n> -\t\trecord_in_rewritten $sha1\n> -\t\t;;\n> -\tedit|e)\n> -\t\tcomment_for_reflog edit\n> -\n> -\t\tmark_action_done\n> -\t\tdo_pick $sha1 \"$rest\"\n> -\t\tsha1_abbrev=$(git rev-parse --short $sha1)\n> -\t\twarn \"$(eval_gettext \"Stopped at \\$sha1_abbrev... \\$rest\")\"\n> -\t\texit_with_patch $sha1 0\n> -\t\t;;\n> -\tsquash|s|fixup|f)\n> -\t\tcase \"$command\" in\n> -\t\tsquash|s)\n> -\t\t\tsquash_style=squash\n> -\t\t\t;;\n> -\t\tfixup|f)\n> -\t\t\tsquash_style=fixup\n> -\t\t\t;;\n> -\t\tesac\n> -\t\tcomment_for_reflog $squash_style\n> -\n> -\t\ttest -f \"$done\" && has_action \"$done\" ||\n> -\t\t\tdie \"$(eval_gettext \"Cannot '\\$squash_style' without a previous commit\")\"\n> -\n> -\t\tmark_action_done\n> -\t\tupdate_squash_messages $squash_style $sha1\n> -\t\tauthor_script_content=$(get_author_ident_from_commit HEAD)\n> -\t\techo \"$author_script_content\" > \"$author_script\"\n> -\t\teval \"$author_script_content\"\n> -\t\tif ! pick_one -n $sha1\n> -\t\tthen\n> -\t\t\tgit rev-parse --verify HEAD >\"$amend\"\n> -\t\t\tdie_failed_squash $sha1 \"$rest\"\n> -\t\tfi\n> -\t\tcase \"$(peek_next_command)\" in\n> -\t\tsquash|s|fixup|f)\n> -\t\t\t# This is an intermediate commit; its message will only be\n> -\t\t\t# used in case of trouble.  So use the long version:\n> -\t\t\tdo_with_author output git commit --amend --no-verify -F \"$squash_msg\" \\\n> -\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n> -\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n> -\t\t\t;;\n> -\t\t*)\n> -\t\t\t# This is the final command of this squash/fixup group\n> -\t\t\tif test -f \"$fixup_msg\"\n> -\t\t\tthen\n> -\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$fixup_msg\" \\\n> -\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n> -\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n> -\t\t\telse\n> -\t\t\t\tcp \"$squash_msg\" \"$GIT_DIR\"/SQUASH_MSG || exit\n> -\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n> -\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$GIT_DIR\"/SQUASH_MSG -e \\\n> -\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n> -\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n> -\t\t\tfi\n> -\t\t\trm -f \"$squash_msg\" \"$fixup_msg\"\n> -\t\t\t;;\n> -\t\tesac\n> -\t\trecord_in_rewritten $sha1\n> -\t\t;;\n> -\tx|\"exec\")\n> -\t\tread -r command rest < \"$todo\"\n> -\t\tmark_action_done\n> -\t\teval_gettextln \"Executing: \\$rest\"\n> -\t\t\"${SHELL:-@SHELL_PATH@}\" -c \"$rest\" # Actual execution\n> -\t\tstatus=$?\n> -\t\t# Run in subshell because require_clean_work_tree can die.\n> -\t\tdirty=f\n> -\t\t(require_clean_work_tree \"rebase\" 2>/dev/null) || dirty=t\n> -\t\tif test \"$status\" -ne 0\n> -\t\tthen\n> -\t\t\twarn \"$(eval_gettext \"Execution failed: \\$rest\")\"\n> -\t\t\ttest \"$dirty\" = f ||\n> -\t\t\t\twarn \"$(gettext \"and made changes to the index and/or the working tree\")\"\n> -\n> -\t\t\twarn \"$(gettext \"\\\n> -You can fix the problem, and then run\n> -\n> -\tgit rebase --continue\")\"\n> -\t\t\twarn\n> -\t\t\tif test $status -eq 127\t\t# command not found\n> -\t\t\tthen\n> -\t\t\t\tstatus=1\n> -\t\t\tfi\n> -\t\t\texit \"$status\"\n> -\t\telif test \"$dirty\" = t\n> -\t\tthen\n> -\t\t\t# TRANSLATORS: after these lines is a command to be issued by the user\n> -\t\t\twarn \"$(eval_gettext \"\\\n> -Execution succeeded: \\$rest\n> -but left changes to the index and/or the working tree\n> -Commit or stash your changes, and then run\n> -\n> -\tgit rebase --continue\")\"\n> -\t\t\twarn\n> -\t\t\texit 1\n> -\t\tfi\n> -\t\t;;\n> -\t*)\n> -\t\twarn \"$(eval_gettext \"Unknown command: \\$command \\$sha1 \\$rest\")\"\n> -\t\tfixtodo=\"$(gettext \"Please fix this using 'git rebase --edit-todo'.\")\"\n> -\t\tif git rev-parse --verify -q \"$sha1\" >/dev/null\n> -\t\tthen\n> -\t\t\tdie_with_patch $sha1 \"$fixtodo\"\n> -\t\telse\n> -\t\t\tdie \"$fixtodo\"\n> -\t\tfi\n> -\t\t;;\n> -\tesac\n> -\ttest -s \"$todo\" && return\n> -\n> -\tcomment_for_reflog finish &&\n> -\tnewhead=$(git rev-parse HEAD) &&\n> -\tcase $head_name in\n> -\trefs/*)\n> -\t\tmessage=\"$GIT_REFLOG_ACTION: $head_name onto $onto\" &&\n> -\t\tgit update-ref -m \"$message\" $head_name $newhead $orig_head &&\n> -\t\tgit symbolic-ref \\\n> -\t\t  -m \"$GIT_REFLOG_ACTION: returning to $head_name\" \\\n> -\t\t  HEAD $head_name\n> -\t\t;;\n> -\tesac && {\n> -\t\ttest ! -f \"$state_dir\"/verbose ||\n> -\t\t\tgit diff-tree --stat $orig_head..HEAD\n> -\t} &&\n> -\t{\n> -\t\ttest -s \"$rewritten_list\" &&\n> -\t\tgit notes copy --for-rewrite=rebase < \"$rewritten_list\" ||\n> -\t\ttrue # we don't care if this copying failed\n> -\t} &&\n> -\thook=\"$(git rev-parse --git-path hooks/post-rewrite)\"\n> -\tif test -x \"$hook\" && test -s \"$rewritten_list\"; then\n> -\t\t\"$hook\" rebase < \"$rewritten_list\"\n> -\t\ttrue # we don't care if this hook failed\n> -\tfi &&\n> -\t\twarn \"$(eval_gettext \"Successfully rebased and updated \\$head_name.\")\"\n> -\n> -\treturn 1 # not failure; just to break the do_rest loop\n> -}\n> -\n> -# can only return 0, when the infinite loop breaks\n> -do_rest () {\n> -\twhile :\n> -\tdo\n> -\t\tdo_next || break\n> -\tdone\n> -}\n> -\n> -expand_todo_ids() {\n> -\tgit rebase--interactive --expand-ids\n> -}\n> -\n> -collapse_todo_ids() {\n> -\tgit rebase--interactive --shorten-ids\n> -}\n> -\n> -# Switch to the branch in $into and notify it in the reflog\n> -checkout_onto () {\n> -\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $onto_name\"\n> -\toutput git checkout $onto || die_abort \"$(gettext \"could not detach HEAD\")\"\n> -\tgit update-ref ORIG_HEAD $orig_head\n> -}\n> -\n> -get_missing_commit_check_level () {\n> -\tcheck_level=$(git config --get rebase.missingCommitsCheck)\n> -\tcheck_level=${check_level:-ignore}\n> -\t# Don't be case sensitive\n> -\tprintf '%s' \"$check_level\" | tr 'A-Z' 'a-z'\n> -}\n> -\n> -# Initiate an action. If the cannot be any\n> -# further action it  may exec a command\n> -# or exit and not return.\n> -#\n> -# TODO: Consider a cleaner return model so it\n> -# never exits and always return 0 if process\n> -# is complete.\n> -#\n> -# Parameter 1 is the action to initiate.\n> -#\n> -# Returns 0 if the action was able to complete\n> -# and if 1 if further processing is required.\n> -initiate_action () {\n> -\tcase \"$1\" in\n> -\tcontinue)\n> -\t\t# do we have anything to commit?\n> -\t\tif git diff-index --cached --quiet HEAD --\n> -\t\tthen\n> -\t\t\t# Nothing to commit -- skip this commit\n> -\n> -\t\t\ttest ! -f \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n> -\t\t\trm \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n> -\t\t\tdie \"$(gettext \"Could not remove CHERRY_PICK_HEAD\")\"\n> -\t\telse\n> -\t\t\tif ! test -f \"$author_script\"\n> -\t\t\tthen\n> -\t\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n> -\t\t\t\tdie \"$(eval_gettext \"\\\n> -You have staged changes in your working tree.\n> -If these changes are meant to be\n> -squashed into the previous commit, run:\n> -\n> -  git commit --amend \\$gpg_sign_opt_quoted\n> -\n> -If they are meant to go into a new commit, run:\n> -\n> -  git commit \\$gpg_sign_opt_quoted\n> -\n> -In both cases, once you're done, continue with:\n> -\n> -  git rebase --continue\n> -\")\"\n> -\t\t\tfi\n> -\t\t\t. \"$author_script\" ||\n> -\t\t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n> -\t\t\tif test -f \"$amend\"\n> -\t\t\tthen\n> -\t\t\t\tcurrent_head=$(git rev-parse --verify HEAD)\n> -\t\t\t\ttest \"$current_head\" = $(cat \"$amend\") ||\n> -\t\t\t\tdie \"$(gettext \"\\\n> -You have uncommitted changes in your working tree. Please commit them\n> -first and then run 'git rebase --continue' again.\")\"\n> -\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$msg\" -e \\\n> -\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n> -\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n> -\t\t\telse\n> -\t\t\t\tdo_with_author git commit --no-verify -F \"$msg\" -e \\\n> -\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n> -\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n> -\t\t\tfi\n> -\t\tfi\n> -\n> -\t\tif test -r \"$state_dir\"/stopped-sha\n> -\t\tthen\n> -\t\t\trecord_in_rewritten \"$(cat \"$state_dir\"/stopped-sha)\"\n> -\t\tfi\n> -\n> -\t\trequire_clean_work_tree \"rebase\"\n> -\t\tdo_rest\n> -\t\treturn 0\n> -\t\t;;\n> -\tskip)\n> -\t\tgit rerere clear\n> -\t\tdo_rest\n> -\t\treturn 0\n> -\t\t;;\n> -\tedit-todo)\n> -\t\tgit stripspace --strip-comments <\"$todo\" >\"$todo\".new\n> -\t\tmv -f \"$todo\".new \"$todo\"\n> -\t\tcollapse_todo_ids\n> -\t\tappend_todo_help\n> -\t\tgettext \"\n> -You are editing the todo file of an ongoing interactive rebase.\n> -To continue rebase after editing, run:\n> -    git rebase --continue\n> -\n> -\" | git stripspace --comment-lines >>\"$todo\"\n> -\n> -\t\tgit_sequence_editor \"$todo\" ||\n> -\t\t\tdie \"$(gettext \"Could not execute editor\")\"\n> -\t\texpand_todo_ids\n> -\n> -\t\texit\n> -\t\t;;\n> -\tshow-current-patch)\n> -\t\texec git show REBASE_HEAD --\n> -\t\t;;\n> -\t*)\n> -\t\treturn 1 # continue\n> -\t\t;;\n> -\tesac\n> -}\n> -\n> -setup_reflog_action () {\n> -\tcomment_for_reflog start\n> -\n> -\tif test ! -z \"$switch_to\"\n> -\tthen\n> -\t\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $switch_to\"\n> -\t\toutput git checkout \"$switch_to\" -- ||\n> -\t\t\tdie \"$(eval_gettext \"Could not checkout \\$switch_to\")\"\n> -\n> -\t\tcomment_for_reflog start\n> -\tfi\n> -}\n> -\n> -init_basic_state () {\n> -\torig_head=$(git rev-parse --verify HEAD) || die \"$(gettext \"No HEAD?\")\"\n> -\tmkdir -p \"$state_dir\" || die \"$(eval_gettext \"Could not create temporary \\$state_dir\")\"\n> -\trm -f \"$(git rev-parse --git-path REBASE_HEAD)\"\n> -\n> -\t: > \"$state_dir\"/interactive || die \"$(gettext \"Could not mark as interactive\")\"\n> -\twrite_basic_state\n> -}\n> -\n> -init_revisions_and_shortrevisions () {\n> -\tshorthead=$(git rev-parse --short $orig_head)\n> -\tshortonto=$(git rev-parse --short $onto)\n> -\tif test -z \"$rebase_root\"\n> -\t\t# this is now equivalent to ! -z \"$upstream\"\n> -\tthen\n> -\t\tshortupstream=$(git rev-parse --short $upstream)\n> -\t\trevisions=$upstream...$orig_head\n> -\t\tshortrevisions=$shortupstream..$shorthead\n> -\telse\n> -\t\trevisions=$onto...$orig_head\n> -\t\tshortrevisions=$shorthead\n> -\t\ttest -z \"$squash_onto\" ||\n> -\t\techo \"$squash_onto\" >\"$state_dir\"/squash-onto\n> -\tfi\n> -}\n> -\n> -complete_action() {\n> -\ttest -s \"$todo\" || echo noop >> \"$todo\"\n> -\ttest -z \"$autosquash\" || git rebase--interactive --rearrange-squash || exit\n> -\ttest -n \"$cmd\" && git rebase--interactive --add-exec-commands --cmd \"$cmd\"\n> -\n> -\ttodocount=$(git stripspace --strip-comments <\"$todo\" | wc -l)\n> -\ttodocount=${todocount##* }\n> -\n> -cat >>\"$todo\" <<EOF\n> -\n> -$comment_char $(eval_ngettext \\\n> -\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount command)\" \\\n> -\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount commands)\" \\\n> -\t\"$todocount\")\n> -EOF\n> -\tappend_todo_help\n> -\tgettext \"\n> -However, if you remove everything, the rebase will be aborted.\n> -\n> -\" | git stripspace --comment-lines >>\"$todo\"\n> -\n> -\tif test -z \"$keep_empty\"\n> -\tthen\n> -\t\tprintf '%s\\n' \"$comment_char $(gettext \"Note that empty commits are commented out\")\" >>\"$todo\"\n> -\tfi\n> -\n> -\n> -\thas_action \"$todo\" ||\n> -\t\treturn 2\n> -\n> -\tcp \"$todo\" \"$todo\".backup\n> -\tcollapse_todo_ids\n> -\tgit_sequence_editor \"$todo\" ||\n> -\t\tdie_abort \"$(gettext \"Could not execute editor\")\"\n> -\n> -\thas_action \"$todo\" ||\n> -\t\treturn 2\n> -\n> -\tgit rebase--interactive --check-todo-list || {\n> -\t\tret=$?\n> -\t\tcheckout_onto\n> -\t\texit $ret\n> -\t}\n> -\n> -\texpand_todo_ids\n> -\tcheckout_onto\n> -\tdo_rest\n> -}\n> -\n> -git_rebase__preserve_merges () {\n> -\tinitiate_action \"$action\"\n> -\tret=$?\n> -\tif test $ret = 0; then\n> -\t\treturn 0\n> -\tfi\n> -\n> -\tsetup_reflog_action\n> -\tinit_basic_state\n> -\n> -\tif test -z \"$rebase_root\"\n> -\tthen\n> -\t\tmkdir \"$rewritten\" &&\n> -\t\tfor c in $(git merge-base --all $orig_head $upstream)\n> -\t\tdo\n> -\t\t\techo $onto > \"$rewritten\"/$c ||\n> -\t\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n> -\t\tdone\n> -\telse\n> -\t\tmkdir \"$rewritten\" &&\n> -\t\techo $onto > \"$rewritten\"/root ||\n> -\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n> -\tfi\n> -\n> -\tinit_revisions_and_shortrevisions\n> -\n> -\tformat=$(git config --get rebase.instructionFormat)\n> -\t# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse\n> -\tgit rev-list --format=\"%m%H ${format:-%s}\" \\\n> -\t\t--reverse --left-right --topo-order \\\n> -\t\t$revisions ${restrict_revision+^$restrict_revision} | \\\n> -\t\tsed -n \"s/^>//p\" |\n> -\twhile read -r sha1 rest\n> -\tdo\n> -\t\tif test -z \"$keep_empty\" && is_empty_commit $sha1 && ! is_merge_commit $sha1\n> -\t\tthen\n> -\t\t\tcomment_out=\"$comment_char \"\n> -\t\telse\n> -\t\t\tcomment_out=\n> -\t\tfi\n> -\n> -\t\tif test -z \"$rebase_root\"\n> -\t\tthen\n> -\t\t\tpreserve=t\n> -\t\t\tfor p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\n> -\t\t\tdo\n> -\t\t\t\tif test -f \"$rewritten\"/$p\n> -\t\t\t\tthen\n> -\t\t\t\t\tpreserve=f\n> -\t\t\t\tfi\n> -\t\t\tdone\n> -\t\telse\n> -\t\t\tpreserve=f\n> -\t\tfi\n> -\t\tif test f = \"$preserve\"\n> -\t\tthen\n> -\t\t\ttouch \"$rewritten\"/$sha1\n> -\t\t\tprintf '%s\\n' \"${comment_out}pick $sha1 $rest\" >>\"$todo\"\n> -\t\tfi\n> -\tdone\n> -\n> -\t# Watch for commits that been dropped by --cherry-pick\n> -\tmkdir \"$dropped\"\n> -\t# Save all non-cherry-picked changes\n> -\tgit rev-list $revisions --left-right --cherry-pick | \\\n> -\t\tsed -n \"s/^>//p\" > \"$state_dir\"/not-cherry-picks\n> -\t# Now all commits and note which ones are missing in\n> -\t# not-cherry-picks and hence being dropped\n> -\tgit rev-list $revisions |\n> -\twhile read rev\n> -\tdo\n> -\t\tif test -f \"$rewritten\"/$rev &&\n> -\t\t   ! sane_grep \"$rev\" \"$state_dir\"/not-cherry-picks >/dev/null\n> -\t\tthen\n> -\t\t\t# Use -f2 because if rev-list is telling us this commit is\n> -\t\t\t# not worthwhile, we don't want to track its multiple heads,\n> -\t\t\t# just the history of its first-parent for others that will\n> -\t\t\t# be rebasing on top of it\n> -\t\t\tgit rev-list --parents -1 $rev | cut -d' ' -s -f2 > \"$dropped\"/$rev\n> -\t\t\tsha1=$(git rev-list -1 $rev)\n> -\t\t\tsane_grep -v \"^[a-z][a-z]* $sha1\" <\"$todo\" > \"${todo}2\" ; mv \"${todo}2\" \"$todo\"\n> -\t\t\trm \"$rewritten\"/$rev\n> -\t\tfi\n> -\tdone\n> -\n> -\tcomplete_action\n> -}\n> \n\n"},{"id":"434785","messageId":"5fcd3201-53d0-df5d-954e-74da1ef7e130@gmail.com","threadId":"52325","inReplyTo":"62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2021-09-06T10:17:43Z","receivedAt":"2021-09-06T10:17:49Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Alban and Johannes\n\nOn 04/09/2021 23:30, Alban Gruin wrote:\n> Hi Johannes,\n> \n> Le 01/09/2021 à 13:57, Johannes Schindelin via GitGitGadget a écrit :\n>> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n>> included in v2.22.0), we officially deprecated the --preserve-merges\n>> backend. Over two years later, it is time to drop that backend, and here is\n>> a patch series that does just that.\n>>\n>> Changes since v1:\n>>\n>>   * Rebased onto v2.33.0\n>>\n>> Johannes Schindelin (7):\n>>    t5520: do not use `pull.rebase=preserve`\n>>    remote: warn about unhandled branch.<name>.rebase values\n>>    tests: stop testing `git rebase --preserve-merges`\n>>    pull: remove support for `--rebase=preserve`\n>>    rebase: drop support for `--preserve-merges`\n>>    git-svn: drop support for `--preserve-merges`\n>>    rebase: drop the internal `rebase--interactive` command\n>>\n> \n> This is good.\n\nI agree\n\n> preserve-merge is the only user of `rebase--interactive'.  In\n> builtin/rebase.c, it is the only producer of the following actions:\n> \n>   - ACTION_SHORTEN_OIDS\n>   - ACTION_EXPAND_OIDS\n>   - ACTION_CHECK_TODO_LIST\n>   - ACTION_REARRANGE_SQUASH\n>   - ACTION_ADD_EXEC\n> \n> Which in turn, are the only reason for these functions to exist:\n> \n>   - transform_todo_file()\n>   - check_todo_list_from_file() (from the sequencer)\n>   - rearrange_squash_in_todo_file()\n>   - add_exec_commands()\n> \n> This is from a cursory glance, it may go a bit deeper.\n\nI think patch 7 addresses most of that apart from the removal of the \nenum members and check_todo_list_from_file()\n\nBest Wishes\n\nPhillip\n> \n> Should we remove these as well?\n> \n> Alban\n> \n\n"},{"id":"434863","messageId":"nycvar.QRO.7.76.6.2109071430320.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"d93a750a-9faf-c91a-c9f7-e968c7ed40f5@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-07T12:32:54Z","receivedAt":"2021-09-07T12:32:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Mon, 6 Sep 2021, Phillip Wood wrote:\n\n> Hi dscho\n>\n> On 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > This option was deprecated in favor of `--rebase-merges` some time ago,\n> > and now we retire it.\n>\n> This all looks good to me. I did see the comment below in builtin/rebase.c\n> that could be tweaked if you reroll, but it is a very minor issue.\n>\n> /* -i followed by -p is still explicitly interactive, but -p alone is not */\n> static int parse_opt_interactive(const struct option *opt, const char *arg,\n>                                  int unset)\n\nRight, without `-p` this comment does not make sense anymore. But once I\nreplace the `-p` by `-r`, it _does_ make sense: `git rebase -r` is not\ninteractive, but `git rebase -ir` _is_.\n\n> I do wonder if we need these option parsing functions now but that is a\n> question for another day.\n\nAs the function parses the `-i`/`--interactive` option, which is not going\nanywhere, we still need it.\n\nThanks,\nDscho\n"},{"id":"434867","messageId":"nycvar.QRO.7.76.6.2109071438580.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"cf76b707-bd59-26f8-f257-02d773294495@gmail.com","subject":"Re: [PATCH v2 7/7] rebase: drop the internal `rebase--interactive` command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-07T12:39:33Z","receivedAt":"2021-09-07T12:39:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Mon, 6 Sep 2021, Phillip Wood wrote:\n\n> Hi dscho\n>\n> Thanks for working on this, it opens up the possibility of future cleanups now\n> we're not constrained by supporting cmd_rebase__interactive()\n\nYes!!!\n\n> On 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > [...]\n> > @@ -437,24 +362,6 @@ static int run_sequencer_rebase(struct rebase_options\n> > *opts,\n> >\n> >     break;\n> > }\n> > -\tcase ACTION_SHORTEN_OIDS:\n> > -\tcase ACTION_EXPAND_OIDS:\n> > -\t\tret = transform_todo_file(flags);\n> > -\t\tbreak;\n> > -\tcase ACTION_CHECK_TODO_LIST:\n> > -\t\tret = check_todo_list_from_file(the_repository);\n> > -\t\tbreak;\n> > -\tcase ACTION_REARRANGE_SQUASH:\n> > -\t\tret = rearrange_squash_in_todo_file();\n> > -\t\tbreak;\n> > -\tcase ACTION_ADD_EXEC: {\n> > -\t\tstruct string_list commands = STRING_LIST_INIT_DUP;\n> > -\n> > -\t\tsplit_exec_commands(opts->cmd, &commands);\n> > -\t\tret = add_exec_commands(&commands);\n> > -\t\tstring_list_clear(&commands, 0);\n> > -\t\tbreak;\n> > -\t}\n>\n> As Alban mentioned, I think it would be worth removing the enum members as\n> well as the case clauses here.\n\nMakes sense.\n\nThank you for your review,\nDscho\n\n>\n> Best Wishes\n>\n> Phillip\n>\n> >    default:\n> >     BUG(\"invalid command '%d'\", command);\n> > }\n> > @@ -476,98 +383,6 @@ static int parse_opt_keep_empty(const struct option\n> > *opt, const char *arg,\n> >    return 0;\n> > }\n> >   -static const char * const builtin_rebase_interactive_usage[] = {\n> > -\tN_(\"git rebase--interactive [<options>]\"),\n> > -\tNULL\n> > -};\n> > -\n> > -int cmd_rebase__interactive(int argc, const char **argv, const char\n> > *prefix)\n> > -{\n> > -\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n> > -\tstruct object_id squash_onto = *null_oid();\n> > -\tenum action command = ACTION_NONE;\n> > -\tstruct option options[] = {\n> > -\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n> > -\t\t\t   REBASE_FORCE),\n> > -\t\tOPT_CALLBACK_F('k', \"keep-empty\", &options, NULL,\n> > -\t\t\tN_(\"keep commits which start empty\"),\n> > -\t\t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN,\n> > -\t\t\tparse_opt_keep_empty),\n> > -\t\tOPT_BOOL_F(0, \"allow-empty-message\",\n> > &opts.allow_empty_message,\n> > -\t\t\t   N_(\"allow commits with empty messages\"),\n> > -\t\t\t   PARSE_OPT_HIDDEN),\n> > -\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase\n> > merge commits\")),\n> > -\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n> > -\t\t\t N_(\"keep original branch points of cousins\")),\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_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> > -\t\tOPT_CMDMODE(0, \"continue\", &command, N_(\"continue rebase\"),\n> > -\t\t\t    ACTION_CONTINUE),\n> > -\t\tOPT_CMDMODE(0, \"skip\", &command, N_(\"skip commit\"),\n> > ACTION_SKIP),\n> > -\t\tOPT_CMDMODE(0, \"edit-todo\", &command, N_(\"edit the todo\n> > list\"),\n> > -\t\t\t    ACTION_EDIT_TODO),\n> > -\t\tOPT_CMDMODE(0, \"show-current-patch\", &command, N_(\"show the\n> > current patch\"),\n> > -\t\t\t    ACTION_SHOW_CURRENT_PATCH),\n> > -\t\tOPT_CMDMODE(0, \"shorten-ids\", &command,\n> > -\t\t\tN_(\"shorten commit ids in the todo list\"),\n> > ACTION_SHORTEN_OIDS),\n> > -\t\tOPT_CMDMODE(0, \"expand-ids\", &command,\n> > -\t\t\tN_(\"expand commit ids in the todo list\"),\n> > ACTION_EXPAND_OIDS),\n> > -\t\tOPT_CMDMODE(0, \"check-todo-list\", &command,\n> > -\t\t\tN_(\"check the todo list\"), ACTION_CHECK_TODO_LIST),\n> > -\t\tOPT_CMDMODE(0, \"rearrange-squash\", &command,\n> > -\t\t\tN_(\"rearrange fixup/squash lines\"),\n> > ACTION_REARRANGE_SQUASH),\n> > -\t\tOPT_CMDMODE(0, \"add-exec-commands\", &command,\n> > -\t\t\tN_(\"insert exec commands in todo list\"),\n> > ACTION_ADD_EXEC),\n> > -\t\t{ OPTION_CALLBACK, 0, \"onto\", &opts.onto, N_(\"onto\"),\n> > N_(\"onto\"),\n> > -\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n> > -\t\t{ OPTION_CALLBACK, 0, \"restrict-revision\",\n> > &opts.restrict_revision,\n> > -\t\t  N_(\"restrict-revision\"), N_(\"restrict revision\"),\n> > -\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n> > -\t\t{ OPTION_CALLBACK, 0, \"squash-onto\", &squash_onto,\n> > N_(\"squash-onto\"),\n> > -\t\t  N_(\"squash onto\"), PARSE_OPT_NONEG, parse_opt_object_id, 0\n> > },\n> > -\t\t{ OPTION_CALLBACK, 0, \"upstream\", &opts.upstream,\n> > N_(\"upstream\"),\n> > -\t\t  N_(\"the upstream commit\"), PARSE_OPT_NONEG,\n> > parse_opt_commit,\n> > -\t\t  0 },\n> > -\t\tOPT_STRING(0, \"head-name\", &opts.head_name, N_(\"head-name\"),\n> > N_(\"head name\")),\n> > -\t\t{ OPTION_STRING, 'S', \"gpg-sign\", &opts.gpg_sign_opt,\n> > N_(\"key-id\"),\n> > -\t\t\tN_(\"GPG-sign commits\"),\n> > -\t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t) \"\" },\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> > N_(\"strategy-opts\"),\n> > -\t\t\t   N_(\"strategy options\")),\n> > -\t\tOPT_STRING(0, \"switch-to\", &opts.switch_to, N_(\"switch-to\"),\n> > -\t\t\t   N_(\"the branch or commit to checkout\")),\n> > -\t\tOPT_STRING(0, \"onto-name\", &opts.onto_name, N_(\"onto-name\"),\n> > N_(\"onto name\")),\n> > -\t\tOPT_STRING(0, \"cmd\", &opts.cmd, N_(\"cmd\"), N_(\"the command to\n> > run\")),\n> > -\t\tOPT_RERERE_AUTOUPDATE(&opts.allow_rerere_autoupdate),\n> > -\t\tOPT_BOOL(0, \"reschedule-failed-exec\",\n> > &opts.reschedule_failed_exec,\n> > -\t\t\t N_(\"automatically re-schedule any `exec` that\n> > fails\")),\n> > -\t\tOPT_END()\n> > -\t};\n> > -\n> > -\topts.rebase_cousins = -1;\n> > -\n> > -\tif (argc == 1)\n> > -\t\tusage_with_options(builtin_rebase_interactive_usage, options);\n> > -\n> > -\targc = parse_options(argc, argv, prefix, options,\n> > -\t\t\tbuiltin_rebase_interactive_usage,\n> > PARSE_OPT_KEEP_ARGV0);\n> > -\n> > -\tif (!is_null_oid(&squash_onto))\n> > -\t\topts.squash_onto = &squash_onto;\n> > -\n> > -\tif (opts.rebase_cousins >= 0 && !opts.rebase_merges)\n> > -\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n> > -\t\t\t  \"--rebase-merges\"));\n> > -\n> > -\treturn !!run_sequencer_rebase(&opts, command);\n> > -}\n> > -\n> >   static int is_merge(struct rebase_options *opts)\n> >   {\n> >   \treturn opts->type == REBASE_MERGE;\n> > diff --git a/git.c b/git.c\n> > index 18bed9a9964..268cdd82cfc 100644\n> > --- a/git.c\n> > +++ b/git.c\n> > @@ -577,7 +577,6 @@ static struct cmd_struct commands[] = {\n> >    { \"range-diff\", cmd_range_diff, RUN_SETUP | USE_PAGER },\n> >    { \"read-tree\", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},\n> >    { \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n> > -\t{ \"rebase--interactive\", cmd_rebase__interactive, RUN_SETUP |\n> > NEED_WORK_TREE },\n> >    { \"receive-pack\", cmd_receive_pack },\n> >    { \"reflog\", cmd_reflog, RUN_SETUP },\n> >    { \"remote\", cmd_remote, RUN_SETUP },\n> >\n>\n>\n>\n"},{"id":"434871","messageId":"nycvar.QRO.7.76.6.2109071444260.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-07T12:48:58Z","receivedAt":"2021-09-07T12:48:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Alban,\n\nOn Sun, 5 Sep 2021, Alban Gruin wrote:\n\n> Le 01/09/2021 à 13:57, Johannes Schindelin via GitGitGadget a écrit :\n> > In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> > included in v2.22.0), we officially deprecated the --preserve-merges\n> > backend. Over two years later, it is time to drop that backend, and here is\n> > a patch series that does just that.\n> >\n> > Changes since v1:\n> >\n> >  * Rebased onto v2.33.0\n> >\n> > Johannes Schindelin (7):\n> >   t5520: do not use `pull.rebase=preserve`\n> >   remote: warn about unhandled branch.<name>.rebase values\n> >   tests: stop testing `git rebase --preserve-merges`\n> >   pull: remove support for `--rebase=preserve`\n> >   rebase: drop support for `--preserve-merges`\n> >   git-svn: drop support for `--preserve-merges`\n> >   rebase: drop the internal `rebase--interactive` command\n> >\n>\n> This is good.\n\nThanks!\n\n> preserve-merge is the only user of `rebase--interactive'.  In\n> builtin/rebase.c, it is the only producer of the following actions:\n>\n>  - ACTION_SHORTEN_OIDS\n>  - ACTION_EXPAND_OIDS\n>  - ACTION_CHECK_TODO_LIST\n>  - ACTION_REARRANGE_SQUASH\n>  - ACTION_ADD_EXEC\n\nMakes sense!\n\n> Which in turn, are the only reason for these functions to exist:\n>\n>  - transform_todo_file()\n\nMy patch series already removed this.\n\n>  - check_todo_list_from_file() (from the sequencer)\n\nGood point!\n\n>  - rearrange_squash_in_todo_file()\n\nThis was already removed by my patch series.\n\n>  - add_exec_commands()\n\nActually, this function is still needed, but its scope can be reduced.\n\nThank you!\nDscho\n"},{"id":"434886","messageId":"86cbe5b9-1a9e-0616-2d66-3130fcb9afb9@gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109071430320.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2021-09-07T15:31:01Z","receivedAt":"2021-09-07T15:31:11Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Dscho\n\nOn 07/09/2021 13:32, Johannes Schindelin wrote:\n> Hi Phillip,\n> \n> On Mon, 6 Sep 2021, Phillip Wood wrote:\n> \n>> Hi dscho\n>>\n>> On 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n>>> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>>>\n>>> This option was deprecated in favor of `--rebase-merges` some time ago,\n>>> and now we retire it.\n>>\n>> This all looks good to me. I did see the comment below in builtin/rebase.c\n>> that could be tweaked if you reroll, but it is a very minor issue.\n>>\n>> /* -i followed by -p is still explicitly interactive, but -p alone is not */\n>> static int parse_opt_interactive(const struct option *opt, const char *arg,\n>>                                   int unset)\n> \n> Right, without `-p` this comment does not make sense anymore. But once I\n> replace the `-p` by `-r`, it _does_ make sense: `git rebase -r` is not\n> interactive, but `git rebase -ir` _is_.\n> \n>> I do wonder if we need these option parsing functions now but that is a\n>> question for another day.\n> \n> As the function parses the `-i`/`--interactive` option, which is not going\n> anywhere, we still need it.\n\nSure I was just wondering if we could simplify things by using something \nlike OPT_BOOL rather than OPT_CALLBACK_F for \"--am\", \"-i\" and \"-m\". I \nhaven't looked too closely though\n\nThanks again for this series\nBest Wishes\n\nPhillip\n\n> Thanks,\n> Dscho\n> \n"},{"id":"434900","messageId":"nycvar.QRO.7.76.6.2109071930080.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"4e998676-4975-8ac2-35a0-34416938b62e@kdbg.org","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-07T17:33:52Z","receivedAt":"2021-09-07T17:33:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 2 Sep 2021, Johannes Sixt wrote:\n\n> Am 02.09.21 um 16:18 schrieb Johannes Schindelin:\n> > On Wed, 1 Sep 2021, Junio C Hamano wrote:\n> >> A good goal.  There is no remaining use case where (a fictitious and\n> >> properly working version of) \"--preserve-merges\" option cannot be\n> >> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n> >> the other Johannes (sorry if it weren't you, j6t) had cases that the\n> >> former worked better, but perhaps I am mis-remembering things.\n> >\n> > I think that I managed to address whatever concerns there were about the\n> > `--rebase-merges` backend in the meantime.\n>\n> That was either my suggestion/desire to make no-rebase-cousins the\n> default. That has been settled.\n>\n> Or my wish not to redo the merge, but to replay the first-parent\n> difference. The idea never got traction, and I've long since abandoned\n> my implementation of it.\n\nThank you for clarifying.\n\nYes, I remember how that idea came up, and I even tried that strategy for\na couple of merging rebases of Git for Windows' branch thicket. Sadly, it\ndid not work half as well as I had hoped.\n\nThe best idea I had back then still is in want of being implemented: sort\nof a \"four-way merge\". It is basically the same as a three-way merge, but\nallows for the pre-images to differ in the context (and yes, this cannot\nbe represented using the current conflict markers). Definitely not\ntrivial.\n\n> > To be honest, I developed one (minor) concern in the meantime... Should we\n> > maybe try to be nicer to our users and keep handling the\n> > `--preserve-merges` option by explicitly erroring out with the suggestion\n> > to use `--rebase-merges` instead? Not everybody reads release notes, after\n> > all. In fact, it is my experience that preciously few users have the time\n> > to even skim release notes...\n>\n> A valid concern, I would think.\n\nGood. Since you concur with my hunch, I implemented that change.\n\nThank you for reviewing,\nDscho\n"},{"id":"434908","messageId":"xmqqpmtkb5r7.fsf@gitster.g","threadId":"52325","inReplyTo":"87y28anq98.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-07T18:27:40Z","receivedAt":"2021-09-07T18:27:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Wed, Sep 01 2021, Junio C Hamano wrote:\n>\n>> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n>> writes:\n>>\n>>> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n>>> included in v2.22.0), we officially deprecated the --preserve-merges\n>>> backend. Over two years later, it is time to drop that backend, and here is\n>>> a patch series that does just that.\n>>\n>> A good goal.  There is no remaining use case where (a fictitious and\n>> properly working version of) \"--preserve-merges\" option cannot be\n>> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n>> the other Johannes (sorry if it weren't you, j6t) had cases that the\n>> former worked better, but perhaps I am mis-remembering things.\n>\n> Fair enough. To be clear I think this series is fine as-is, we've just\n> usually done \"now that this function is dead, rm it\" as part of the\n> series that makes it dead, so I figured fixups/squashes to change those\n> parts would be welcome & integrated, likewise Alban Gruin's suggestions\n> in <62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com>.\n>\n> But the git-sh-i18n.sh change and/or his suggestions can be done after\n> this lands...\n\nI have this funny feeling that the \"Fair enough\" is thrown at a\ncomment that you didn't intend to ;-)\n"},{"id":"434916","messageId":"nycvar.QRO.7.76.6.2109072135250.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"86cbe5b9-1a9e-0616-2d66-3130fcb9afb9@gmail.com","subject":"Re: [PATCH v2 5/7] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-07T19:44:01Z","receivedAt":"2021-09-07T19:43:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Tue, 7 Sep 2021, Phillip Wood wrote:\n\n> On 07/09/2021 13:32, Johannes Schindelin wrote:\n> >\n> > On Mon, 6 Sep 2021, Phillip Wood wrote:\n> >\n> > > On 01/09/2021 12:57, Johannes Schindelin via GitGitGadget wrote:\n> > > > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > > >\n> > > > This option was deprecated in favor of `--rebase-merges` some time ago,\n> > > > and now we retire it.\n> > >\n> > > This all looks good to me. I did see the comment below in builtin/rebase.c\n> > > that could be tweaked if you reroll, but it is a very minor issue.\n> > >\n> > > /* -i followed by -p is still explicitly interactive, but -p alone is not\n> > > */\n> > > static int parse_opt_interactive(const struct option *opt, const char\n> > > *arg,\n> > >                                   int unset)\n> >\n> > Right, without `-p` this comment does not make sense anymore. But once I\n> > replace the `-p` by `-r`, it _does_ make sense: `git rebase -r` is not\n> > interactive, but `git rebase -ir` _is_.\n> >\n> > > I do wonder if we need these option parsing functions now but that is a\n> > > question for another day.\n> >\n> > As the function parses the `-i`/`--interactive` option, which is not going\n> > anywhere, we still need it.\n>\n> Sure I was just wondering if we could simplify things by using something like\n> OPT_BOOL rather than OPT_CALLBACK_F for \"--am\", \"-i\" and \"-m\". I haven't\n> looked too closely though\n\nIt's definitely a good question, and I wondered, too, but failed to share\nmy conclusions with you.\n\nThe callback does two things: first, it switches the rebase type to\n`merge`, and then it also sets the flag (by setting a bit in the bit\nfield) that the rebase is explicitly interactive.\n\nThe reason for this \"explicitly interactive\" wording is historical, of\ncourse, because historically some functionality was implemented by\n`git-rebase--interactive.sh` even if the rebase itself was intended _not_\nto be run interactively. Think `git rebase --exec <command>`, for example.\n\nThese days, it is still true that `rebase-interactive.c` implements some\nfunctionality that is not necessarily meant to be executed interactively\n(again, `--exec`, but also `--rebase-merges`).\n\nSo there _is_ a need for that option to do more than one thing, and as\nsome options can try to set, say, the rebase type, it is important to\nhandle those options immediately (as opposed to trying to set a flag based\non `--interactive` and then trying to infer the rebase type from that flag\n_after_ `parse_options()` is done).\n\nCiao,\nDscho\n"},{"id":"434923","messageId":"87y288jh62.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"xmqqpmtkb5r7.fsf@gitster.g","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-07T19:52:54Z","receivedAt":"2021-09-07T19:54:02Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Sep 07 2021, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>> On Wed, Sep 01 2021, Junio C Hamano wrote:\n>>\n>>> \"Johannes Schindelin via GitGitGadget\" <gitgitgadget@gmail.com>\n>>> writes:\n>>>\n>>>> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n>>>> included in v2.22.0), we officially deprecated the --preserve-merges\n>>>> backend. Over two years later, it is time to drop that backend, and here is\n>>>> a patch series that does just that.\n>>>\n>>> A good goal.  There is no remaining use case where (a fictitious and\n>>> properly working version of) \"--preserve-merges\" option cannot be\n>>> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n>>> the other Johannes (sorry if it weren't you, j6t) had cases that the\n>>> former worked better, but perhaps I am mis-remembering things.\n>>\n>> Fair enough. To be clear I think this series is fine as-is, we've just\n>> usually done \"now that this function is dead, rm it\" as part of the\n>> series that makes it dead, so I figured fixups/squashes to change those\n>> parts would be welcome & integrated, likewise Alban Gruin's suggestions\n>> in <62fbd389-28f5-76e5-d3f3-5510415a7bf5@gmail.com>.\n>>\n>> But the git-sh-i18n.sh change and/or his suggestions can be done after\n>> this lands...\n>\n> I have this funny feeling that the \"Fair enough\" is thrown at a\n> comment that you didn't intend to ;-)\n\nI think I meant to reply to\nhttps://lore.kernel.org/git/xmqqlf4aejko.fsf@gitster.g/; I don't know\nhow I got them mixed up, sorry about that.\n"},{"id":"434936","messageId":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v2.git.1630497435.gitgitgadget@gmail.com","subject":"[PATCH v3 00/11] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:01Z","receivedAt":"2021-09-07T21:05:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\nincluded in v2.22.0), we officially deprecated the --preserve-merges\nbackend. Over two years later, it is time to drop that backend, and here is\na patch series that does just that.\n\nChanges since v2:\n\n * Removed the no-longer-needed script_snippet variable\n * Enhanced the commit message of the git svn patch to clarify that the\n   deprecation happened only in v2.25 there\n * Adjusted code comments that still talked about the removed option\n * Removed some no-longer-needed ACTION_* enum values\n * We now also drop check_todo_list_from_file() because it is no longer\n   needed\n * The todo_list_add_exec_commands() function is now scoped to the file\n   (because there are no longer any outside users)\n * When users still use the options, they are no longer met by Git's blank\n   stares, but by a helpful error message suggesting to use --rebase-merges\n   instead\n\nChanges since v1:\n\n * Rebased onto v2.33.0\n\nJohannes Schindelin (11):\n  t5520: do not use `pull.rebase=preserve`\n  remote: warn about unhandled branch.<name>.rebase values\n  tests: stop testing `git rebase --preserve-merges`\n  pull: remove support for `--rebase=preserve`\n  rebase: drop support for `--preserve-merges`\n  git-svn: drop support for `--preserve-merges`\n  rebase: drop the internal `rebase--interactive` command\n  rebase: remove obsolete code comment\n  rebase: stop mentioning the -p option in comments\n  rebase: remove a no-longer-used function\n  sequencer: restrict scope of a formerly public function\n\n .github/workflows/main.yml                |    1 -\n .gitignore                                |    1 -\n Documentation/config/branch.txt           |    4 -\n Documentation/config/pull.txt             |    4 -\n Documentation/git-pull.txt                |    6 +-\n Documentation/git-rebase.txt              |   51 -\n Documentation/git-svn.txt                 |    1 -\n Makefile                                  |    2 -\n builtin/pull.c                            |    9 +-\n builtin/rebase.c                          |  335 +------\n builtin/remote.c                          |    3 +\n contrib/completion/git-completion.bash    |    2 +-\n git-rebase--preserve-merges.sh            | 1057 ---------------------\n git-svn.perl                              |    1 -\n git.c                                     |    1 -\n rebase-interactive.c                      |   29 -\n rebase-interactive.h                      |    2 -\n rebase.c                                  |    5 +-\n rebase.h                                  |    1 -\n sequencer.c                               |    4 +-\n sequencer.h                               |    2 -\n t/t3404-rebase-interactive.sh             |   76 --\n t/t3408-rebase-multi-line.sh              |   10 -\n t/t3409-rebase-preserve-merges.sh         |  130 ---\n t/t3410-rebase-preserve-dropped-merges.sh |   90 --\n t/t3411-rebase-preserve-around-merges.sh  |   80 --\n t/t3412-rebase-root.sh                    |   37 -\n t/t3414-rebase-preserve-onto.sh           |   85 --\n t/t3418-rebase-continue.sh                |   15 -\n t/t3421-rebase-topology-linear.sh         |   19 -\n t/t3422-rebase-incompatible-options.sh    |   11 -\n t/t3425-rebase-topology-merges.sh         |  151 ---\n t/t3427-rebase-subtree.sh                 |   26 +-\n t/t5520-pull.sh                           |   24 +-\n t/t7505-prepare-commit-msg-hook.sh        |    1 -\n t/t7517-per-repo-email.sh                 |   13 -\n t/test-lib.sh                             |    4 -\n 37 files changed, 33 insertions(+), 2260 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\n\nbase-commit: 225bc32a989d7a22fa6addafd4ce7dcd04675dbf\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-195%2Fdscho%2Fdrop-rebase-p-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-195/dscho/drop-rebase-p-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/195\n\nRange-diff vs v2:\n\n  1:  8da29d539fc =  1:  8da29d539fc t5520: do not use `pull.rebase=preserve`\n  2:  acda0f59947 =  2:  acda0f59947 remote: warn about unhandled branch.<name>.rebase values\n  3:  cdb9fae4b93 !  3:  e4b683f0cd6 tests: stop testing `git rebase --preserve-merges`\n     @@ t/t3425-rebase-topology-merges.sh: test_run_rebase success 'd n o e' --apply\n       test_done\n      \n       ## t/t3427-rebase-subtree.sh ##\n     +@@ t/t3427-rebase-subtree.sh: commit_message() {\n     + # where the root commit adds three files: topic_1.t, topic_2.t and topic_3.t.\n     + #\n     + # This commit history is then rebased onto `topic_3` with the\n     +-# `-Xsubtree=files_subtree` option in three different ways:\n     ++# `-Xsubtree=files_subtree` option in two different ways:\n     + #\n     +-# 1. using `--preserve-merges`\n     +-# 2. using `--preserve-merges` and --keep-empty\n     +-# 3. without specifying a rebase backend\n     ++# 1. without specifying a rebase backend\n     ++# 2. using the `--rebase-merges` backend\n     + \n     + test_expect_success 'setup' '\n     + \ttest_commit README &&\n      @@ t/t3427-rebase-subtree.sh: test_expect_success 'setup' '\n       \tgit commit -m \"Empty commit\" --allow-empty\n       '\n  4:  b493046134d !  4:  6e45e90abe5 pull: remove support for `--rebase=preserve`\n     @@ Commit message\n          In preparation for `git-rebase--preserve-merges.sh` entering its after\n          life, we remove this (deprecated) option that would still rely on it.\n      \n     +    To help users transition who still did not receive the memo about the\n     +    deprecation, we offer a helpful error message instead of throwing our\n     +    hands in the air and saying that we don't know that option, never heard\n     +    of it.\n     +\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       ## Documentation/config/branch.txt ##\n     @@ contrib/completion/git-completion.bash: __git_complete_config_variable_value ()\n       \tremote.pushdefault)\n      \n       ## rebase.c ##\n     +@@\n     + #include \"rebase.h\"\n     + #include \"config.h\"\n     ++#include \"gettext.h\"\n     + \n     + /*\n     +  * Parses textual value for pull.rebase, branch.<name>.rebase, etc.\n      @@ rebase.c: enum rebase_type rebase_parse_value(const char *value)\n       \t\treturn REBASE_FALSE;\n       \telse if (v > 0)\n     @@ rebase.c: enum rebase_type rebase_parse_value(const char *value)\n       \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n       \t\treturn REBASE_MERGES;\n       \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\n     + \t\treturn REBASE_INTERACTIVE;\n     ++\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n     ++\t\terror(_(\"%s: 'preserve' superseded by 'merges'\"), value);\n     + \t/*\n     + \t * Please update _git_config() in git-completion.bash when you\n     + \t * add new rebase modes.\n      \n       ## rebase.h ##\n      @@ rebase.h: enum rebase_type {\n  5:  eb738b1bf05 !  5:  2d7a4a2c564 rebase: drop support for `--preserve-merges`\n     @@ Commit message\n          This option was deprecated in favor of `--rebase-merges` some time ago,\n          and now we retire it.\n      \n     +    To assist users to transition away, we do not _actually_ remove the\n     +    option, but now we no longer implement the functionality. Instead, we\n     +    offer a helpful error message suggesting which option to use.\n     +\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       ## .gitignore ##\n     @@ builtin/rebase.c: static int run_am(struct rebase_options *opts)\n       {\n      -\tconst char *argv[] = { NULL, NULL };\n      -\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n     -+\tstruct strbuf script_snippet = STRBUF_INIT;\n       \tint status;\n      -\tconst char *backend, *backend_func;\n       \n     @@ builtin/rebase.c: static int run_specific_rebase(struct rebase_options *opts, en\n       \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n      -\t\tbreak;\n      -\t}\n     - \n     +-\n      -\tstrbuf_addf(&script_snippet,\n      -\t\t    \". git-sh-setup && . %s && %s\", backend, backend_func);\n      -\targv[0] = script_snippet.buf;\n     --\n     + \n      -\tstatus = run_command_v_opt(argv, RUN_USING_SHELL);\n      -finished_rebase:\n       \tif (opts->dont_finish_rebase)\n       \t\t; /* do nothing */\n       \telse if (opts->type == REBASE_MERGE)\n     +@@ builtin/rebase.c: finished_rebase:\n     + \t\tdie(\"Nothing to do\");\n     + \t}\n     + \n     +-\tstrbuf_release(&script_snippet);\n     +-\n     + \treturn status ? -1 : 0;\n     + }\n     + \n     +@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     + \tchar *squash_onto_name = NULL;\n     + \tint reschedule_failed_exec = -1;\n     + \tint allow_preemptive_ff = 1;\n     ++\tint preserve_merges_selected = 0;\n     + \tstruct option builtin_rebase_options[] = {\n     + \t\tOPT_STRING(0, \"onto\", &options.onto_name,\n     + \t\t\t   N_(\"revision\"),\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n       \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n       \t\t\tparse_opt_interactive),\n      -\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n     --\t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n     --\t\t\t\t \"ignoring them\"),\n     ++\t\tOPT_SET_INT_F('p', \"preserve-merges\", &preserve_merges_selected,\n     + \t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n     + \t\t\t\t \"ignoring them\"),\n      -\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n     ++\t\t\t      1, PARSE_OPT_HIDDEN),\n       \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n       \t\tOPT_CALLBACK_F(0, \"empty\", &options, \"{drop,keep,ask}\",\n       \t\t\t       N_(\"how to handle commits that become empty\"),\n     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix\n       \t\t} else {\n       \t\t\tstrbuf_reset(&buf);\n       \t\t\tstrbuf_addf(&buf, \"%s/interactive\", merge_dir());\n     +@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n     + \t\t\t     builtin_rebase_options,\n     + \t\t\t     builtin_rebase_usage, 0);\n     + \n     ++\tif (preserve_merges_selected)\n     ++\t\tdie(_(\"--preserve-merges was replaced by --rebase-merges\"));\n     ++\n     + \tif (action != ACTION_NONE && total_argc != 2) {\n     + \t\tusage_with_options(builtin_rebase_usage,\n     + \t\t\t\t   builtin_rebase_options);\n      @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)\n       \t\tusage_with_options(builtin_rebase_usage,\n       \t\t\t\t   builtin_rebase_options);\n  6:  a987e9439af !  6:  913647d8e76 git-svn: drop support for `--preserve-merges`\n     @@ Commit message\n          We already passed the `--rebase-merges` option to `git rebase` instead,\n          now we make this move permanent.\n      \n     +    As pointed out by Ævar Arnfjörð Bjarmason, in contrast to the\n     +    deprecation of `git rebase`'s `--preserve-merges` backend, `git svn`\n     +    only deprecated this option in v2.25.0 (because this developer missed\n     +    `git svn`'s use of that backend when deprecating the rebase backend\n     +    running up to Git v2.22).\n     +\n     +    Still, v2.25.0 has been released on January 13th, 2020. In other words,\n     +    `git svn` deprecated this option over one and a half years ago, _and_\n     +    has been redirecting to the `--rebase-merges` option during all that\n     +    time (read: `git svn rebase --preserve-merges` didn't do _precisely_\n     +    what the user asked, since v2.25.0, anyway, it fell back to pretending\n     +    that the user asked for `git svn rebase --rebase-merges` instead).\n     +\n     +    It is time to act on that deprecation and remove that option after all.\n     +\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       ## Documentation/git-svn.txt ##\n  7:  4492cca369c !  7:  b5a16e205e6 rebase: drop the internal `rebase--interactive` command\n     @@ Commit message\n          It was only used by the `--preserve-merges` backend, which we just\n          removed.\n      \n     +    Helped-by: Alban Gruin <alban.gruin@gmail.com>\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       ## builtin/rebase.c ##\n     +@@ builtin/rebase.c: enum action {\n     + \tACTION_ABORT,\n     + \tACTION_QUIT,\n     + \tACTION_EDIT_TODO,\n     +-\tACTION_SHOW_CURRENT_PATCH,\n     +-\tACTION_SHORTEN_OIDS,\n     +-\tACTION_EXPAND_OIDS,\n     +-\tACTION_CHECK_TODO_LIST,\n     +-\tACTION_REARRANGE_SQUASH,\n     +-\tACTION_ADD_EXEC\n     ++\tACTION_SHOW_CURRENT_PATCH\n     + };\n     + \n     + static const char *action_names[] = { \"undefined\",\n      @@ builtin/rebase.c: static const char *action_names[] = { \"undefined\",\n       \t\t\t\t      \"edit_todo\",\n       \t\t\t\t      \"show_current_patch\" };\n     @@ builtin/rebase.c: static const char *action_names[] = { \"undefined\",\n       {\n       \tconst char *todo_file = rebase_path_todo();\n      @@ builtin/rebase.c: static int run_sequencer_rebase(struct rebase_options *opts,\n     + \tflags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;\n     + \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n     + \tflags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;\n     +-\tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n     + \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n     + \n     + \tswitch (command) {\n     +@@ builtin/rebase.c: static int run_sequencer_rebase(struct rebase_options *opts,\n       \n       \t\tbreak;\n       \t}\n  -:  ----------- >  8:  d23f245b684 rebase: remove obsolete code comment\n  -:  ----------- >  9:  6905c8746ba rebase: stop mentioning the -p option in comments\n  -:  ----------- > 10:  5bb04ea3f6c rebase: remove a no-longer-used function\n  -:  ----------- > 11:  aae9323b25f sequencer: restrict scope of a formerly public function\n\n-- \ngitgitgadget\n"},{"id":"434937","messageId":"8da29d539fc2c9700630d5ec4a80cacf64d44aa0.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 01/11] t5520: do not use `pull.rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:02Z","receivedAt":"2021-09-07T21:05:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nEven if those tests try to override that setting, let's not use it\nbecause it is deprecated: let's use `merges` instead.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t5520-pull.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex e2c0c510222..bb9b6b900eb 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -598,7 +598,7 @@ test_expect_success '--rebase=false create a new merge commit' '\n \n test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase=true . copy &&\n \ttest_cmp_rev HEAD^^ copy &&\n \techo file3 >expect &&\n@@ -620,9 +620,9 @@ test_expect_success '--rebase=invalid fails' '\n \ttest_must_fail git pull --rebase=invalid . copy\n '\n \n-test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '\n+test_expect_success '--rebase overrides pull.rebase=merges and flattens keep-merge' '\n \tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n+\ttest_config pull.rebase merges &&\n \tgit pull --rebase . copy &&\n \ttest_cmp_rev HEAD^^ copy &&\n \techo file3 >expect &&\n-- \ngitgitgadget\n\n"},{"id":"434938","messageId":"acda0f599475c07c6c1a5e75384e0cff98d2c19f.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 02/11] remote: warn about unhandled branch.<name>.rebase values","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:03Z","receivedAt":"2021-09-07T21:05:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe ignore them silently, but it actually makes sense to warn the users\nthat their config setting has no effect.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/remote.c | 3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..5705e088e5b 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -318,6 +318,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)\n \t\t * truth value with >= REBASE_TRUE.\n \t\t */\n \t\tinfo->rebase = rebase_parse_value(value);\n+\t\tif (info->rebase == REBASE_INVALID)\n+\t\t\twarning(_(\"unhandled branch.%s.rebase=%s; assuming \"\n+\t\t\t\t  \"'true'\"), name, value);\n \t\tbreak;\n \tcase PUSH_REMOTE:\n \t\tif (info->push_remote_name)\n-- \ngitgitgadget\n\n"},{"id":"434940","messageId":"e4b683f0cd6300cdda78075a03665db369c9a0aa.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 03/11] tests: stop testing `git rebase --preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:04Z","receivedAt":"2021-09-07T21:05:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis backend has been deprecated in favor of `git rebase\n--rebase-merges`.\n\nIn preparation for dropping it, let's remove all the regression tests\nthat would need it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .github/workflows/main.yml                |   1 -\n t/t3404-rebase-interactive.sh             |  76 -----------\n t/t3408-rebase-multi-line.sh              |  10 --\n t/t3409-rebase-preserve-merges.sh         | 130 -------------------\n t/t3410-rebase-preserve-dropped-merges.sh |  90 -------------\n t/t3411-rebase-preserve-around-merges.sh  |  80 ------------\n t/t3412-rebase-root.sh                    |  37 ------\n t/t3414-rebase-preserve-onto.sh           |  85 ------------\n t/t3418-rebase-continue.sh                |  15 ---\n t/t3421-rebase-topology-linear.sh         |  19 ---\n t/t3422-rebase-incompatible-options.sh    |  11 --\n t/t3425-rebase-topology-merges.sh         | 151 ----------------------\n t/t3427-rebase-subtree.sh                 |  26 +---\n t/t5520-pull.sh                           |  18 ---\n t/t7505-prepare-commit-msg-hook.sh        |   1 -\n t/t7517-per-repo-email.sh                 |  13 --\n t/test-lib.sh                             |   4 -\n 17 files changed, 3 insertions(+), 764 deletions(-)\n delete mode 100755 t/t3409-rebase-preserve-merges.sh\n delete mode 100755 t/t3410-rebase-preserve-dropped-merges.sh\n delete mode 100755 t/t3411-rebase-preserve-around-merges.sh\n delete mode 100755 t/t3414-rebase-preserve-onto.sh\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex 47876a4f02e..6115755c4df 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -198,7 +198,6 @@ jobs:\n       shell: bash\n       env:\n         NO_SVN_TESTS: 1\n-        GIT_TEST_SKIP_REBASE_P: 1\n       run: ci/run-test-slice.sh ${{matrix.nr}} 10\n     - name: ci/print-test-failures.sh\n       if: failure()\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 66bcbbf9528..827b0450b9f 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -351,82 +351,6 @@ test_expect_success 'retain authorship when squashing' '\n \tgit show HEAD | grep \"^Author: Twerp Snog\"\n '\n \n-test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n-\tHEAD=$(git rev-parse HEAD) &&\n-\tgit rebase -i -p HEAD^ &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $HEAD = $(git rev-parse HEAD)\n-'\n-\n-test_expect_failure REBASE_P 'exchange two commits with -p' '\n-\tgit checkout H &&\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2\n-\t) &&\n-\ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n-\ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n-'\n-\n-test_expect_success REBASE_P 'preserve merges with -p' '\n-\tgit checkout -b to-be-preserved primary^ &&\n-\t: > unrelated-file &&\n-\tgit add unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m \"unrelated\" &&\n-\tgit checkout -b another-branch primary &&\n-\techo B > file1 &&\n-\ttest_tick &&\n-\tgit commit -m J file1 &&\n-\ttest_tick &&\n-\tgit merge to-be-preserved &&\n-\techo C > file1 &&\n-\ttest_tick &&\n-\tgit commit -m K file1 &&\n-\techo D > file1 &&\n-\ttest_tick &&\n-\tgit commit -m L1 file1 &&\n-\tgit checkout HEAD^ &&\n-\techo 1 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2 unrelated-file &&\n-\ttest_tick &&\n-\tgit merge another-branch &&\n-\techo E > file1 &&\n-\ttest_tick &&\n-\tgit commit -m M file1 &&\n-\tgit checkout -b to-be-rebased &&\n-\ttest_tick &&\n-\tgit rebase -i -p --onto branch1 primary &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest_cmp_rev HEAD~6 branch1 &&\n-\ttest_cmp_rev HEAD~4^2 to-be-preserved &&\n-\ttest_cmp_rev HEAD^^2^ HEAD^^^ &&\n-\ttest $(git show HEAD~5:file1) = B &&\n-\ttest $(git show HEAD~3:file1) = C &&\n-\ttest $(git show HEAD:file1) = E &&\n-\ttest $(git show HEAD:unrelated-file) = 1\n-'\n-\n-test_expect_success REBASE_P 'edit ancestor with -p' '\n-\t(\n-\t\tset_fake_editor &&\n-\t\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3\n-\t) &&\n-\techo 2 > unrelated-file &&\n-\ttest_tick &&\n-\tgit commit -m L2-modified --amend unrelated-file &&\n-\tgit rebase --continue &&\n-\tgit update-index --refresh &&\n-\tgit diff-files --quiet &&\n-\tgit diff-index --quiet --cached HEAD -- &&\n-\ttest $(git show HEAD:unrelated-file) = 2\n-'\n-\n test_expect_success '--continue tries to commit' '\n \tgit reset --hard D &&\n \ttest_tick &&\ndiff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh\nindex ab0960e6d99..cde3562e3a6 100755\n--- a/t/t3408-rebase-multi-line.sh\n+++ b/t/t3408-rebase-multi-line.sh\n@@ -55,14 +55,4 @@ test_expect_success rebase '\n \ttest_cmp expect actual\n \n '\n-test_expect_success REBASE_P rebasep '\n-\n-\tgit checkout side-merge &&\n-\tgit rebase -p side &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual &&\n-\tgit cat-file commit side-merge-original | sed -e \"1,/^\\$/d\" >expect &&\n-\ttest_cmp expect actual\n-\n-'\n-\n test_done\ndiff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh\ndeleted file mode 100755\nindex ec8062a66ac..00000000000\n--- a/t/t3409-rebase-preserve-merges.sh\n+++ /dev/null\n@@ -1,130 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright(C) 2008 Stephen Habermann & Andreas Ericsson\n-#\n-test_description='git rebase -p should preserve merges\n-\n-Run \"git rebase -p\" and check that merges are properly carried along\n-'\n-GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n-export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-GIT_AUTHOR_EMAIL=bogus_email_address\n-export GIT_AUTHOR_EMAIL\n-\n-# Clone 2 (conflicting merge):\n-#\n-# A1--A2--B3   <-- origin/main\n-#  \\       \\\n-#   B1------M  <-- topic\n-#    \\\n-#     B2       <-- origin/topic\n-#\n-# Clone 3 (no-ff merge):\n-#\n-# A1--A2--B3   <-- origin/main\n-#  \\\n-#   B1------M  <-- topic\n-#    \\     /\n-#     \\--A3    <-- topic2\n-#      \\\n-#       B2     <-- origin/topic\n-#\n-# Clone 4 (same as Clone 3)\n-\n-test_expect_success 'setup for merge-preserving rebase' \\\n-\t'echo First > A &&\n-\tgit add A &&\n-\tgit commit -m \"Add A1\" &&\n-\tgit checkout -b topic &&\n-\techo Second > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add B1\" &&\n-\tgit checkout -f main &&\n-\techo Third >> A &&\n-\tgit commit -a -m \"Modify A2\" &&\n-\techo Fifth > B &&\n-\tgit add B &&\n-\tgit commit -m \"Add different B\" &&\n-\n-\tgit clone ./. clone2 &&\n-\t(\n-\t\tcd clone2 &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\ttest_must_fail git merge origin/main &&\n-\t\techo Resolved >B &&\n-\t\tgit add B &&\n-\t\tgit commit -m \"Merge origin/main into topic\"\n-\t) &&\n-\n-\tgit clone ./. clone3 &&\n-\t(\n-\t\tcd clone3 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit clone ./. clone4 &&\n-\t(\n-\t\tcd clone4 &&\n-\t\tgit checkout -b topic2 origin/topic &&\n-\t\techo Sixth > A &&\n-\t\tgit commit -a -m \"Modify A3\" &&\n-\t\tgit checkout -b topic origin/topic &&\n-\t\tgit merge --no-ff topic2\n-\t) &&\n-\n-\tgit checkout topic &&\n-\techo Fourth >> B &&\n-\tgit commit -a -m \"Modify B2\"\n-'\n-\n-test_expect_success '--continue works after a conflict' '\n-\t(\n-\tcd clone2 &&\n-\tgit fetch &&\n-\ttest_must_fail git rebase -p origin/topic &&\n-\ttest 2 = $(git ls-files B | wc -l) &&\n-\techo Resolved again > B &&\n-\ttest_must_fail git rebase --continue &&\n-\tgrep \"^@@@ \" .git/rebase-merge/patch &&\n-\tgit add B &&\n-\tgit rebase --continue &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Add different\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge origin\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p preserves no-ff merges' '\n-\t(\n-\tcd clone3 &&\n-\tgit fetch &&\n-\tgit rebase -p origin/topic &&\n-\ttest 3 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n-\ttest 1 = $(git rev-list --all --pretty=oneline | grep \"Merge branch\" | wc -l)\n-\t)\n-'\n-\n-test_expect_success 'rebase -p ignores merge.log config' '\n-\t(\n-\tcd clone4 &&\n-\tgit fetch &&\n-\tgit -c merge.log=1 rebase -p origin/topic &&\n-\techo >expected &&\n-\tgit log --format=\"%b\" -1 >current &&\n-\ttest_cmp expected current\n-\t)\n-'\n-\n-test_done\ndiff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh\ndeleted file mode 100755\nindex 2e29866993c..00000000000\n--- a/t/t3410-rebase-preserve-dropped-merges.sh\n+++ /dev/null\n@@ -1,90 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with preserve merges and ensures commits\n-dropped by the --cherry-pick flag have their childrens parents\n-rewritten.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-# set up two branches like this:\n-#\n-# A - B - C - D - E\n-#   \\\n-#     F - G - H\n-#       \\\n-#         I\n-#\n-# where B, D and G touch the same file.\n-\n-test_expect_success 'setup' '\n-\ttest_commit A file1 &&\n-\ttest_commit B file1 1 &&\n-\ttest_commit C file2 &&\n-\ttest_commit D file1 2 &&\n-\ttest_commit E file3 &&\n-\tgit checkout A &&\n-\ttest_commit F file4 &&\n-\ttest_commit G file1 3 &&\n-\ttest_commit H file5 &&\n-\tgit checkout F &&\n-\ttest_commit I file6\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L \\        -->   L\n-#       \\            |               \\\n-#         I -- G2 -- J -- K           I -- K\n-# G2 = same changes as G\n-test_expect_success 'skip same-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G2 file1 3 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J file1 23 &&\n-\ttest_commit K file7 file7 &&\n-\tgit rebase -i -p L &&\n-\ttest $(git rev-parse HEAD^^) = $(git rev-parse L) &&\n-\ttest \"23\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-# A - B - C - D - E\n-#   \\             \\ \\\n-#     F - G - H -- L2 \\        -->   L2\n-#       \\             |                \\\n-#         I -- G3 --- J2 -- K2           I -- G3 -- K2\n-# G2 = different changes as G\n-test_expect_success 'keep different-resolution merges with -p' '\n-\tgit checkout H &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit L2 file1 23 &&\n-\tgit checkout I &&\n-\ttest_commit G3 file1 4 &&\n-\ttest_must_fail git merge E &&\n-\ttest_commit J2 file1 24 &&\n-\ttest_commit K2 file7 file7 &&\n-\ttest_must_fail git rebase -i -p L2 &&\n-\techo 234 > file1 &&\n-\tgit add file1 &&\n-\tgit rebase --continue &&\n-\ttest $(git rev-parse HEAD^^^) = $(git rev-parse L2) &&\n-\ttest \"234\" = \"$(cat file1)\" &&\n-\ttest \"I\" = \"$(cat file6)\" &&\n-\ttest \"file7\" = \"$(cat file7)\"\n-'\n-\n-test_done\ndiff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh\ndeleted file mode 100755\nindex fb45e7bf7bd..00000000000\n--- a/t/t3411-rebase-preserve-around-merges.sh\n+++ /dev/null\n@@ -1,80 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2008 Stephen Haberman\n-#\n-\n-test_description='git rebase preserve merges\n-\n-This test runs git rebase with -p and tries to squash a commit from after\n-a merge to before the merge.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-set_fake_editor\n-\n-# set up two branches like this:\n-#\n-# A1 - B1 - D1 - E1 - F1\n-#       \\        /\n-#        -- C1 --\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit D1 &&\n-\ttest_merge E1 C1 &&\n-\ttest_commit F1\n-'\n-\n-# Should result in:\n-#\n-# A1 - B1 - D2 - E2\n-#       \\        /\n-#        -- C1 --\n-#\n-test_expect_success 'squash F1 into D1' '\n-\tFAKE_LINES=\"1 squash 4 2 3\" git rebase -i -p B1 &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse C1)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse B1)\" &&\n-\tgit tag E2\n-'\n-\n-# Start with:\n-#\n-# A1 - B1 - D2 - E2\n-#  \\\n-#   G1 ---- L1 ---- M1\n-#    \\             /\n-#     H1 -- J1 -- K1\n-#      \\         /\n-#        -- I1 --\n-#\n-# And rebase G1..M1 onto E2\n-\n-test_expect_success 'rebase two levels of merge' '\n-\tgit checkout A1 &&\n-\ttest_commit G1 &&\n-\ttest_commit H1 &&\n-\ttest_commit I1 &&\n-\tgit checkout -b branch3 H1 &&\n-\ttest_commit J1 &&\n-\ttest_merge K1 I1 &&\n-\tgit checkout -b branch2 G1 &&\n-\ttest_commit L1 &&\n-\ttest_merge M1 K1 &&\n-\tGIT_EDITOR=: git rebase -i -p E2 &&\n-\ttest \"$(git rev-parse HEAD~3)\" = \"$(git rev-parse E2)\" &&\n-\ttest \"$(git rev-parse HEAD~2)\" = \"$(git rev-parse HEAD^2^2~2)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse HEAD^2^2^1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh\nindex fda62c65bd5..19c6f4acbf6 100755\n--- a/t/t3412-rebase-root.sh\n+++ b/t/t3412-rebase-root.sh\n@@ -89,17 +89,6 @@ test_expect_success 'pre-rebase got correct input (4)' '\n \ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,work4\n '\n \n-test_expect_success REBASE_P 'rebase -i -p with linear history' '\n-\tgit checkout -b work5 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tgit log --pretty=tformat:\"%s\" > rebased5 &&\n-\ttest_cmp expect rebased5\n-'\n-\n-test_expect_success REBASE_P 'pre-rebase got correct input (5)' '\n-\ttest \"z$(cat .git/PRE-REBASE-INPUT)\" = z--root,\n-'\n-\n test_expect_success 'set up merge history' '\n \tgit checkout other^ &&\n \tgit checkout -b side &&\n@@ -123,13 +112,6 @@ commit work6~4\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with merge' '\n-\tgit checkout -b work6 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tlog_with_names work6 > rebased6 &&\n-\ttest_cmp expect-side rebased6\n-'\n-\n test_expect_success 'set up second root and merge' '\n \tgit symbolic-ref HEAD refs/heads/third &&\n \trm .git/index &&\n@@ -158,13 +140,6 @@ commit work7~5\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p with two roots' '\n-\tgit checkout -b work7 other &&\n-\tgit rebase -i -p --root --onto main &&\n-\tlog_with_names work7 > rebased7 &&\n-\ttest_cmp expect-third rebased7\n-'\n-\n test_expect_success 'setup pre-rebase hook that fails' '\n \tmkdir -p .git/hooks &&\n \tcat >.git/hooks/pre-rebase <<EOF &&\n@@ -264,21 +239,9 @@ commit conflict3~6\n 1\n EOF\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' '\n-\tgit checkout -b conflict3 other &&\n-\ttest_must_fail git rebase -i -p --root --onto main &&\n-\tgit ls-files -u | grep \"B$\"\n-'\n-\n test_expect_success 'fix the conflict' '\n \techo 3 > B &&\n \tgit add B\n '\n \n-test_expect_success REBASE_P 'rebase -i -p --root with conflict (second part)' '\n-\tgit rebase --continue &&\n-\tlog_with_names conflict3 >out &&\n-\ttest_cmp expect-conflict-p out\n-'\n-\n test_done\ndiff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh\ndeleted file mode 100755\nindex 72e04b5386a..00000000000\n--- a/t/t3414-rebase-preserve-onto.sh\n+++ /dev/null\n@@ -1,85 +0,0 @@\n-#!/bin/sh\n-#\n-# Copyright (c) 2009 Greg Price\n-#\n-\n-test_description='git rebase -p should respect --onto\n-\n-In a rebase with --onto, we should rewrite all the commits that\n-aren'\"'\"'t on top of $ONTO, even if they are on top of $UPSTREAM.\n-'\n-. ./test-lib.sh\n-\n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-. \"$TEST_DIRECTORY\"/lib-rebase.sh\n-\n-# Set up branches like this:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    H1\n-\n-test_expect_success 'setup' '\n-\ttest_commit A1 &&\n-\ttest_commit B1 &&\n-\ttest_commit C1 &&\n-\ttest_commit D1 &&\n-\tgit reset --hard B1 &&\n-\ttest_commit E1 &&\n-\ttest_commit F1 &&\n-\ttest_merge G1 D1 &&\n-\tgit reset --hard A1 &&\n-\ttest_commit H1\n-'\n-\n-# Now rebase merge G1 from both branches' base B1, both should move:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\\n-#     H1---E2---F2---G2\n-#      \\             /\n-#       \\--C2---D2--/\n-\n-test_expect_success 'rebase from B1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 B1 &&\n-\ttest \"$(git rev-parse HEAD^1^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2^1^1)\" = \"$(git rev-parse H1)\"\n-'\n-\n-# On the other hand if rebase from E1 which is within one branch,\n-# then the other branch stays:\n-# A1---B1---E1---F1---G1\n-#  \\    \\             /\n-#   \\    \\--C1---D1--/\n-#    \\             \\\n-#     H1-----F3-----G3\n-\n-test_expect_success 'rebase from E1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rebase -p --onto H1 E1 &&\n-\ttest \"$(git rev-parse HEAD^1^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^2)\" = \"$(git rev-parse D1)\"\n-'\n-\n-# And the same if we rebase from a commit in the second-parent branch.\n-# A1---B1---E1---F1----G1\n-#  \\    \\          \\   /\n-#   \\    \\--C1---D1-\\-/\n-#    \\               \\\n-#     H1------D3------G4\n-\n-test_expect_success 'rebase from C1 onto H1' '\n-\tgit checkout G1 &&\n-\tgit rev-list --first-parent --pretty=oneline C1..G1 &&\n-\tgit rebase -p --onto H1 C1 &&\n-\ttest \"$(git rev-parse HEAD^2^1)\" = \"$(git rev-parse H1)\" &&\n-\ttest \"$(git rev-parse HEAD^1)\" = \"$(git rev-parse F1)\"\n-'\n-\n-test_done\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex f4c2ee02bc9..b62c16026fc 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -109,20 +109,6 @@ test_expect_success 'rebase -i --continue handles merge strategy and options' '\n \ttest -f funny.was.run\n '\n \n-test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '\n-\trm -fr .git/rebase-* &&\n-\tgit reset --hard commit-new-file-F3-on-topic-branch &&\n-\ttest_commit theirs-to-merge &&\n-\tgit reset --hard HEAD^ &&\n-\ttest_commit some-commit &&\n-\ttest_tick &&\n-\tgit merge --no-ff theirs-to-merge &&\n-\tFAKE_LINES=\"1 edit 2 3\" git rebase -i -f -p -m \\\n-\t\t-s recursive --strategy-option=theirs HEAD~2 &&\n-\ttest_commit force-change &&\n-\tgit rebase --continue\n-'\n-\n test_expect_success 'rebase -r passes merge strategy options correctly' '\n \trm -fr .git/rebase-* &&\n \tgit reset --hard commit-new-file-F3-on-topic-branch &&\n@@ -258,7 +244,6 @@ test_rerere_autoupdate\n test_rerere_autoupdate -m\n GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR\n test_rerere_autoupdate -i\n-test_have_prereq !REBASE_P || test_rerere_autoupdate --preserve-merges\n unset GIT_SEQUENCE_EDITOR\n \n test_expect_success 'the todo command \"break\" works' '\ndiff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh\nindex 4a9204b4b64..62d86d557da 100755\n--- a/t/t3421-rebase-topology-linear.sh\n+++ b/t/t3421-rebase-topology-linear.sh\n@@ -29,7 +29,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_expect_success 'setup branches and remote tracking' '\n \tgit tag -l >tags &&\n@@ -53,7 +52,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -70,7 +68,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -87,7 +84,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -102,7 +98,6 @@ test_run_rebase success --apply\n test_run_rebase success --fork-point\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n #       f\n #      /\n@@ -142,7 +137,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -157,7 +151,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -172,7 +165,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -187,7 +179,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n # a---b---c---j!\n #      \\\n@@ -215,7 +206,6 @@ test_run_rebase () {\n test_run_rebase failure --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -229,7 +219,6 @@ test_run_rebase () {\n }\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -243,7 +232,6 @@ test_run_rebase () {\n }\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n test_run_rebase success --rebase-merges\n \n #       m\n@@ -283,7 +271,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -298,7 +285,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -313,7 +299,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -329,7 +314,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -344,7 +328,6 @@ test_run_rebase () {\n test_run_rebase success --apply\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -358,7 +341,6 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase failure -p\n \n test_run_rebase () {\n \tresult=$1\n@@ -373,6 +355,5 @@ test_run_rebase () {\n test_run_rebase success ''\n test_run_rebase success -m\n test_run_rebase success -i\n-test_have_prereq !REBASE_P || test_run_rebase success -p\n \n test_done\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex c8234062c6c..eb0a3d9d487 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -63,15 +63,4 @@ test_rebase_am_only () {\n test_rebase_am_only --whitespace=fix\n test_rebase_am_only -C4\n \n-test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --signoff A\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'--preserve-merges incompatible with --rebase-merges' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --preserve-merges --rebase-merges A\n-'\n-\n test_done\ndiff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh\nindex e42faa44e74..63acc1ea4da 100755\n--- a/t/t3425-rebase-topology-merges.sh\n+++ b/t/t3425-rebase-topology-merges.sh\n@@ -106,155 +106,4 @@ test_run_rebase success 'd n o e' --apply\n test_run_rebase success 'd n o e' -m\n test_run_rebase success 'd n o e' -i\n \n-if ! test_have_prereq REBASE_P; then\n-\tskip_all='skipping git rebase -p tests, as asked for'\n-\ttest_done\n-fi\n-\n-test_expect_success \"rebase -p is no-op in non-linear history\" \"\n-\treset_rebase &&\n-\tgit rebase -p d w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p is no-op when base inside second parent\" \"\n-\treset_rebase &&\n-\tgit rebase -p e w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_failure \"rebase -p --root on non-linear history is a no-op\" \"\n-\treset_rebase &&\n-\tgit rebase -p --root w &&\n-\ttest_cmp_rev w HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates merge from side branch\" \"\n-\treset_rebase &&\n-\tgit rebase -p z w &&\n-\ttest_cmp_rev z HEAD^ &&\n-\ttest_cmp_rev w^2 HEAD^2\n-\"\n-\n-test_expect_success \"rebase -p re-creates internal merge\" \"\n-\treset_rebase &&\n-\tgit rebase -p c w &&\n-\ttest_cmp_rev c HEAD~4 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~3 &&\n-\ttest_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p can re-create two branches on onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto c d w &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev c HEAD^2^ &&\n-\ttest_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-#       f\n-#      /\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--i\n-#        \\       \\\n-#         e-------u\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for patch-equivalence tests' '\n-\tgit checkout e &&\n-\ttest_merge u i\n-'\n-\n-test_expect_success \"rebase -p re-creates history around dropped commit matching upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p h u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history drops patches in upstream\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto f h u &&\n-\ttest_cmp_rev f HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p --onto in merged history does not drop patches in onto\" \"\n-\treset_rebase &&\n-\tgit rebase -p --onto h f u &&\n-\ttest_cmp_rev h HEAD~3 &&\n-\ttest_cmp_rev HEAD^2~2 HEAD~2 &&\n-\ttest_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD\n-\"\n-\n-# a---b---c---g---h\n-#      \\\n-#       d---gp--s\n-#        \\   \\ /\n-#         \\   X\n-#          \\ / \\\n-#           e---t\n-#\n-# gp = cherry-picked g\n-# h = reverted g\n-test_expect_success 'setup of non-linear-history for dropping whole side' '\n-\tgit checkout gp &&\n-\ttest_merge s e &&\n-\tgit checkout e &&\n-\ttest_merge t gp\n-'\n-\n-test_expect_failure \"rebase -p drops merge commit when entire first-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h s &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-test_expect_success \"rebase -p drops merge commit when entire second-parent side is dropped\" \"\n-\treset_rebase &&\n-\tgit rebase -p h t &&\n-\ttest_cmp_rev h HEAD~2 &&\n-\ttest_linear_range 'd e' h..\n-\"\n-\n-# a---b---c\n-#      \\\n-#       d---e\n-#        \\   \\\n-#         n---r\n-#          \\\n-#           o\n-#\n-# r = tree-same with n\n-test_expect_success 'setup of non-linear-history for empty commits' '\n-\tgit checkout n &&\n-\tgit merge --no-commit e &&\n-\tgit reset n . &&\n-\tgit commit -m r &&\n-\tgit reset --hard &&\n-\tgit clean -f &&\n-\tgit tag r\n-'\n-\n-test_expect_success \"rebase -p re-creates empty internal merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p c r &&\n-\ttest_cmp_rev c HEAD~3 &&\n-\ttest_cmp_rev HEAD^2^ HEAD~2 &&\n-\ttest_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD\n-\"\n-\n-test_expect_success \"rebase -p re-creates empty merge commit\" \"\n-\treset_rebase &&\n-\tgit rebase -p o r &&\n-\ttest_cmp_rev e HEAD^2 &&\n-\ttest_cmp_rev o HEAD^ &&\n-\ttest_revision_subjects 'r' HEAD\n-\"\n-\n test_done\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex e78c7e37969..48b76f82325 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -36,11 +36,10 @@ commit_message() {\n # where the root commit adds three files: topic_1.t, topic_2.t and topic_3.t.\n #\n # This commit history is then rebased onto `topic_3` with the\n-# `-Xsubtree=files_subtree` option in three different ways:\n+# `-Xsubtree=files_subtree` option in two different ways:\n #\n-# 1. using `--preserve-merges`\n-# 2. using `--preserve-merges` and --keep-empty\n-# 3. without specifying a rebase backend\n+# 1. without specifying a rebase backend\n+# 2. using the `--rebase-merges` backend\n \n test_expect_success 'setup' '\n \ttest_commit README &&\n@@ -69,25 +68,6 @@ test_expect_success 'setup' '\n \tgit commit -m \"Empty commit\" --allow-empty\n '\n \n-# FAILURE: Does not preserve topic_4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-main main &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"topic_4\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"files_subtree/topic_5\"\n-'\n-\n-# FAILURE: Does not preserve topic_4.\n-test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-main main &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"topic_4\" &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/topic_5\" &&\n-\tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n-'\n-\n test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\ndiff --git a/t/t5520-pull.sh b/t/t5520-pull.sh\nindex bb9b6b900eb..a2924036ad4 100755\n--- a/t/t5520-pull.sh\n+++ b/t/t5520-pull.sh\n@@ -546,15 +546,6 @@ test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success REBASE_P \\\n-\t'pull.rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase preserve &&\n-\tgit pull . copy &&\n-\ttest_cmp_rev HEAD^^ copy &&\n-\ttest_cmp_rev HEAD^2 keep-merge\n-'\n-\n test_expect_success 'pull.rebase=interactive' '\n \twrite_script \"$TRASH_DIRECTORY/fake-editor\" <<-\\EOF &&\n \techo I was here >fake.out &&\n@@ -606,15 +597,6 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' '\n \ttest_cmp expect actual\n '\n \n-test_expect_success REBASE_P \\\n-\t'--rebase=preserve rebases and merges keep-merge' '\n-\tgit reset --hard before-preserve-rebase &&\n-\ttest_config pull.rebase true &&\n-\tgit pull --rebase=preserve . copy &&\n-\ttest_cmp_rev HEAD^^ copy &&\n-\ttest_cmp_rev HEAD^2 keep-merge\n-'\n-\n test_expect_success '--rebase=invalid fails' '\n \tgit reset --hard before-preserve-rebase &&\n \ttest_must_fail git pull --rebase=invalid . copy\ndiff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh\nindex 7a8194ce720..2a07c708679 100755\n--- a/t/t7505-prepare-commit-msg-hook.sh\n+++ b/t/t7505-prepare-commit-msg-hook.sh\n@@ -250,7 +250,6 @@ test_rebase () {\n }\n \n test_rebase success\n-test_have_prereq !REBASE_P || test_rebase success -p\n \n test_expect_success 'with hook (cherry-pick)' '\n \ttest_when_finished \"git checkout -f main\" &&\ndiff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\nindex 405420ae4d8..163ae804685 100755\n--- a/t/t7517-per-repo-email.sh\n+++ b/t/t7517-per-repo-email.sh\n@@ -75,19 +75,6 @@ test_expect_success 'noop interactive rebase does not care about ident' '\n \tgit rebase -i HEAD^\n '\n \n-test_expect_success REBASE_P \\\n-\t'fast-forward rebase does not care about ident (preserve)' '\n-\tgit checkout -B tmp side-without-commit &&\n-\tgit rebase -p main\n-'\n-\n-test_expect_success REBASE_P \\\n-\t'non-fast-forward rebase refuses to write commits (preserve)' '\n-\ttest_when_finished \"git rebase --abort || true\" &&\n-\tgit checkout -B tmp side-with-commit &&\n-\ttest_must_fail git rebase -p main\n-'\n-\n test_expect_success 'author.name overrides user.name' '\n \ttest_config user.name user &&\n \ttest_config user.email user@example.com &&\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex abcfbed6d61..11a9c8a6516 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -1708,10 +1708,6 @@ test_lazy_prereq SHA1 '\n \tesac\n '\n \n-test_lazy_prereq REBASE_P '\n-\ttest -z \"$GIT_TEST_SKIP_REBASE_P\"\n-'\n-\n # Ensure that no test accidentally triggers a Git command\n # that runs the actual maintenance scheduler, affecting a user's\n # system permanently.\n-- \ngitgitgadget\n\n"},{"id":"434939","messageId":"6e45e90abe59395a13ae5872ab706aff173152f4.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 04/11] pull: remove support for `--rebase=preserve`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:05Z","receivedAt":"2021-09-07T21:05:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn preparation for `git-rebase--preserve-merges.sh` entering its after\nlife, we remove this (deprecated) option that would still rely on it.\n\nTo help users transition who still did not receive the memo about the\ndeprecation, we offer a helpful error message instead of throwing our\nhands in the air and saying that we don't know that option, never heard\nof it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config/branch.txt        | 4 ----\n Documentation/config/pull.txt          | 4 ----\n Documentation/git-pull.txt             | 6 +-----\n builtin/pull.c                         | 9 +++------\n contrib/completion/git-completion.bash | 2 +-\n rebase.c                               | 5 +++--\n rebase.h                               | 1 -\n 7 files changed, 8 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt\nindex cc5f3249fc5..d323d7327f6 100644\n--- a/Documentation/config/branch.txt\n+++ b/Documentation/config/branch.txt\n@@ -85,10 +85,6 @@ When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive` (or just 'i'), the rebase is run in interactive\n mode.\n +\ndiff --git a/Documentation/config/pull.txt b/Documentation/config/pull.txt\nindex 54048306095..9349e09261b 100644\n--- a/Documentation/config/pull.txt\n+++ b/Documentation/config/pull.txt\n@@ -18,10 +18,6 @@ When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'\n so that the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When `preserve` (or just 'p', deprecated in favor of `merges`), also pass\n-`--preserve-merges` along to 'git rebase' so that locally committed merge\n-commits will not be flattened by running 'git pull'.\n-+\n When the value is `interactive` (or just 'i'), the rebase is run in interactive\n mode.\n +\ndiff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt\nindex 7f4b2d1982e..7144690a0cb 100644\n--- a/Documentation/git-pull.txt\n+++ b/Documentation/git-pull.txt\n@@ -102,7 +102,7 @@ Options related to merging\n include::merge-options.txt[]\n \n -r::\n---rebase[=false|true|merges|preserve|interactive]::\n+--rebase[=false|true|merges|interactive]::\n \tWhen true, rebase the current branch on top of the upstream\n \tbranch after fetching. If there is a remote-tracking branch\n \tcorresponding to the upstream branch and the upstream branch\n@@ -113,10 +113,6 @@ When set to `merges`, rebase using `git rebase --rebase-merges` so that\n the local merge commits are included in the rebase (see\n linkgit:git-rebase[1] for details).\n +\n-When set to `preserve` (deprecated in favor of `merges`), rebase with the\n-`--preserve-merges` option passed to `git rebase` so that locally created\n-merge commits will not be flattened.\n-+\n When false, merge the upstream branch into the current branch.\n +\n When `interactive`, enable the interactive mode of rebase.\ndiff --git a/builtin/pull.c b/builtin/pull.c\nindex 3e13f810843..bda5c32ab6f 100644\n--- a/builtin/pull.c\n+++ b/builtin/pull.c\n@@ -30,9 +30,8 @@\n /**\n  * Parses the value of --rebase. If value is a false value, returns\n  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is\n- * \"merges\", returns REBASE_MERGES. If value is \"preserve\", returns\n- * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if\n- * fatal is true, otherwise returns REBASE_INVALID.\n+ * \"merges\", returns REBASE_MERGES. If value is a invalid value, dies with\n+ * a fatal error if fatal is true, otherwise returns REBASE_INVALID.\n  */\n static enum rebase_type parse_config_rebase(const char *key, const char *value,\n \t\tint fatal)\n@@ -126,7 +125,7 @@ static struct option pull_options[] = {\n \t/* Options passed to git-merge or git-rebase */\n \tOPT_GROUP(N_(\"Options related to merging\")),\n \tOPT_CALLBACK_F('r', \"rebase\", &opt_rebase,\n-\t\t\"(false|true|merges|preserve|interactive)\",\n+\t\t\"(false|true|merges|interactive)\",\n \t\tN_(\"incorporate changes by rebasing rather than merging\"),\n \t\tPARSE_OPT_OPTARG, parse_opt_rebase),\n \tOPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,\n@@ -883,8 +882,6 @@ static int run_rebase(const struct object_id *newbase,\n \t/* Options passed to git-rebase */\n \tif (opt_rebase == REBASE_MERGES)\n \t\tstrvec_push(&args, \"--rebase-merges\");\n-\telse if (opt_rebase == REBASE_PRESERVE)\n-\t\tstrvec_push(&args, \"--preserve-merges\");\n \telse if (opt_rebase == REBASE_INTERACTIVE)\n \t\tstrvec_push(&args, \"--interactive\");\n \tif (opt_diffstat)\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc87..5dab8bd579e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2543,7 +2543,7 @@ __git_complete_config_variable_value ()\n \t\treturn\n \t\t;;\n \tbranch.*.rebase)\n-\t\t__gitcomp \"false true merges preserve interactive\" \"\" \"$cur_\"\n+\t\t__gitcomp \"false true merges interactive\" \"\" \"$cur_\"\n \t\treturn\n \t\t;;\n \tremote.pushdefault)\ndiff --git a/rebase.c b/rebase.c\nindex f8137d859b5..6775cddb284 100644\n--- a/rebase.c\n+++ b/rebase.c\n@@ -1,5 +1,6 @@\n #include \"rebase.h\"\n #include \"config.h\"\n+#include \"gettext.h\"\n \n /*\n  * Parses textual value for pull.rebase, branch.<name>.rebase, etc.\n@@ -20,12 +21,12 @@ enum rebase_type rebase_parse_value(const char *value)\n \t\treturn REBASE_FALSE;\n \telse if (v > 0)\n \t\treturn REBASE_TRUE;\n-\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n-\t\treturn REBASE_PRESERVE;\n \telse if (!strcmp(value, \"merges\") || !strcmp(value, \"m\"))\n \t\treturn REBASE_MERGES;\n \telse if (!strcmp(value, \"interactive\") || !strcmp(value, \"i\"))\n \t\treturn REBASE_INTERACTIVE;\n+\telse if (!strcmp(value, \"preserve\") || !strcmp(value, \"p\"))\n+\t\terror(_(\"%s: 'preserve' superseded by 'merges'\"), value);\n \t/*\n \t * Please update _git_config() in git-completion.bash when you\n \t * add new rebase modes.\ndiff --git a/rebase.h b/rebase.h\nindex cc723d47489..203b4372823 100644\n--- a/rebase.h\n+++ b/rebase.h\n@@ -5,7 +5,6 @@ enum rebase_type {\n \tREBASE_INVALID = -1,\n \tREBASE_FALSE = 0,\n \tREBASE_TRUE,\n-\tREBASE_PRESERVE,\n \tREBASE_MERGES,\n \tREBASE_INTERACTIVE\n };\n-- \ngitgitgadget\n\n"},{"id":"434941","messageId":"913647d8e76b74bfd2de77463aea14d501489186.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 06/11] git-svn: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:07Z","receivedAt":"2021-09-07T21:05:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe already passed the `--rebase-merges` option to `git rebase` instead,\nnow we make this move permanent.\n\nAs pointed out by Ævar Arnfjörð Bjarmason, in contrast to the\ndeprecation of `git rebase`'s `--preserve-merges` backend, `git svn`\nonly deprecated this option in v2.25.0 (because this developer missed\n`git svn`'s use of that backend when deprecating the rebase backend\nrunning up to Git v2.22).\n\nStill, v2.25.0 has been released on January 13th, 2020. In other words,\n`git svn` deprecated this option over one and a half years ago, _and_\nhas been redirecting to the `--rebase-merges` option during all that\ntime (read: `git svn rebase --preserve-merges` didn't do _precisely_\nwhat the user asked, since v2.25.0, anyway, it fell back to pretending\nthat the user asked for `git svn rebase --rebase-merges` instead).\n\nIt is time to act on that deprecation and remove that option after all.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-svn.txt | 1 -\n git-svn.perl              | 1 -\n 2 files changed, 2 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex d5776ffcfd5..222b556d7a9 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -678,7 +678,6 @@ config key: svn.authorsProg\n --strategy=<strategy>::\n -p::\n --rebase-merges::\n---preserve-merges (DEPRECATED)::\n \tThese are only used with the 'dcommit' and 'rebase' commands.\n +\n Passed directly to 'git rebase' when using 'dcommit' if a\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 70cb5e2a83b..be987e316f9 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -273,7 +273,6 @@ my %cmd = (\n \t\t\t  'fetch-all|all' => \\$_fetch_all,\n \t\t\t  'dry-run|n' => \\$_dry_run,\n \t\t\t  'rebase-merges|p' => \\$_rebase_merges,\n-\t\t\t  'preserve-merges|p' => \\$_rebase_merges,\n \t\t\t  %fc_opts } ],\n \t'commit-diff' => [ \\&cmd_commit_diff,\n \t                   'Commit a diff between two trees',\n-- \ngitgitgadget\n\n"},{"id":"434943","messageId":"2d7a4a2c564aaafbf8da97cf017766163c77b70b.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 05/11] rebase: drop support for `--preserve-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:06Z","receivedAt":"2021-09-07T21:05:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThis option was deprecated in favor of `--rebase-merges` some time ago,\nand now we retire it.\n\nTo assist users to transition away, we do not _actually_ remove the\noption, but now we no longer implement the functionality. Instead, we\noffer a helpful error message suggesting which option to use.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n .gitignore                     |    1 -\n Documentation/git-rebase.txt   |   51 --\n Makefile                       |    2 -\n builtin/rebase.c               |  138 +----\n git-rebase--preserve-merges.sh | 1057 --------------------------------\n 5 files changed, 11 insertions(+), 1238 deletions(-)\n delete mode 100644 git-rebase--preserve-merges.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 311841f9bed..98d6275b20d 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -125,7 +125,6 @@\n /git-range-diff\n /git-read-tree\n /git-rebase\n-/git-rebase--preserve-merges\n /git-receive-pack\n /git-reflog\n /git-remote\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 55af6fd24e2..1382dc6f005 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -525,29 +525,12 @@ i.e. commits that would be excluded by linkgit:git-log[1]'s\n the `rebase-cousins` mode is turned on, such commits are instead rebased\n onto `<upstream>` (or `<onto>`, if specified).\n +\n-The `--rebase-merges` mode is similar in spirit to the deprecated\n-`--preserve-merges` but works with interactive rebases,\n-where commits can be reordered, inserted and dropped at will.\n-+\n It is currently only possible to recreate the merge commits using the\n `recursive` merge strategy; Different merge strategies can be used only via\n explicit `exec git merge -s <strategy> [...]` commands.\n +\n See also REBASING MERGES and INCOMPATIBLE OPTIONS below.\n \n--p::\n---preserve-merges::\n-\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n-\tinstead of flattening the history by replaying commits a merge commit\n-\tintroduces. Merge conflict resolutions or manual amendments to merge\n-\tcommits are not preserved.\n-+\n-This uses the `--interactive` machinery internally, but combining it\n-with the `--interactive` option explicitly is generally not a good\n-idea unless you know what you are doing (see BUGS below).\n-+\n-See also INCOMPATIBLE OPTIONS below.\n-\n -x <cmd>::\n --exec <cmd>::\n \tAppend \"exec <cmd>\" after each line creating a commit in the\n@@ -579,9 +562,6 @@ See also INCOMPATIBLE OPTIONS below.\n \tthe root commit(s) on a branch.  When used with --onto, it\n \twill skip changes already contained in <newbase> (instead of\n \t<upstream>) whereas without --onto it will operate on every change.\n-\tWhen used together with both --onto and --preserve-merges,\n-\t'all' root commits will be rewritten to have <newbase> as parent\n-\tinstead.\n +\n See also INCOMPATIBLE OPTIONS below.\n \n@@ -643,7 +623,6 @@ are incompatible with the following options:\n  * --allow-empty-message\n  * --[no-]autosquash\n  * --rebase-merges\n- * --preserve-merges\n  * --interactive\n  * --exec\n  * --no-keep-empty\n@@ -654,13 +633,6 @@ are incompatible with the following options:\n \n In addition, the following pairs of options are incompatible:\n \n- * --preserve-merges and --interactive\n- * --preserve-merges and --signoff\n- * --preserve-merges and --rebase-merges\n- * --preserve-merges and --empty=\n- * --preserve-merges and --ignore-whitespace\n- * --preserve-merges and --committer-date-is-author-date\n- * --preserve-merges and --ignore-date\n  * --keep-base and --onto\n  * --keep-base and --root\n  * --fork-point and --root\n@@ -1274,29 +1246,6 @@ CONFIGURATION\n include::config/rebase.txt[]\n include::config/sequencer.txt[]\n \n-BUGS\n-----\n-The todo list presented by the deprecated `--preserve-merges --interactive`\n-does not represent the topology of the revision graph (use `--rebase-merges`\n-instead).  Editing commits and rewording their commit messages should work\n-fine, but attempts to reorder commits tend to produce counterintuitive results.\n-Use `--rebase-merges` in such scenarios instead.\n-\n-For example, an attempt to rearrange\n-------------\n-1 --- 2 --- 3 --- 4 --- 5\n-------------\n-to\n-------------\n-1 --- 2 --- 4 --- 3 --- 5\n-------------\n-by moving the \"pick 4\" line will result in the following history:\n-------------\n-\t3\n-       /\n-1 --- 2 --- 4 --- 5\n-------------\n-\n GIT\n ---\n Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex 9573190f1d7..43f93f61660 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -616,7 +616,6 @@ SCRIPT_SH += git-submodule.sh\n SCRIPT_SH += git-web--browse.sh\n \n SCRIPT_LIB += git-mergetool--lib\n-SCRIPT_LIB += git-rebase--preserve-merges\n SCRIPT_LIB += git-sh-i18n\n SCRIPT_LIB += git-sh-setup\n \n@@ -2649,7 +2648,6 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \\\n \t--keyword=__ --keyword=N__ --keyword=\"__n:1,2\"\n LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)\n LOCALIZED_SH = $(SCRIPT_SH)\n-LOCALIZED_SH += git-rebase--preserve-merges.sh\n LOCALIZED_SH += git-sh-setup.sh\n LOCALIZED_PERL = $(SCRIPT_PERL)\n \ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 33e09619005..5f8d9f89ba4 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, \"rebase-merge\")\n enum rebase_type {\n \tREBASE_UNSPECIFIED = -1,\n \tREBASE_APPLY,\n-\tREBASE_MERGE,\n-\tREBASE_PRESERVE_MERGES\n+\tREBASE_MERGE\n };\n \n enum empty_type {\n@@ -571,8 +570,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n \n static int is_merge(struct rebase_options *opts)\n {\n-\treturn opts->type == REBASE_MERGE ||\n-\t\topts->type == REBASE_PRESERVE_MERGES;\n+\treturn opts->type == REBASE_MERGE;\n }\n \n static void imply_merge(struct rebase_options *opts, const char *option)\n@@ -582,7 +580,6 @@ static void imply_merge(struct rebase_options *opts, const char *option)\n \t\tdie(_(\"%s requires the merge backend\"), option);\n \t\tbreak;\n \tcase REBASE_MERGE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\tbreak;\n \tdefault:\n \t\topts->type = REBASE_MERGE; /* implied */\n@@ -773,17 +770,6 @@ static struct commit *peel_committish(const char *name)\n \treturn (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);\n }\n \n-static void add_var(struct strbuf *buf, const char *name, const char *value)\n-{\n-\tif (!value)\n-\t\tstrbuf_addf(buf, \"unset %s; \", name);\n-\telse {\n-\t\tstrbuf_addf(buf, \"%s=\", name);\n-\t\tsq_quote_buf(buf, value);\n-\t\tstrbuf_addstr(buf, \"; \");\n-\t}\n-}\n-\n static int move_to_original_branch(struct rebase_options *opts)\n {\n \tstruct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;\n@@ -940,10 +926,7 @@ static int run_am(struct rebase_options *opts)\n \n static int run_specific_rebase(struct rebase_options *opts, enum action action)\n {\n-\tconst char *argv[] = { NULL, NULL };\n-\tstruct strbuf script_snippet = STRBUF_INIT, buf = STRBUF_INIT;\n \tint status;\n-\tconst char *backend, *backend_func;\n \n \tif (opts->type == REBASE_MERGE) {\n \t\t/* Run sequencer-based rebase */\n@@ -960,87 +943,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t\t}\n \n \t\tstatus = run_sequencer_rebase(opts, action);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tif (opts->type == REBASE_APPLY) {\n+\t} else if (opts->type == REBASE_APPLY)\n \t\tstatus = run_am(opts);\n-\t\tgoto finished_rebase;\n-\t}\n-\n-\tadd_var(&script_snippet, \"GIT_DIR\", absolute_path(get_git_dir()));\n-\tadd_var(&script_snippet, \"state_dir\", opts->state_dir);\n-\n-\tadd_var(&script_snippet, \"upstream_name\", opts->upstream_name);\n-\tadd_var(&script_snippet, \"upstream\", opts->upstream ?\n-\t\toid_to_hex(&opts->upstream->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"head_name\",\n-\t\topts->head_name ? opts->head_name : \"detached HEAD\");\n-\tadd_var(&script_snippet, \"orig_head\", oid_to_hex(&opts->orig_head));\n-\tadd_var(&script_snippet, \"onto\", opts->onto ?\n-\t\toid_to_hex(&opts->onto->object.oid) : NULL);\n-\tadd_var(&script_snippet, \"onto_name\", opts->onto_name);\n-\tadd_var(&script_snippet, \"revisions\", opts->revisions);\n-\tadd_var(&script_snippet, \"restrict_revision\", opts->restrict_revision ?\n-\t\toid_to_hex(&opts->restrict_revision->object.oid) : NULL);\n-\tsq_quote_argv_pretty(&buf, opts->git_am_opts.v);\n-\tadd_var(&script_snippet, \"git_am_opt\", buf.buf);\n-\tstrbuf_release(&buf);\n-\tadd_var(&script_snippet, \"verbose\",\n-\t\topts->flags & REBASE_VERBOSE ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"diffstat\",\n-\t\topts->flags & REBASE_DIFFSTAT ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"force_rebase\",\n-\t\topts->flags & REBASE_FORCE ? \"t\" : \"\");\n-\tif (opts->switch_to)\n-\t\tadd_var(&script_snippet, \"switch_to\", opts->switch_to);\n-\tadd_var(&script_snippet, \"action\", opts->action ? opts->action : \"\");\n-\tadd_var(&script_snippet, \"signoff\", opts->signoff ? \"--signoff\" : \"\");\n-\tadd_var(&script_snippet, \"allow_rerere_autoupdate\",\n-\t\topts->allow_rerere_autoupdate ?\n-\t\t\topts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?\n-\t\t\t\"--rerere-autoupdate\" : \"--no-rerere-autoupdate\" : \"\");\n-\tadd_var(&script_snippet, \"keep_empty\", opts->keep_empty ? \"yes\" : \"\");\n-\tadd_var(&script_snippet, \"autosquash\", opts->autosquash ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"gpg_sign_opt\", opts->gpg_sign_opt);\n-\tadd_var(&script_snippet, \"cmd\", opts->cmd);\n-\tadd_var(&script_snippet, \"allow_empty_message\",\n-\t\topts->allow_empty_message ?  \"--allow-empty-message\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_merges\",\n-\t\topts->rebase_merges ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"rebase_cousins\",\n-\t\topts->rebase_cousins ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"strategy\", opts->strategy);\n-\tadd_var(&script_snippet, \"strategy_opts\", opts->strategy_opts);\n-\tadd_var(&script_snippet, \"rebase_root\", opts->root ? \"t\" : \"\");\n-\tadd_var(&script_snippet, \"squash_onto\",\n-\t\topts->squash_onto ? oid_to_hex(opts->squash_onto) : \"\");\n-\tadd_var(&script_snippet, \"git_format_patch_opt\",\n-\t\topts->git_format_patch_opt.buf);\n-\n-\tif (is_merge(opts) &&\n-\t    !(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {\n-\t\tstrbuf_addstr(&script_snippet,\n-\t\t\t      \"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; \");\n-\t\topts->autosquash = 0;\n-\t}\n-\n-\tswitch (opts->type) {\n-\tcase REBASE_PRESERVE_MERGES:\n-\t\tbackend = \"git-rebase--preserve-merges\";\n-\t\tbackend_func = \"git_rebase__preserve_merges\";\n-\t\tbreak;\n-\tdefault:\n+\telse\n \t\tBUG(\"Unhandled rebase type %d\", opts->type);\n-\t\tbreak;\n-\t}\n-\n-\tstrbuf_addf(&script_snippet,\n-\t\t    \". git-sh-setup && . %s && %s\", backend, backend_func);\n-\targv[0] = script_snippet.buf;\n \n-\tstatus = run_command_v_opt(argv, RUN_USING_SHELL);\n-finished_rebase:\n \tif (opts->dont_finish_rebase)\n \t\t; /* do nothing */\n \telse if (opts->type == REBASE_MERGE)\n@@ -1058,8 +965,6 @@ finished_rebase:\n \t\tdie(\"Nothing to do\");\n \t}\n \n-\tstrbuf_release(&script_snippet);\n-\n \treturn status ? -1 : 0;\n }\n \n@@ -1313,6 +1218,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tchar *squash_onto_name = NULL;\n \tint reschedule_failed_exec = -1;\n \tint allow_preemptive_ff = 1;\n+\tint preserve_merges_selected = 0;\n \tstruct option builtin_rebase_options[] = {\n \t\tOPT_STRING(0, \"onto\", &options.onto_name,\n \t\t\t   N_(\"revision\"),\n@@ -1377,10 +1283,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"let the user edit the list of commits to rebase\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\tparse_opt_interactive),\n-\t\tOPT_SET_INT_F('p', \"preserve-merges\", &options.type,\n+\t\tOPT_SET_INT_F('p', \"preserve-merges\", &preserve_merges_selected,\n \t\t\t      N_(\"(DEPRECATED) try to recreate merges instead of \"\n \t\t\t\t \"ignoring them\"),\n-\t\t\t      REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),\n+\t\t\t      1, PARSE_OPT_HIDDEN),\n \t\tOPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),\n \t\tOPT_CALLBACK_F(0, \"empty\", &options, \"{drop,keep,ask}\",\n \t\t\t       N_(\"how to handle commits that become empty\"),\n@@ -1448,8 +1354,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_reset(&buf);\n \t\tstrbuf_addf(&buf, \"%s/rewritten\", merge_dir());\n \t\tif (is_directory(buf.buf)) {\n-\t\t\toptions.type = REBASE_PRESERVE_MERGES;\n-\t\t\toptions.flags |= REBASE_INTERACTIVE_EXPLICIT;\n+\t\t\tdie(\"`rebase -p` is no longer supported\");\n \t\t} else {\n \t\t\tstrbuf_reset(&buf);\n \t\t\tstrbuf_addf(&buf, \"%s/interactive\", merge_dir());\n@@ -1470,6 +1375,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t     builtin_rebase_options,\n \t\t\t     builtin_rebase_usage, 0);\n \n+\tif (preserve_merges_selected)\n+\t\tdie(_(\"--preserve-merges was replaced by --rebase-merges\"));\n+\n \tif (action != ACTION_NONE && total_argc != 2) {\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n@@ -1479,10 +1387,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(builtin_rebase_usage,\n \t\t\t\t   builtin_rebase_options);\n \n-\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\twarning(_(\"git rebase --preserve-merges is deprecated. \"\n-\t\t\t  \"Use --rebase-merges instead.\"));\n-\n \tif (keep_base) {\n \t\tif (options.onto_name)\n \t\t\tdie(_(\"cannot combine '--keep-base' with '--onto'\"));\n@@ -1728,7 +1632,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tcase REBASE_APPLY:\n \t\t\tdie(_(\"--strategy requires --merge or --interactive\"));\n \t\tcase REBASE_MERGE:\n-\t\tcase REBASE_PRESERVE_MERGES:\n \t\t\t/* compatible */\n \t\t\tbreak;\n \t\tcase REBASE_UNSPECIFIED:\n@@ -1780,7 +1683,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \n \tswitch (options.type) {\n \tcase REBASE_MERGE:\n-\tcase REBASE_PRESERVE_MERGES:\n \t\toptions.state_dir = merge_dir();\n \t\tbreak;\n \tcase REBASE_APPLY:\n@@ -1805,28 +1707,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\toptions.reschedule_failed_exec = reschedule_failed_exec;\n \n \tif (options.signoff) {\n-\t\tif (options.type == REBASE_PRESERVE_MERGES)\n-\t\t\tdie(\"cannot combine '--signoff' with \"\n-\t\t\t    \"'--preserve-merges'\");\n \t\tstrvec_push(&options.git_am_opts, \"--signoff\");\n \t\toptions.flags |= REBASE_FORCE;\n \t}\n \n-\tif (options.type == REBASE_PRESERVE_MERGES) {\n-\t\t/*\n-\t\t * Note: incompatibility with --signoff handled in signoff block above\n-\t\t * Note: incompatibility with --interactive is just a strong warning;\n-\t\t *       git-rebase.txt caveats with \"unless you know what you are doing\"\n-\t\t */\n-\t\tif (options.rebase_merges)\n-\t\t\tdie(_(\"cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--rebase-merges'\"));\n-\n-\t\tif (options.reschedule_failed_exec)\n-\t\t\tdie(_(\"error: cannot combine '--preserve-merges' with \"\n-\t\t\t      \"'--reschedule-failed-exec'\"));\n-\t}\n-\n \tif (!options.root) {\n \t\tif (argc < 1) {\n \t\t\tstruct branch *branch;\ndiff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh\ndeleted file mode 100644\nindex b9c71d2a71b..00000000000\n--- a/git-rebase--preserve-merges.sh\n+++ /dev/null\n@@ -1,1057 +0,0 @@\n-# This shell script fragment is sourced by git-rebase to implement its\n-# preserve-merges mode.\n-#\n-# Copyright (c) 2006 Johannes E. Schindelin\n-#\n-# The file containing rebase commands, comments, and empty lines.\n-# This file is created by \"git rebase -i\" then edited by the user.  As\n-# the lines are processed, they are removed from the front of this\n-# file and written to the tail of $done.\n-todo=\"$state_dir\"/git-rebase-todo\n-\n-# The rebase command lines that have already been processed.  A line\n-# is moved here when it is first handled, before any associated user\n-# actions.\n-done=\"$state_dir\"/done\n-\n-# The commit message that is planned to be used for any changes that\n-# need to be committed following a user interaction.\n-msg=\"$state_dir\"/message\n-\n-# The file into which is accumulated the suggested commit message for\n-# squash/fixup commands.  When the first of a series of squash/fixups\n-# is seen, the file is created and the commit message from the\n-# previous commit and from the first squash/fixup commit are written\n-# to it.  The commit message for each subsequent squash/fixup commit\n-# is appended to the file as it is processed.\n-#\n-# The first line of the file is of the form\n-#     # This is a combination of $count commits.\n-# where $count is the number of commits whose messages have been\n-# written to the file so far (including the initial \"pick\" commit).\n-# Each time that a commit message is processed, this line is read and\n-# updated.  It is deleted just before the combined commit is made.\n-squash_msg=\"$state_dir\"/message-squash\n-\n-# If the current series of squash/fixups has not yet included a squash\n-# command, then this file exists and holds the commit message of the\n-# original \"pick\" commit.  (If the series ends without a \"squash\"\n-# command, then this can be used as the commit message of the combined\n-# commit without opening the editor.)\n-fixup_msg=\"$state_dir\"/message-fixup\n-\n-# $rewritten is the name of a directory containing files for each\n-# commit that is reachable by at least one merge base of $head and\n-# $upstream. They are not necessarily rewritten, but their children\n-# might be.  This ensures that commits on merged, but otherwise\n-# unrelated side branches are left alone. (Think \"X\" in the man page's\n-# example.)\n-rewritten=\"$state_dir\"/rewritten\n-\n-dropped=\"$state_dir\"/dropped\n-\n-end=\"$state_dir\"/end\n-msgnum=\"$state_dir\"/msgnum\n-\n-# A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE that will be used for the commit that is currently\n-# being rebased.\n-author_script=\"$state_dir\"/author-script\n-\n-# When an \"edit\" rebase command is being processed, the SHA1 of the\n-# commit to be edited is recorded in this file.  When \"git rebase\n-# --continue\" is executed, if there are any staged changes then they\n-# will be amended to the HEAD commit, but only provided the HEAD\n-# commit is still the commit to be edited.  When any other rebase\n-# command is processed, this file is deleted.\n-amend=\"$state_dir\"/amend\n-\n-# For the post-rewrite hook, we make a list of rewritten commits and\n-# their new sha1s.  The rewritten-pending list keeps the sha1s of\n-# commits that have been processed, but not committed yet,\n-# e.g. because they are waiting for a 'squash' command.\n-rewritten_list=\"$state_dir\"/rewritten-list\n-rewritten_pending=\"$state_dir\"/rewritten-pending\n-\n-# Work around Git for Windows' Bash whose \"read\" does not strip CRLF\n-# and leaves CR at the end instead.\n-cr=$(printf \"\\015\")\n-\n-resolvemsg=\"\n-$(gettext 'Resolve all conflicts manually, mark them as resolved with\n-\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n-You can instead skip this commit: run \"git rebase --skip\".\n-To abort and get back to the state before \"git rebase\", run \"git rebase --abort\".')\n-\"\n-\n-write_basic_state () {\n-\techo \"$head_name\" > \"$state_dir\"/head-name &&\n-\techo \"$onto\" > \"$state_dir\"/onto &&\n-\techo \"$orig_head\" > \"$state_dir\"/orig-head &&\n-\ttest t = \"$GIT_QUIET\" && : > \"$state_dir\"/quiet\n-\ttest t = \"$verbose\" && : > \"$state_dir\"/verbose\n-\ttest -n \"$strategy\" && echo \"$strategy\" > \"$state_dir\"/strategy\n-\ttest -n \"$strategy_opts\" && echo \"$strategy_opts\" > \\\n-\t\t\"$state_dir\"/strategy_opts\n-\ttest -n \"$allow_rerere_autoupdate\" && echo \"$allow_rerere_autoupdate\" > \\\n-\t\t\"$state_dir\"/allow_rerere_autoupdate\n-\ttest -n \"$gpg_sign_opt\" && echo \"$gpg_sign_opt\" > \"$state_dir\"/gpg_sign_opt\n-\ttest -n \"$signoff\" && echo \"$signoff\" >\"$state_dir\"/signoff\n-\ttest -n \"$reschedule_failed_exec\" && : > \"$state_dir\"/reschedule-failed-exec\n-}\n-\n-apply_autostash () {\n-\tif test -f \"$state_dir/autostash\"\n-\tthen\n-\t\tstash_sha1=$(cat \"$state_dir/autostash\")\n-\t\tif git stash apply $stash_sha1 >/dev/null 2>&1\n-\t\tthen\n-\t\t\techo \"$(gettext 'Applied autostash.')\" >&2\n-\t\telse\n-\t\t\tgit stash store -m \"autostash\" -q $stash_sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot store \\$stash_sha1\")\"\n-\t\t\tgettext 'Applying autostash resulted in conflicts.\n-Your changes are safe in the stash.\n-You can run \"git stash pop\" or \"git stash drop\" at any time.\n-' >&2\n-\t\tfi\n-\tfi\n-}\n-\n-output () {\n-\tcase \"$verbose\" in\n-\t'')\n-\t\toutput=$(\"$@\" 2>&1 )\n-\t\tstatus=$?\n-\t\ttest $status != 0 && printf \"%s\\n\" \"$output\"\n-\t\treturn $status\n-\t\t;;\n-\t*)\n-\t\t\"$@\"\n-\t\t;;\n-\tesac\n-}\n-\n-strategy_args=${strategy:+--strategy=$strategy}\n-test -n \"$strategy_opts\" &&\n-eval '\n-\tfor strategy_opt in '\"$strategy_opts\"'\n-\tdo\n-\t\tstrategy_args=\"$strategy_args -X$(git rev-parse --sq-quote \"${strategy_opt#--}\")\"\n-\tdone\n-'\n-\n-GIT_CHERRY_PICK_HELP=\"$resolvemsg\"\n-export GIT_CHERRY_PICK_HELP\n-\n-comment_char=$(git config --get core.commentchar 2>/dev/null)\n-case \"$comment_char\" in\n-'' | auto)\n-\tcomment_char=\"#\"\n-\t;;\n-?)\n-\t;;\n-*)\n-\tcomment_char=$(echo \"$comment_char\" | cut -c1)\n-\t;;\n-esac\n-\n-warn () {\n-\tprintf '%s\\n' \"$*\" >&2\n-}\n-\n-# Output the commit message for the specified commit.\n-commit_message () {\n-\tgit cat-file commit \"$1\" | sed \"1,/^$/d\"\n-}\n-\n-orig_reflog_action=\"$GIT_REFLOG_ACTION\"\n-\n-comment_for_reflog () {\n-\tcase \"$orig_reflog_action\" in\n-\t''|rebase*)\n-\t\tGIT_REFLOG_ACTION=\"rebase -i ($1)\"\n-\t\texport GIT_REFLOG_ACTION\n-\t\t;;\n-\tesac\n-}\n-\n-last_count=\n-mark_action_done () {\n-\tsed -e 1q < \"$todo\" >> \"$done\"\n-\tsed -e 1d < \"$todo\" >> \"$todo\".new\n-\tmv -f \"$todo\".new \"$todo\"\n-\tnew_count=$(( $(git stripspace --strip-comments <\"$done\" | wc -l) ))\n-\techo $new_count >\"$msgnum\"\n-\ttotal=$(($new_count + $(git stripspace --strip-comments <\"$todo\" | wc -l)))\n-\techo $total >\"$end\"\n-\tif test \"$last_count\" != \"$new_count\"\n-\tthen\n-\t\tlast_count=$new_count\n-\t\teval_gettext \"Rebasing (\\$new_count/\\$total)\"; printf \"\\r\"\n-\t\ttest -z \"$verbose\" || echo\n-\tfi\n-}\n-\n-append_todo_help () {\n-\tgettext \"\n-Commands:\n-p, pick <commit> = use commit\n-r, reword <commit> = use commit, but edit the commit message\n-e, edit <commit> = use commit, but stop for amending\n-s, squash <commit> = use commit, but meld into previous commit\n-f, fixup <commit> = like \\\"squash\\\", but discard this commit's log message\n-x, exec <commit> = run command (the rest of the line) using shell\n-d, drop <commit> = remove commit\n-l, label <label> = label current HEAD with a name\n-t, reset <label> = reset HEAD to a label\n-m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n-.       create a merge commit using the original merge commit's\n-.       message (or the oneline, if no original merge commit was\n-.       specified). Use -c <commit> to reword the commit message.\n-\n-These lines can be re-ordered; they are executed from top to bottom.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test $(get_missing_commit_check_level) = error\n-\tthen\n-\t\tgettext \"\n-Do not remove any line. Use 'drop' explicitly to remove a commit.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\telse\n-\t\tgettext \"\n-If you remove a line here THAT COMMIT WILL BE LOST.\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\tfi\n-}\n-\n-make_patch () {\n-\tsha1_and_parents=\"$(git rev-list --parents -1 \"$1\")\"\n-\tcase \"$sha1_and_parents\" in\n-\t?*' '?*' '?*)\n-\t\tgit diff --cc $sha1_and_parents\n-\t\t;;\n-\t?*' '?*)\n-\t\tgit diff-tree -p \"$1^!\"\n-\t\t;;\n-\t*)\n-\t\techo \"Root commit\"\n-\t\t;;\n-\tesac > \"$state_dir\"/patch\n-\ttest -f \"$msg\" ||\n-\t\tcommit_message \"$1\" > \"$msg\"\n-\ttest -f \"$author_script\" ||\n-\t\tget_author_ident_from_commit \"$1\" > \"$author_script\"\n-}\n-\n-die_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch \"$1\"\n-\tdie \"$2\"\n-}\n-\n-exit_with_patch () {\n-\techo \"$1\" > \"$state_dir\"/stopped-sha\n-\tgit update-ref REBASE_HEAD \"$1\"\n-\tmake_patch $1\n-\tgit rev-parse --verify HEAD > \"$amend\"\n-\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\twarn \"$(eval_gettext \"\\\n-You can amend the commit now, with\n-\n-\tgit commit --amend \\$gpg_sign_opt_quoted\n-\n-Once you are satisfied with your changes, run\n-\n-\tgit rebase --continue\")\"\n-\twarn\n-\texit $2\n-}\n-\n-die_abort () {\n-\tapply_autostash\n-\trm -rf \"$state_dir\"\n-\tdie \"$1\"\n-}\n-\n-has_action () {\n-\ttest -n \"$(git stripspace --strip-comments <\"$1\")\"\n-}\n-\n-is_empty_commit() {\n-\ttree=$(git rev-parse -q --verify \"$1\"^{tree} 2>/dev/null) || {\n-\t\tsha1=$1\n-\t\tdie \"$(eval_gettext \"\\$sha1: not a commit that can be picked\")\"\n-\t}\n-\tptree=$(git rev-parse -q --verify \"$1\"^^{tree} 2>/dev/null) ||\n-\t\tptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904\n-\ttest \"$tree\" = \"$ptree\"\n-}\n-\n-is_merge_commit()\n-{\n-\tgit rev-parse --verify --quiet \"$1\"^2 >/dev/null 2>&1\n-}\n-\n-# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and\n-# GIT_AUTHOR_DATE exported from the current environment.\n-do_with_author () {\n-\t(\n-\t\texport GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE\n-\t\t\"$@\"\n-\t)\n-}\n-\n-git_sequence_editor () {\n-\tif test -z \"$GIT_SEQUENCE_EDITOR\"\n-\tthen\n-\t\tGIT_SEQUENCE_EDITOR=\"$(git config sequence.editor)\"\n-\t\tif [ -z \"$GIT_SEQUENCE_EDITOR\" ]\n-\t\tthen\n-\t\t\tGIT_SEQUENCE_EDITOR=\"$(git var GIT_EDITOR)\" || return $?\n-\t\tfi\n-\tfi\n-\n-\teval \"$GIT_SEQUENCE_EDITOR\" '\"$@\"'\n-}\n-\n-pick_one () {\n-\tff=--ff\n-\n-\tcase \"$1\" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac\n-\tcase \"$force_rebase\" in '') ;; ?*) ff= ;; esac\n-\toutput git rev-parse --verify $sha1 || die \"$(eval_gettext \"Invalid commit name: \\$sha1\")\"\n-\n-\tif is_empty_commit \"$sha1\"\n-\tthen\n-\t\tempty_args=\"--allow-empty\"\n-\tfi\n-\n-\tpick_one_preserving_merges \"$@\"\n-}\n-\n-pick_one_preserving_merges () {\n-\tfast_forward=t\n-\tcase \"$1\" in\n-\t-n)\n-\t\tfast_forward=f\n-\t\tsha1=$2\n-\t\t;;\n-\t*)\n-\t\tsha1=$1\n-\t\t;;\n-\tesac\n-\tsha1=$(git rev-parse $sha1)\n-\n-\tif test -f \"$state_dir\"/current-commit && test \"$fast_forward\" = t\n-\tthen\n-\t\twhile read current_commit\n-\t\tdo\n-\t\t\tgit rev-parse HEAD > \"$rewritten\"/$current_commit\n-\t\tdone <\"$state_dir\"/current-commit\n-\t\trm \"$state_dir\"/current-commit ||\n-\t\t\tdie \"$(gettext \"Cannot write current commit's replacement sha1\")\"\n-\tfi\n-\n-\techo $sha1 >> \"$state_dir\"/current-commit\n-\n-\t# rewrite parents; if none were rewritten, we can fast-forward.\n-\tnew_parents=\n-\tpend=\" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\"\n-\tif test \"$pend\" = \" \"\n-\tthen\n-\t\tpend=\" root\"\n-\tfi\n-\twhile [ \"$pend\" != \"\" ]\n-\tdo\n-\t\tp=$(expr \"$pend\" : ' \\([^ ]*\\)')\n-\t\tpend=\"${pend# $p}\"\n-\n-\t\tif test -f \"$rewritten\"/$p\n-\t\tthen\n-\t\t\tnew_p=$(cat \"$rewritten\"/$p)\n-\n-\t\t\t# If the todo reordered commits, and our parent is marked for\n-\t\t\t# rewriting, but hasn't been gotten to yet, assume the user meant to\n-\t\t\t# drop it on top of the current HEAD\n-\t\t\tif test -z \"$new_p\"\n-\t\t\tthen\n-\t\t\t\tnew_p=$(git rev-parse HEAD)\n-\t\t\tfi\n-\n-\t\t\ttest $p != $new_p && fast_forward=f\n-\t\t\tcase \"$new_parents\" in\n-\t\t\t*$new_p*)\n-\t\t\t\t;; # do nothing; that parent is already there\n-\t\t\t*)\n-\t\t\t\tnew_parents=\"$new_parents $new_p\"\n-\t\t\t\t;;\n-\t\t\tesac\n-\t\telse\n-\t\t\tif test -f \"$dropped\"/$p\n-\t\t\tthen\n-\t\t\t\tfast_forward=f\n-\t\t\t\treplacement=\"$(cat \"$dropped\"/$p)\"\n-\t\t\t\ttest -z \"$replacement\" && replacement=root\n-\t\t\t\tpend=\" $replacement$pend\"\n-\t\t\telse\n-\t\t\t\tnew_parents=\"$new_parents $p\"\n-\t\t\tfi\n-\t\tfi\n-\tdone\n-\tcase $fast_forward in\n-\tt)\n-\t\toutput warn \"$(eval_gettext \"Fast-forward to \\$sha1\")\"\n-\t\toutput git reset --hard $sha1 ||\n-\t\t\tdie \"$(eval_gettext \"Cannot fast-forward to \\$sha1\")\"\n-\t\t;;\n-\tf)\n-\t\tfirst_parent=$(expr \"$new_parents\" : ' \\([^ ]*\\)')\n-\n-\t\tif [ \"$1\" != \"-n\" ]\n-\t\tthen\n-\t\t\t# detach HEAD to current parent\n-\t\t\toutput git checkout $first_parent 2> /dev/null ||\n-\t\t\t\tdie \"$(eval_gettext \"Cannot move HEAD to \\$first_parent\")\"\n-\t\tfi\n-\n-\t\tcase \"$new_parents\" in\n-\t\t' '*' '*)\n-\t\t\ttest \"a$1\" = a-n && die \"$(eval_gettext \"Refusing to squash a merge: \\$sha1\")\"\n-\n-\t\t\t# redo merge\n-\t\t\tauthor_script_content=$(get_author_ident_from_commit $sha1)\n-\t\t\teval \"$author_script_content\"\n-\t\t\tmsg_content=\"$(commit_message $sha1)\"\n-\t\t\t# No point in merging the first parent, that's HEAD\n-\t\t\tnew_parents=${new_parents# $first_parent}\n-\t\t\tmerge_args=\"--no-log --no-ff\"\n-\t\t\tif ! do_with_author output eval \\\n-\t\t\t\tgit merge ${gpg_sign_opt:+$(git rev-parse \\\n-\t\t\t\t\t--sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t$allow_rerere_autoupdate \"$merge_args\" \\\n-\t\t\t\t\"$strategy_args\" \\\n-\t\t\t\t-m \"$(git rev-parse --sq-quote \"$msg_content\")\" \\\n-\t\t\t\t\"$new_parents\"\n-\t\t\tthen\n-\t\t\t\tprintf \"%s\\n\" \"$msg_content\" > \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Error redoing merge \\$sha1\")\"\n-\t\t\tfi\n-\t\t\techo \"$sha1 $(git rev-parse HEAD^0)\" >> \"$rewritten_list\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\toutput eval git cherry-pick $allow_rerere_autoupdate \\\n-\t\t\t\t$allow_empty_message \\\n-\t\t\t\t${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")} \\\n-\t\t\t\t\"$strategy_args\" \"$@\" ||\n-\t\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not pick \\$sha1\")\"\n-\t\t\t;;\n-\t\tesac\n-\t\t;;\n-\tesac\n-}\n-\n-this_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"This is the commit message #\\${n}:\"\n-}\n-\n-skip_nth_commit_message () {\n-\tn=$1\n-\teval_gettext \"The commit message #\\${n} will be skipped:\"\n-}\n-\n-update_squash_messages () {\n-\tif test -f \"$squash_msg\"; then\n-\t\tmv \"$squash_msg\" \"$squash_msg\".bak || exit\n-\t\tcount=$(($(sed -n \\\n-\t\t\t-e \"1s/^$comment_char[^0-9]*\\([0-9][0-9]*\\).*/\\1/p\" \\\n-\t\t\t-e \"q\" < \"$squash_msg\".bak)+1))\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(eval_ngettext \\\n-\t\t\t\t\"This is a combination of \\$count commit.\" \\\n-\t\t\t\t\"This is a combination of \\$count commits.\" \\\n-\t\t\t\t$count)\"\n-\t\t\tsed -e 1d -e '2,/^./{\n-\t\t\t\t/^$/d\n-\t\t\t}' <\"$squash_msg\".bak\n-\t\t} >\"$squash_msg\"\n-\telse\n-\t\tcommit_message HEAD >\"$fixup_msg\" ||\n-\t\tdie \"$(eval_gettext \"Cannot write \\$fixup_msg\")\"\n-\t\tcount=2\n-\t\t{\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is a combination of 2 commits.\")\"\n-\t\t\tprintf '%s\\n' \"$comment_char $(gettext \"This is the 1st commit message:\")\"\n-\t\t\techo\n-\t\t\tcat \"$fixup_msg\"\n-\t\t} >\"$squash_msg\"\n-\tfi\n-\tcase $1 in\n-\tsquash)\n-\t\trm -f \"$fixup_msg\"\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(this_nth_commit_message $count)\"\n-\t\techo\n-\t\tcommit_message $2\n-\t\t;;\n-\tfixup)\n-\t\techo\n-\t\tprintf '%s\\n' \"$comment_char $(skip_nth_commit_message $count)\"\n-\t\techo\n-\t\t# Change the space after the comment character to TAB:\n-\t\tcommit_message $2 | git stripspace --comment-lines | sed -e 's/ /\t/'\n-\t\t;;\n-\tesac >>\"$squash_msg\"\n-}\n-\n-peek_next_command () {\n-\tgit stripspace --strip-comments <\"$todo\" | sed -n -e 's/ .*//p' -e q\n-}\n-\n-# A squash/fixup has failed.  Prepare the long version of the squash\n-# commit message, then die_with_patch.  This code path requires the\n-# user to edit the combined commit message for all commits that have\n-# been squashed/fixedup so far.  So also erase the old squash\n-# messages, effectively causing the combined commit to be used as the\n-# new basis for any further squash/fixups.  Args: sha1 rest\n-die_failed_squash() {\n-\tsha1=$1\n-\trest=$2\n-\tmv \"$squash_msg\" \"$msg\" || exit\n-\trm -f \"$fixup_msg\"\n-\tcp \"$msg\" \"$GIT_DIR\"/MERGE_MSG || exit\n-\twarn\n-\twarn \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tdie_with_patch $sha1 \"\"\n-}\n-\n-flush_rewritten_pending() {\n-\ttest -s \"$rewritten_pending\" || return\n-\tnewsha1=\"$(git rev-parse HEAD^0)\"\n-\tsed \"s/$/ $newsha1/\" < \"$rewritten_pending\" >> \"$rewritten_list\"\n-\trm -f \"$rewritten_pending\"\n-}\n-\n-record_in_rewritten() {\n-\toldsha1=\"$(git rev-parse $1)\"\n-\techo \"$oldsha1\" >> \"$rewritten_pending\"\n-\n-\tcase \"$(peek_next_command)\" in\n-\tsquash|s|fixup|f)\n-\t\t;;\n-\t*)\n-\t\tflush_rewritten_pending\n-\t\t;;\n-\tesac\n-}\n-\n-do_pick () {\n-\tsha1=$1\n-\trest=$2\n-\tif test \"$(git rev-parse HEAD)\" = \"$squash_onto\"\n-\tthen\n-\t\t# Set the correct commit message and author info on the\n-\t\t# sentinel root before cherry-picking the original changes\n-\t\t# without committing (-n).  Finally, update the sentinel again\n-\t\t# to include these changes.  If the cherry-pick results in a\n-\t\t# conflict, this means our behaviour is similar to a standard\n-\t\t# failed cherry-pick during rebase, with a dirty index to\n-\t\t# resolve before manually running git commit --amend then git\n-\t\t# rebase --continue.\n-\t\tgit commit --allow-empty --allow-empty-message --amend \\\n-\t\t\t   --no-post-rewrite -n -q -C $sha1 $signoff &&\n-\t\t\tpick_one -n $sha1 &&\n-\t\t\tgit commit --allow-empty --allow-empty-message \\\n-\t\t\t\t   --amend --no-post-rewrite -n -q -C $sha1 $signoff \\\n-\t\t\t\t   ${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n-\t\t\t\t   die_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\telse\n-\t\tpick_one $sha1 ||\n-\t\t\tdie_with_patch $sha1 \"$(eval_gettext \"Could not apply \\$sha1... \\$rest\")\"\n-\tfi\n-}\n-\n-do_next () {\n-\trm -f \"$msg\" \"$author_script\" \"$amend\" \"$state_dir\"/stopped-sha || exit\n-\tread -r command sha1 rest < \"$todo\"\n-\tcase \"$command\" in\n-\t\"$comment_char\"*|''|noop|drop|d)\n-\t\tmark_action_done\n-\t\t;;\n-\t\"$cr\")\n-\t\t# Work around CR left by \"read\" (e.g. with Git for Windows' Bash).\n-\t\tmark_action_done\n-\t\t;;\n-\tpick|p)\n-\t\tcomment_for_reflog pick\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\treword|r)\n-\t\tcomment_for_reflog reword\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tgit commit --amend --no-post-rewrite ${gpg_sign_opt:+\"$gpg_sign_opt\"} \\\n-\t\t\t$allow_empty_message || {\n-\t\t\twarn \"$(eval_gettext \"\\\n-Could not amend commit after successfully picking \\$sha1... \\$rest\n-This is most likely due to an empty commit message, or the pre-commit hook\n-failed. If the pre-commit hook failed, you may need to resolve the issue before\n-you are able to reword the commit.\")\"\n-\t\t\texit_with_patch $sha1 1\n-\t\t}\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tedit|e)\n-\t\tcomment_for_reflog edit\n-\n-\t\tmark_action_done\n-\t\tdo_pick $sha1 \"$rest\"\n-\t\tsha1_abbrev=$(git rev-parse --short $sha1)\n-\t\twarn \"$(eval_gettext \"Stopped at \\$sha1_abbrev... \\$rest\")\"\n-\t\texit_with_patch $sha1 0\n-\t\t;;\n-\tsquash|s|fixup|f)\n-\t\tcase \"$command\" in\n-\t\tsquash|s)\n-\t\t\tsquash_style=squash\n-\t\t\t;;\n-\t\tfixup|f)\n-\t\t\tsquash_style=fixup\n-\t\t\t;;\n-\t\tesac\n-\t\tcomment_for_reflog $squash_style\n-\n-\t\ttest -f \"$done\" && has_action \"$done\" ||\n-\t\t\tdie \"$(eval_gettext \"Cannot '\\$squash_style' without a previous commit\")\"\n-\n-\t\tmark_action_done\n-\t\tupdate_squash_messages $squash_style $sha1\n-\t\tauthor_script_content=$(get_author_ident_from_commit HEAD)\n-\t\techo \"$author_script_content\" > \"$author_script\"\n-\t\teval \"$author_script_content\"\n-\t\tif ! pick_one -n $sha1\n-\t\tthen\n-\t\t\tgit rev-parse --verify HEAD >\"$amend\"\n-\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\tfi\n-\t\tcase \"$(peek_next_command)\" in\n-\t\tsquash|s|fixup|f)\n-\t\t\t# This is an intermediate commit; its message will only be\n-\t\t\t# used in case of trouble.  So use the long version:\n-\t\t\tdo_with_author output git commit --amend --no-verify -F \"$squash_msg\" \\\n-\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t# This is the final command of this squash/fixup group\n-\t\t\tif test -f \"$fixup_msg\"\n-\t\t\tthen\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$fixup_msg\" \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\telse\n-\t\t\t\tcp \"$squash_msg\" \"$GIT_DIR\"/SQUASH_MSG || exit\n-\t\t\t\trm -f \"$GIT_DIR\"/MERGE_MSG\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$GIT_DIR\"/SQUASH_MSG -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie_failed_squash $sha1 \"$rest\"\n-\t\t\tfi\n-\t\t\trm -f \"$squash_msg\" \"$fixup_msg\"\n-\t\t\t;;\n-\t\tesac\n-\t\trecord_in_rewritten $sha1\n-\t\t;;\n-\tx|\"exec\")\n-\t\tread -r command rest < \"$todo\"\n-\t\tmark_action_done\n-\t\teval_gettextln \"Executing: \\$rest\"\n-\t\t\"${SHELL:-@SHELL_PATH@}\" -c \"$rest\" # Actual execution\n-\t\tstatus=$?\n-\t\t# Run in subshell because require_clean_work_tree can die.\n-\t\tdirty=f\n-\t\t(require_clean_work_tree \"rebase\" 2>/dev/null) || dirty=t\n-\t\tif test \"$status\" -ne 0\n-\t\tthen\n-\t\t\twarn \"$(eval_gettext \"Execution failed: \\$rest\")\"\n-\t\t\ttest \"$dirty\" = f ||\n-\t\t\t\twarn \"$(gettext \"and made changes to the index and/or the working tree\")\"\n-\n-\t\t\twarn \"$(gettext \"\\\n-You can fix the problem, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\tif test $status -eq 127\t\t# command not found\n-\t\t\tthen\n-\t\t\t\tstatus=1\n-\t\t\tfi\n-\t\t\texit \"$status\"\n-\t\telif test \"$dirty\" = t\n-\t\tthen\n-\t\t\t# TRANSLATORS: after these lines is a command to be issued by the user\n-\t\t\twarn \"$(eval_gettext \"\\\n-Execution succeeded: \\$rest\n-but left changes to the index and/or the working tree\n-Commit or stash your changes, and then run\n-\n-\tgit rebase --continue\")\"\n-\t\t\twarn\n-\t\t\texit 1\n-\t\tfi\n-\t\t;;\n-\t*)\n-\t\twarn \"$(eval_gettext \"Unknown command: \\$command \\$sha1 \\$rest\")\"\n-\t\tfixtodo=\"$(gettext \"Please fix this using 'git rebase --edit-todo'.\")\"\n-\t\tif git rev-parse --verify -q \"$sha1\" >/dev/null\n-\t\tthen\n-\t\t\tdie_with_patch $sha1 \"$fixtodo\"\n-\t\telse\n-\t\t\tdie \"$fixtodo\"\n-\t\tfi\n-\t\t;;\n-\tesac\n-\ttest -s \"$todo\" && return\n-\n-\tcomment_for_reflog finish &&\n-\tnewhead=$(git rev-parse HEAD) &&\n-\tcase $head_name in\n-\trefs/*)\n-\t\tmessage=\"$GIT_REFLOG_ACTION: $head_name onto $onto\" &&\n-\t\tgit update-ref -m \"$message\" $head_name $newhead $orig_head &&\n-\t\tgit symbolic-ref \\\n-\t\t  -m \"$GIT_REFLOG_ACTION: returning to $head_name\" \\\n-\t\t  HEAD $head_name\n-\t\t;;\n-\tesac && {\n-\t\ttest ! -f \"$state_dir\"/verbose ||\n-\t\t\tgit diff-tree --stat $orig_head..HEAD\n-\t} &&\n-\t{\n-\t\ttest -s \"$rewritten_list\" &&\n-\t\tgit notes copy --for-rewrite=rebase < \"$rewritten_list\" ||\n-\t\ttrue # we don't care if this copying failed\n-\t} &&\n-\thook=\"$(git rev-parse --git-path hooks/post-rewrite)\"\n-\tif test -x \"$hook\" && test -s \"$rewritten_list\"; then\n-\t\t\"$hook\" rebase < \"$rewritten_list\"\n-\t\ttrue # we don't care if this hook failed\n-\tfi &&\n-\t\twarn \"$(eval_gettext \"Successfully rebased and updated \\$head_name.\")\"\n-\n-\treturn 1 # not failure; just to break the do_rest loop\n-}\n-\n-# can only return 0, when the infinite loop breaks\n-do_rest () {\n-\twhile :\n-\tdo\n-\t\tdo_next || break\n-\tdone\n-}\n-\n-expand_todo_ids() {\n-\tgit rebase--interactive --expand-ids\n-}\n-\n-collapse_todo_ids() {\n-\tgit rebase--interactive --shorten-ids\n-}\n-\n-# Switch to the branch in $into and notify it in the reflog\n-checkout_onto () {\n-\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $onto_name\"\n-\toutput git checkout $onto || die_abort \"$(gettext \"could not detach HEAD\")\"\n-\tgit update-ref ORIG_HEAD $orig_head\n-}\n-\n-get_missing_commit_check_level () {\n-\tcheck_level=$(git config --get rebase.missingCommitsCheck)\n-\tcheck_level=${check_level:-ignore}\n-\t# Don't be case sensitive\n-\tprintf '%s' \"$check_level\" | tr 'A-Z' 'a-z'\n-}\n-\n-# Initiate an action. If the cannot be any\n-# further action it  may exec a command\n-# or exit and not return.\n-#\n-# TODO: Consider a cleaner return model so it\n-# never exits and always return 0 if process\n-# is complete.\n-#\n-# Parameter 1 is the action to initiate.\n-#\n-# Returns 0 if the action was able to complete\n-# and if 1 if further processing is required.\n-initiate_action () {\n-\tcase \"$1\" in\n-\tcontinue)\n-\t\t# do we have anything to commit?\n-\t\tif git diff-index --cached --quiet HEAD --\n-\t\tthen\n-\t\t\t# Nothing to commit -- skip this commit\n-\n-\t\t\ttest ! -f \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\trm \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n-\t\t\tdie \"$(gettext \"Could not remove CHERRY_PICK_HEAD\")\"\n-\t\telse\n-\t\t\tif ! test -f \"$author_script\"\n-\t\t\tthen\n-\t\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\t\t\t\tdie \"$(eval_gettext \"\\\n-You have staged changes in your working tree.\n-If these changes are meant to be\n-squashed into the previous commit, run:\n-\n-  git commit --amend \\$gpg_sign_opt_quoted\n-\n-If they are meant to go into a new commit, run:\n-\n-  git commit \\$gpg_sign_opt_quoted\n-\n-In both cases, once you're done, continue with:\n-\n-  git rebase --continue\n-\")\"\n-\t\t\tfi\n-\t\t\t. \"$author_script\" ||\n-\t\t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n-\t\t\tif test -f \"$amend\"\n-\t\t\tthen\n-\t\t\t\tcurrent_head=$(git rev-parse --verify HEAD)\n-\t\t\t\ttest \"$current_head\" = $(cat \"$amend\") ||\n-\t\t\t\tdie \"$(gettext \"\\\n-You have uncommitted changes in your working tree. Please commit them\n-first and then run 'git rebase --continue' again.\")\"\n-\t\t\t\tdo_with_author git commit --amend --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\telse\n-\t\t\t\tdo_with_author git commit --no-verify -F \"$msg\" -e \\\n-\t\t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} $allow_empty_message ||\n-\t\t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\n-\t\t\tfi\n-\t\tfi\n-\n-\t\tif test -r \"$state_dir\"/stopped-sha\n-\t\tthen\n-\t\t\trecord_in_rewritten \"$(cat \"$state_dir\"/stopped-sha)\"\n-\t\tfi\n-\n-\t\trequire_clean_work_tree \"rebase\"\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tskip)\n-\t\tgit rerere clear\n-\t\tdo_rest\n-\t\treturn 0\n-\t\t;;\n-\tedit-todo)\n-\t\tgit stripspace --strip-comments <\"$todo\" >\"$todo\".new\n-\t\tmv -f \"$todo\".new \"$todo\"\n-\t\tcollapse_todo_ids\n-\t\tappend_todo_help\n-\t\tgettext \"\n-You are editing the todo file of an ongoing interactive rebase.\n-To continue rebase after editing, run:\n-    git rebase --continue\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\t\tgit_sequence_editor \"$todo\" ||\n-\t\t\tdie \"$(gettext \"Could not execute editor\")\"\n-\t\texpand_todo_ids\n-\n-\t\texit\n-\t\t;;\n-\tshow-current-patch)\n-\t\texec git show REBASE_HEAD --\n-\t\t;;\n-\t*)\n-\t\treturn 1 # continue\n-\t\t;;\n-\tesac\n-}\n-\n-setup_reflog_action () {\n-\tcomment_for_reflog start\n-\n-\tif test ! -z \"$switch_to\"\n-\tthen\n-\t\tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION: checkout $switch_to\"\n-\t\toutput git checkout \"$switch_to\" -- ||\n-\t\t\tdie \"$(eval_gettext \"Could not checkout \\$switch_to\")\"\n-\n-\t\tcomment_for_reflog start\n-\tfi\n-}\n-\n-init_basic_state () {\n-\torig_head=$(git rev-parse --verify HEAD) || die \"$(gettext \"No HEAD?\")\"\n-\tmkdir -p \"$state_dir\" || die \"$(eval_gettext \"Could not create temporary \\$state_dir\")\"\n-\trm -f \"$(git rev-parse --git-path REBASE_HEAD)\"\n-\n-\t: > \"$state_dir\"/interactive || die \"$(gettext \"Could not mark as interactive\")\"\n-\twrite_basic_state\n-}\n-\n-init_revisions_and_shortrevisions () {\n-\tshorthead=$(git rev-parse --short $orig_head)\n-\tshortonto=$(git rev-parse --short $onto)\n-\tif test -z \"$rebase_root\"\n-\t\t# this is now equivalent to ! -z \"$upstream\"\n-\tthen\n-\t\tshortupstream=$(git rev-parse --short $upstream)\n-\t\trevisions=$upstream...$orig_head\n-\t\tshortrevisions=$shortupstream..$shorthead\n-\telse\n-\t\trevisions=$onto...$orig_head\n-\t\tshortrevisions=$shorthead\n-\t\ttest -z \"$squash_onto\" ||\n-\t\techo \"$squash_onto\" >\"$state_dir\"/squash-onto\n-\tfi\n-}\n-\n-complete_action() {\n-\ttest -s \"$todo\" || echo noop >> \"$todo\"\n-\ttest -z \"$autosquash\" || git rebase--interactive --rearrange-squash || exit\n-\ttest -n \"$cmd\" && git rebase--interactive --add-exec-commands --cmd \"$cmd\"\n-\n-\ttodocount=$(git stripspace --strip-comments <\"$todo\" | wc -l)\n-\ttodocount=${todocount##* }\n-\n-cat >>\"$todo\" <<EOF\n-\n-$comment_char $(eval_ngettext \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount command)\" \\\n-\t\"Rebase \\$shortrevisions onto \\$shortonto (\\$todocount commands)\" \\\n-\t\"$todocount\")\n-EOF\n-\tappend_todo_help\n-\tgettext \"\n-However, if you remove everything, the rebase will be aborted.\n-\n-\" | git stripspace --comment-lines >>\"$todo\"\n-\n-\tif test -z \"$keep_empty\"\n-\tthen\n-\t\tprintf '%s\\n' \"$comment_char $(gettext \"Note that empty commits are commented out\")\" >>\"$todo\"\n-\tfi\n-\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tcp \"$todo\" \"$todo\".backup\n-\tcollapse_todo_ids\n-\tgit_sequence_editor \"$todo\" ||\n-\t\tdie_abort \"$(gettext \"Could not execute editor\")\"\n-\n-\thas_action \"$todo\" ||\n-\t\treturn 2\n-\n-\tgit rebase--interactive --check-todo-list || {\n-\t\tret=$?\n-\t\tcheckout_onto\n-\t\texit $ret\n-\t}\n-\n-\texpand_todo_ids\n-\tcheckout_onto\n-\tdo_rest\n-}\n-\n-git_rebase__preserve_merges () {\n-\tinitiate_action \"$action\"\n-\tret=$?\n-\tif test $ret = 0; then\n-\t\treturn 0\n-\tfi\n-\n-\tsetup_reflog_action\n-\tinit_basic_state\n-\n-\tif test -z \"$rebase_root\"\n-\tthen\n-\t\tmkdir \"$rewritten\" &&\n-\t\tfor c in $(git merge-base --all $orig_head $upstream)\n-\t\tdo\n-\t\t\techo $onto > \"$rewritten\"/$c ||\n-\t\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\t\tdone\n-\telse\n-\t\tmkdir \"$rewritten\" &&\n-\t\techo $onto > \"$rewritten\"/root ||\n-\t\t\tdie \"$(gettext \"Could not init rewritten commits\")\"\n-\tfi\n-\n-\tinit_revisions_and_shortrevisions\n-\n-\tformat=$(git config --get rebase.instructionFormat)\n-\t# the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse\n-\tgit rev-list --format=\"%m%H ${format:-%s}\" \\\n-\t\t--reverse --left-right --topo-order \\\n-\t\t$revisions ${restrict_revision+^$restrict_revision} | \\\n-\t\tsed -n \"s/^>//p\" |\n-\twhile read -r sha1 rest\n-\tdo\n-\t\tif test -z \"$keep_empty\" && is_empty_commit $sha1 && ! is_merge_commit $sha1\n-\t\tthen\n-\t\t\tcomment_out=\"$comment_char \"\n-\t\telse\n-\t\t\tcomment_out=\n-\t\tfi\n-\n-\t\tif test -z \"$rebase_root\"\n-\t\tthen\n-\t\t\tpreserve=t\n-\t\t\tfor p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)\n-\t\t\tdo\n-\t\t\t\tif test -f \"$rewritten\"/$p\n-\t\t\t\tthen\n-\t\t\t\t\tpreserve=f\n-\t\t\t\tfi\n-\t\t\tdone\n-\t\telse\n-\t\t\tpreserve=f\n-\t\tfi\n-\t\tif test f = \"$preserve\"\n-\t\tthen\n-\t\t\ttouch \"$rewritten\"/$sha1\n-\t\t\tprintf '%s\\n' \"${comment_out}pick $sha1 $rest\" >>\"$todo\"\n-\t\tfi\n-\tdone\n-\n-\t# Watch for commits that been dropped by --cherry-pick\n-\tmkdir \"$dropped\"\n-\t# Save all non-cherry-picked changes\n-\tgit rev-list $revisions --left-right --cherry-pick | \\\n-\t\tsed -n \"s/^>//p\" > \"$state_dir\"/not-cherry-picks\n-\t# Now all commits and note which ones are missing in\n-\t# not-cherry-picks and hence being dropped\n-\tgit rev-list $revisions |\n-\twhile read rev\n-\tdo\n-\t\tif test -f \"$rewritten\"/$rev &&\n-\t\t   ! sane_grep \"$rev\" \"$state_dir\"/not-cherry-picks >/dev/null\n-\t\tthen\n-\t\t\t# Use -f2 because if rev-list is telling us this commit is\n-\t\t\t# not worthwhile, we don't want to track its multiple heads,\n-\t\t\t# just the history of its first-parent for others that will\n-\t\t\t# be rebasing on top of it\n-\t\t\tgit rev-list --parents -1 $rev | cut -d' ' -s -f2 > \"$dropped\"/$rev\n-\t\t\tsha1=$(git rev-list -1 $rev)\n-\t\t\tsane_grep -v \"^[a-z][a-z]* $sha1\" <\"$todo\" > \"${todo}2\" ; mv \"${todo}2\" \"$todo\"\n-\t\t\trm \"$rewritten\"/$rev\n-\t\tfi\n-\tdone\n-\n-\tcomplete_action\n-}\n-- \ngitgitgadget\n\n"},{"id":"434942","messageId":"b5a16e205e6c1fd4e888438c13bab9b7d992b7e9.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 07/11] rebase: drop the internal `rebase--interactive` command","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:08Z","receivedAt":"2021-09-07T21:05:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIt was only used by the `--preserve-merges` backend, which we just\nremoved.\n\nHelped-by: Alban Gruin <alban.gruin@gmail.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c | 193 +----------------------------------------------\n git.c            |   1 -\n 2 files changed, 1 insertion(+), 193 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 5f8d9f89ba4..0935e8d6e83 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -162,12 +162,7 @@ enum action {\n \tACTION_ABORT,\n \tACTION_QUIT,\n \tACTION_EDIT_TODO,\n-\tACTION_SHOW_CURRENT_PATCH,\n-\tACTION_SHORTEN_OIDS,\n-\tACTION_EXPAND_OIDS,\n-\tACTION_CHECK_TODO_LIST,\n-\tACTION_REARRANGE_SQUASH,\n-\tACTION_ADD_EXEC\n+\tACTION_SHOW_CURRENT_PATCH\n };\n \n static const char *action_names[] = { \"undefined\",\n@@ -178,81 +173,6 @@ static const char *action_names[] = { \"undefined\",\n \t\t\t\t      \"edit_todo\",\n \t\t\t\t      \"show_current_patch\" };\n \n-static int add_exec_commands(struct string_list *commands)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\ttodo_list_add_exec_commands(&todo_list, commands);\n-\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int rearrange_squash_in_todo_file(void)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res = 0;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_rearrange_squash(&todo_list);\n-\tif (!res)\n-\t\tres = todo_list_write_to_file(the_repository, &todo_list,\n-\t\t\t\t\t      todo_file, NULL, NULL, -1, 0);\n-\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n-static int transform_todo_file(unsigned flags)\n-{\n-\tconst char *todo_file = rebase_path_todo();\n-\tstruct todo_list todo_list = TODO_LIST_INIT;\n-\tint res;\n-\n-\tif (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)\n-\t\treturn error_errno(_(\"could not read '%s'.\"), todo_file);\n-\n-\tif (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,\n-\t\t\t\t\t&todo_list)) {\n-\t\ttodo_list_release(&todo_list);\n-\t\treturn error(_(\"unusable todo list: '%s'\"), todo_file);\n-\t}\n-\n-\tres = todo_list_write_to_file(the_repository, &todo_list, todo_file,\n-\t\t\t\t      NULL, NULL, -1, flags);\n-\ttodo_list_release(&todo_list);\n-\n-\tif (res)\n-\t\treturn error_errno(_(\"could not write '%s'.\"), todo_file);\n-\treturn 0;\n-}\n-\n static int edit_todo_file(unsigned flags)\n {\n \tconst char *todo_file = rebase_path_todo();\n@@ -402,7 +322,6 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \tflags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;\n \tflags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;\n \tflags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;\n-\tflags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;\n \tflags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;\n \n \tswitch (command) {\n@@ -437,24 +356,6 @@ static int run_sequencer_rebase(struct rebase_options *opts,\n \n \t\tbreak;\n \t}\n-\tcase ACTION_SHORTEN_OIDS:\n-\tcase ACTION_EXPAND_OIDS:\n-\t\tret = transform_todo_file(flags);\n-\t\tbreak;\n-\tcase ACTION_CHECK_TODO_LIST:\n-\t\tret = check_todo_list_from_file(the_repository);\n-\t\tbreak;\n-\tcase ACTION_REARRANGE_SQUASH:\n-\t\tret = rearrange_squash_in_todo_file();\n-\t\tbreak;\n-\tcase ACTION_ADD_EXEC: {\n-\t\tstruct string_list commands = STRING_LIST_INIT_DUP;\n-\n-\t\tsplit_exec_commands(opts->cmd, &commands);\n-\t\tret = add_exec_commands(&commands);\n-\t\tstring_list_clear(&commands, 0);\n-\t\tbreak;\n-\t}\n \tdefault:\n \t\tBUG(\"invalid command '%d'\", command);\n \t}\n@@ -476,98 +377,6 @@ static int parse_opt_keep_empty(const struct option *opt, const char *arg,\n \treturn 0;\n }\n \n-static const char * const builtin_rebase_interactive_usage[] = {\n-\tN_(\"git rebase--interactive [<options>]\"),\n-\tNULL\n-};\n-\n-int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)\n-{\n-\tstruct rebase_options opts = REBASE_OPTIONS_INIT;\n-\tstruct object_id squash_onto = *null_oid();\n-\tenum action command = ACTION_NONE;\n-\tstruct option options[] = {\n-\t\tOPT_NEGBIT(0, \"ff\", &opts.flags, N_(\"allow fast-forward\"),\n-\t\t\t   REBASE_FORCE),\n-\t\tOPT_CALLBACK_F('k', \"keep-empty\", &options, NULL,\n-\t\t\tN_(\"keep commits which start empty\"),\n-\t\t\tPARSE_OPT_NOARG | PARSE_OPT_HIDDEN,\n-\t\t\tparse_opt_keep_empty),\n-\t\tOPT_BOOL_F(0, \"allow-empty-message\", &opts.allow_empty_message,\n-\t\t\t   N_(\"allow commits with empty messages\"),\n-\t\t\t   PARSE_OPT_HIDDEN),\n-\t\tOPT_BOOL(0, \"rebase-merges\", &opts.rebase_merges, N_(\"rebase merge commits\")),\n-\t\tOPT_BOOL(0, \"rebase-cousins\", &opts.rebase_cousins,\n-\t\t\t N_(\"keep original branch points of cousins\")),\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_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-\t\tOPT_CMDMODE(0, \"continue\", &command, N_(\"continue rebase\"),\n-\t\t\t    ACTION_CONTINUE),\n-\t\tOPT_CMDMODE(0, \"skip\", &command, N_(\"skip commit\"), ACTION_SKIP),\n-\t\tOPT_CMDMODE(0, \"edit-todo\", &command, N_(\"edit the todo list\"),\n-\t\t\t    ACTION_EDIT_TODO),\n-\t\tOPT_CMDMODE(0, \"show-current-patch\", &command, N_(\"show the current patch\"),\n-\t\t\t    ACTION_SHOW_CURRENT_PATCH),\n-\t\tOPT_CMDMODE(0, \"shorten-ids\", &command,\n-\t\t\tN_(\"shorten commit ids in the todo list\"), ACTION_SHORTEN_OIDS),\n-\t\tOPT_CMDMODE(0, \"expand-ids\", &command,\n-\t\t\tN_(\"expand commit ids in the todo list\"), ACTION_EXPAND_OIDS),\n-\t\tOPT_CMDMODE(0, \"check-todo-list\", &command,\n-\t\t\tN_(\"check the todo list\"), ACTION_CHECK_TODO_LIST),\n-\t\tOPT_CMDMODE(0, \"rearrange-squash\", &command,\n-\t\t\tN_(\"rearrange fixup/squash lines\"), ACTION_REARRANGE_SQUASH),\n-\t\tOPT_CMDMODE(0, \"add-exec-commands\", &command,\n-\t\t\tN_(\"insert exec commands in todo list\"), ACTION_ADD_EXEC),\n-\t\t{ OPTION_CALLBACK, 0, \"onto\", &opts.onto, N_(\"onto\"), N_(\"onto\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"restrict-revision\", &opts.restrict_revision,\n-\t\t  N_(\"restrict-revision\"), N_(\"restrict revision\"),\n-\t\t  PARSE_OPT_NONEG, parse_opt_commit, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"squash-onto\", &squash_onto, N_(\"squash-onto\"),\n-\t\t  N_(\"squash onto\"), PARSE_OPT_NONEG, parse_opt_object_id, 0 },\n-\t\t{ OPTION_CALLBACK, 0, \"upstream\", &opts.upstream, N_(\"upstream\"),\n-\t\t  N_(\"the upstream commit\"), PARSE_OPT_NONEG, parse_opt_commit,\n-\t\t  0 },\n-\t\tOPT_STRING(0, \"head-name\", &opts.head_name, N_(\"head-name\"), N_(\"head name\")),\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_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-\t\t\t   N_(\"strategy options\")),\n-\t\tOPT_STRING(0, \"switch-to\", &opts.switch_to, N_(\"switch-to\"),\n-\t\t\t   N_(\"the branch or commit to checkout\")),\n-\t\tOPT_STRING(0, \"onto-name\", &opts.onto_name, N_(\"onto-name\"), N_(\"onto name\")),\n-\t\tOPT_STRING(0, \"cmd\", &opts.cmd, N_(\"cmd\"), N_(\"the command to run\")),\n-\t\tOPT_RERERE_AUTOUPDATE(&opts.allow_rerere_autoupdate),\n-\t\tOPT_BOOL(0, \"reschedule-failed-exec\", &opts.reschedule_failed_exec,\n-\t\t\t N_(\"automatically re-schedule any `exec` that fails\")),\n-\t\tOPT_END()\n-\t};\n-\n-\topts.rebase_cousins = -1;\n-\n-\tif (argc == 1)\n-\t\tusage_with_options(builtin_rebase_interactive_usage, options);\n-\n-\targc = parse_options(argc, argv, prefix, options,\n-\t\t\tbuiltin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);\n-\n-\tif (!is_null_oid(&squash_onto))\n-\t\topts.squash_onto = &squash_onto;\n-\n-\tif (opts.rebase_cousins >= 0 && !opts.rebase_merges)\n-\t\twarning(_(\"--[no-]rebase-cousins has no effect without \"\n-\t\t\t  \"--rebase-merges\"));\n-\n-\treturn !!run_sequencer_rebase(&opts, command);\n-}\n-\n static int is_merge(struct rebase_options *opts)\n {\n \treturn opts->type == REBASE_MERGE;\ndiff --git a/git.c b/git.c\nindex 18bed9a9964..268cdd82cfc 100644\n--- a/git.c\n+++ b/git.c\n@@ -577,7 +577,6 @@ static struct cmd_struct commands[] = {\n \t{ \"range-diff\", cmd_range_diff, RUN_SETUP | USE_PAGER },\n \t{ \"read-tree\", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},\n \t{ \"rebase\", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },\n-\t{ \"rebase--interactive\", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"receive-pack\", cmd_receive_pack },\n \t{ \"reflog\", cmd_reflog, RUN_SETUP },\n \t{ \"remote\", cmd_remote, RUN_SETUP },\n-- \ngitgitgadget\n\n"},{"id":"434944","messageId":"d23f245b68442df01f698bb9f5aaabcc5bee5f9c.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 08/11] rebase: remove obsolete code comment","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:09Z","receivedAt":"2021-09-07T21:05:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nNow that we no longer have a `--preserve-merges` backend, this comment\nneeds to be adjusted.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 0935e8d6e83..b8eb8e8304b 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1415,7 +1415,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\tif (options.ignore_date)\n \t\t\tstrvec_push(&options.git_am_opts, \"--ignore-date\");\n \t} else {\n-\t\t/* REBASE_MERGE and PRESERVE_MERGES */\n+\t\t/* REBASE_MERGE */\n \t\tif (ignore_whitespace) {\n \t\t\tstring_list_append(&strategy_options,\n \t\t\t\t\t   \"ignore-space-change\");\n-- \ngitgitgadget\n\n"},{"id":"434945","messageId":"6905c8746ba2049e9ddfa8ceff5c714559ebdb86.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 09/11] rebase: stop mentioning the -p option in comments","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:10Z","receivedAt":"2021-09-07T21:05:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWe no longer support `--preserve-merges`, therefore it does not make\nsense to keep mentioning that option, even in code comments.\n\nHelped-by: Phillip Wood <phillip.wood123@gmail.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex b8eb8e8304b..c4d4cf25028 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -909,7 +909,7 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset)\n \treturn 0;\n }\n \n-/* -i followed by -p is still explicitly interactive, but -p alone is not */\n+/* -i followed by -r is still explicitly interactive, but -r alone is not */\n static int parse_opt_interactive(const struct option *opt, const char *arg,\n \t\t\t\t int unset)\n {\n-- \ngitgitgadget\n\n"},{"id":"434946","messageId":"5bb04ea3f6c02c611e197d966919de351981a25a.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 10/11] rebase: remove a no-longer-used function","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:11Z","receivedAt":"2021-09-07T21:05:45Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWith the `--preserve-merges` option going away, we no longer need this\nfunction.\n\nHelped-by: Alban Gruin <alban.gruin@gmail.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n rebase-interactive.c | 29 -----------------------------\n rebase-interactive.h |  2 --\n 2 files changed, 31 deletions(-)\n\ndiff --git a/rebase-interactive.c b/rebase-interactive.c\nindex b6cbd16a17f..87649d0c016 100644\n--- a/rebase-interactive.c\n+++ b/rebase-interactive.c\n@@ -226,32 +226,3 @@ int todo_list_check_against_backup(struct repository *r, struct todo_list *todo_\n \ttodo_list_release(&backup);\n \treturn res;\n }\n-\n-int check_todo_list_from_file(struct repository *r)\n-{\n-\tstruct todo_list old_todo = TODO_LIST_INIT, new_todo = TODO_LIST_INIT;\n-\tint res = 0;\n-\n-\tif (strbuf_read_file(&new_todo.buf, rebase_path_todo(), 0) < 0) {\n-\t\tres = error(_(\"could not read '%s'.\"), rebase_path_todo());\n-\t\tgoto out;\n-\t}\n-\n-\tif (strbuf_read_file(&old_todo.buf, rebase_path_todo_backup(), 0) < 0) {\n-\t\tres = error(_(\"could not read '%s'.\"), rebase_path_todo_backup());\n-\t\tgoto out;\n-\t}\n-\n-\tres = todo_list_parse_insn_buffer(r, old_todo.buf.buf, &old_todo);\n-\tif (!res)\n-\t\tres = todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo);\n-\tif (res)\n-\t\tfprintf(stderr, _(edit_todo_list_advice));\n-\tif (!res)\n-\t\tres = todo_list_check(&old_todo, &new_todo);\n-out:\n-\ttodo_list_release(&old_todo);\n-\ttodo_list_release(&new_todo);\n-\n-\treturn res;\n-}\ndiff --git a/rebase-interactive.h b/rebase-interactive.h\nindex dc2cf0ee122..7239c60f791 100644\n--- a/rebase-interactive.h\n+++ b/rebase-interactive.h\n@@ -16,6 +16,4 @@ int todo_list_check(struct todo_list *old_todo, struct todo_list *new_todo);\n int todo_list_check_against_backup(struct repository *r,\n \t\t\t\t   struct todo_list *todo_list);\n \n-int check_todo_list_from_file(struct repository *r);\n-\n #endif\n-- \ngitgitgadget\n\n"},{"id":"434947","messageId":"aae9323b25fa9cdd69dcde278f9ac2c60539f153.1631048713.git.gitgitgadget@gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"[PATCH v3 11/11] sequencer: restrict scope of a formerly public function","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-09-07T21:05:12Z","receivedAt":"2021-09-07T21:05:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nThe function to add the `exec` commands to the todo list only needed to\nbe public API because it was not only used internally by the sequencer,\nbut also by `git rebase --preserve-merges`.\n\nNow that that mode has been removed, we no longer need that function to\nbe scoped publicly.\n\nHelped-by: Alban Gruin <alban.gruin@gmail.com>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n sequencer.c | 4 ++--\n sequencer.h | 2 --\n 2 files changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex 7f07cd00f3f..3cdb20b0743 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -5387,8 +5387,8 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,\n  * Add commands after pick and (series of) squash/fixup commands\n  * in the todo list.\n  */\n-void todo_list_add_exec_commands(struct todo_list *todo_list,\n-\t\t\t\t struct string_list *commands)\n+static void todo_list_add_exec_commands(struct todo_list *todo_list,\n+\t\t\t\t\tstruct string_list *commands)\n {\n \tstruct strbuf *buf = &todo_list->buf;\n \tsize_t base_offset = buf->len;\ndiff --git a/sequencer.h b/sequencer.h\nindex d57d8ea23d7..60a156ea906 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -160,8 +160,6 @@ int sequencer_remove_state(struct replay_opts *opts);\n int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,\n \t\t\t  const char **argv, unsigned flags);\n \n-void todo_list_add_exec_commands(struct todo_list *todo_list,\n-\t\t\t\t struct string_list *commands);\n int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,\n \t\t    const char *shortrevisions, const char *onto_name,\n \t\t    struct commit *onto, const struct object_id *orig_head,\n-- \ngitgitgadget\n"},{"id":"434967","messageId":"CABPp-BFZfa7cchRTycdyMbnwb_f=vHxQYLA5QswuM0ExfxeMAQ@mail.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109071930080.55@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-09-07T22:48:22Z","receivedAt":"2021-09-07T22:48:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> Hi Hannes,\n>\n> On Thu, 2 Sep 2021, Johannes Sixt wrote:\n>\n> > Am 02.09.21 um 16:18 schrieb Johannes Schindelin:\n> > > On Wed, 1 Sep 2021, Junio C Hamano wrote:\n> > >> A good goal.  There is no remaining use case where (a fictitious and\n> > >> properly working version of) \"--preserve-merges\" option cannot be\n> > >> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n> > >> the other Johannes (sorry if it weren't you, j6t) had cases that the\n> > >> former worked better, but perhaps I am mis-remembering things.\n> > >\n> > > I think that I managed to address whatever concerns there were about the\n> > > `--rebase-merges` backend in the meantime.\n> >\n> > That was either my suggestion/desire to make no-rebase-cousins the\n> > default. That has been settled.\n> >\n> > Or my wish not to redo the merge, but to replay the first-parent\n> > difference. The idea never got traction, and I've long since abandoned\n> > my implementation of it.\n>\n> Thank you for clarifying.\n>\n> Yes, I remember how that idea came up, and I even tried that strategy for\n> a couple of merging rebases of Git for Windows' branch thicket. Sadly, it\n> did not work half as well as I had hoped.\n>\n> The best idea I had back then still is in want of being implemented: sort\n> of a \"four-way merge\". It is basically the same as a three-way merge, but\n> allows for the pre-images to differ in the context (and yes, this cannot\n> be represented using the current conflict markers). Definitely not\n> trivial.\n\nmerge-ort opens a new possibility (since it does merges without\ntouching the index or working tree): Take the merge commit, M, that\nyou are trying to transplant.  Hold on to it for a minute.  Do what\nrebase-merges does now; namely, do a simple merge of the desired new\nbranches that otherwise ignores M to get your new merge commit N.\nHang on to N too for a minute.  Now use merge-ort to auto-remerge M\n(much like AUTO_MERGE or --remerge-diff does) to get a new merge\ncommit that we'll call pre-M.  If M was a clean merge that the user\ndidn't amend, then pre-M will match M.  If M wasn't a clean merge or\nwas amended, then pre-M will otherwise differ from M by not including\nany manual changes the user made when they originally created M --\nsuch as removing conflict markers, fixing semantic conflicts, evil\nchanges, etc.\n\nNow we've got three merge commits: pre-M, M, and N.  (Technically,\npre-M and N might be toplevel trees rather than full commits, but\nwhatever.)  The difference between pre-M and M represent the manual\nwork the user did in order to create M.  Now, do a three-way\n(non-recursive) merge of those commits, to get the rebased result, R.\nThis operation has the affect of applying the changes from pre-M to M\non top of N.\n\nThere's obviously some edge cases (e.g. nested conflict markers), but\nI think they're better than the edge cases presented by the\nalternatives:\n  * the first-parent difference idea silently discards intermediate\nchanges from reapplying other patches (especially if other patches are\nadded or dropped), which to me feels _very_ dangerous\n  * the current rebase-merges idea silently discards manual user\nchanges within the original merge commit (i.e. it hopes that there is\nno difference between pre-M and M), which can also be lossy\n  * I don't think this idea drops any data, but it does run the risk\nof conflicts that are difficult to understand.  But I suspect less so\nthan your five-way merge would entail.\n\nIf the difficulty of conflicts in this scheme is too high, we could do\na few things like providing multiple versions (e.g. if either\npre-M:file or N:file had conflicts, or maybe if R:file has nested\nconflicts, then place both R:file and N:file in the working tree\nsomewhere) or pointing at special commands that help users figure out\nwhat went on (e.g. 'git log -1 --remerge-diff M -- file').\n"},{"id":"434987","messageId":"87czpjkg3m.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"pull.195.v3.git.1631048712.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 00/11] Drop support for git rebase --preserve-merges","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-08T01:30:41Z","receivedAt":"2021-09-08T01:31:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> In 427c3bd28ab (rebase: deprecate --preserve-merges, 2019-03-11) (which was\n> included in v2.22.0), we officially deprecated the --preserve-merges\n> backend. Over two years later, it is time to drop that backend, and here is\n> a patch series that does just that.\n>\n> Changes since v2:\n>\n>  * Removed the no-longer-needed script_snippet variable\n>  * Enhanced the commit message of the git svn patch to clarify that the\n>    deprecation happened only in v2.25 there\n>  * Adjusted code comments that still talked about the removed option\n>  * Removed some no-longer-needed ACTION_* enum values\n>  * We now also drop check_todo_list_from_file() because it is no longer\n>    needed\n>  * The todo_list_add_exec_commands() function is now scoped to the file\n>    (because there are no longer any outside users)\n>  * When users still use the options, they are no longer met by Git's blank\n>    stares, but by a helpful error message suggesting to use --rebase-merges\n>    instead\n>\n> Changes since v1:\n>\n>  * Rebased onto v2.33.0\n>\n> Johannes Schindelin (11):\n>   t5520: do not use `pull.rebase=preserve`\n>   remote: warn about unhandled branch.<name>.rebase values\n>   tests: stop testing `git rebase --preserve-merges`\n>   pull: remove support for `--rebase=preserve`\n>   rebase: drop support for `--preserve-merges`\n>   git-svn: drop support for `--preserve-merges`\n>   rebase: drop the internal `rebase--interactive` command\n>   rebase: remove obsolete code comment\n>   rebase: stop mentioning the -p option in comments\n>   rebase: remove a no-longer-used function\n>   sequencer: restrict scope of a formerly public function\n\nI've looked this version over & followed all the discussions on the\nearlier rounds (this year), this looks good to me. Thanks a lot for\nworking on it:\n\nReviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n"},{"id":"435406","messageId":"nycvar.QRO.7.76.6.2109101325410.59@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"CABPp-BFZfa7cchRTycdyMbnwb_f=vHxQYLA5QswuM0ExfxeMAQ@mail.gmail.com","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-10T12:08:44Z","receivedAt":"2021-09-10T12:08:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Elijah,\n\nOn Tue, 7 Sep 2021, Elijah Newren wrote:\n\n> On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Thu, 2 Sep 2021, Johannes Sixt wrote:\n> >\n> > > Am 02.09.21 um 16:18 schrieb Johannes Schindelin:\n> > > > On Wed, 1 Sep 2021, Junio C Hamano wrote:\n> > > >> A good goal.  There is no remaining use case where (a fictitious and\n> > > >> properly working version of) \"--preserve-merges\" option cannot be\n> > > >> replaced by \"--rebase-merges\", is it?  I somehow had a feeling that\n> > > >> the other Johannes (sorry if it weren't you, j6t) had cases that the\n> > > >> former worked better, but perhaps I am mis-remembering things.\n> > > >\n> > > > I think that I managed to address whatever concerns there were about the\n> > > > `--rebase-merges` backend in the meantime.\n> > >\n> > > That was either my suggestion/desire to make no-rebase-cousins the\n> > > default. That has been settled.\n> > >\n> > > Or my wish not to redo the merge, but to replay the first-parent\n> > > difference. The idea never got traction, and I've long since abandoned\n> > > my implementation of it.\n> >\n> > Thank you for clarifying.\n> >\n> > Yes, I remember how that idea came up, and I even tried that strategy for\n> > a couple of merging rebases of Git for Windows' branch thicket. Sadly, it\n> > did not work half as well as I had hoped.\n> >\n> > The best idea I had back then still is in want of being implemented: sort\n> > of a \"four-way merge\". It is basically the same as a three-way merge, but\n> > allows for the pre-images to differ in the context (and yes, this cannot\n> > be represented using the current conflict markers). Definitely not\n> > trivial.\n>\n> merge-ort opens a new possibility (since it does merges without\n> touching the index or working tree): Take the merge commit, M, that\n> you are trying to transplant.  Hold on to it for a minute.  Do what\n> rebase-merges does now; namely, do a simple merge of the desired new\n> branches that otherwise ignores M to get your new merge commit N.\n> Hang on to N too for a minute.  Now use merge-ort to auto-remerge M\n> (much like AUTO_MERGE or --remerge-diff does) to get a new merge\n> commit that we'll call pre-M.  If M was a clean merge that the user\n> didn't amend, then pre-M will match M.  If M wasn't a clean merge or\n> was amended, then pre-M will otherwise differ from M by not including\n> any manual changes the user made when they originally created M --\n> such as removing conflict markers, fixing semantic conflicts, evil\n> changes, etc.\n>\n> Now we've got three merge commits: pre-M, M, and N.  (Technically,\n> pre-M and N might be toplevel trees rather than full commits, but\n> whatever.)  The difference between pre-M and M represent the manual\n> work the user did in order to create M.  Now, do a three-way\n> (non-recursive) merge of those commits, to get the rebased result, R.\n> This operation has the affect of applying the changes from pre-M to M\n> on top of N.\n>\n> There's obviously some edge cases (e.g. nested conflict markers), but\n> I think they're better than the edge cases presented by the\n> alternatives:\n>   * the first-parent difference idea silently discards intermediate\n> changes from reapplying other patches (especially if other patches are\n> added or dropped), which to me feels _very_ dangerous\n>   * the current rebase-merges idea silently discards manual user\n> changes within the original merge commit (i.e. it hopes that there is\n> no difference between pre-M and M), which can also be lossy\n>   * I don't think this idea drops any data, but it does run the risk\n> of conflicts that are difficult to understand.  But I suspect less so\n> than your five-way merge would entail.\n>\n> If the difficulty of conflicts in this scheme is too high, we could do\n> a few things like providing multiple versions (e.g. if either\n> pre-M:file or N:file had conflicts, or maybe if R:file has nested\n> conflicts, then place both R:file and N:file in the working tree\n> somewhere) or pointing at special commands that help users figure out\n> what went on (e.g. 'git log -1 --remerge-diff M -- file').\n\nWhile I agree that `merge-ort` makes a lot of things much better, I think\nin this context we need to keep in mind that those nested merge conflicts\ncan really hurt.\n\nIn my tests (I tried to implement a strategy where a 3-way merge is done\nwith M and N^, using the parent commits of M as merge parents\nsuccessively, see\nhttps://lore.kernel.org/git/nycvar.QRO.7.76.6.1804130002090.65@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz/\nfor the nitty gritty), I ran into _nasty_ nested merge conflicts, even\nwith trivial examples. And I came to the conviction that treating the\nmerge conflict markers as Just Another Line was the main culprit.\n\nI wish I had the time to try out your proposed strategy with the\nconconcted example I presented in that mail I linked above. Because now I\nam curious what it would do...\n\nCiao,\nDscho\n"},{"id":"435421","messageId":"87pmtgcwdi.fsf@evledraar.gmail.com","threadId":"52325","inReplyTo":"2d7a4a2c564aaafbf8da97cf017766163c77b70b.1631048713.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 05/11] rebase: drop support for `--preserve-merges`","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-10T14:53:42Z","receivedAt":"2021-09-10T14:56:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> diff --git a/builtin/rebase.c b/builtin/rebase.c\n> index 33e09619005..5f8d9f89ba4 100644\n> --- a/builtin/rebase.c\n> +++ b/builtin/rebase.c\n> @@ -48,8 +48,7 @@ static GIT_PATH_FUNC(merge_dir, \"rebase-merge\")\n>  enum rebase_type {\n>  \tREBASE_UNSPECIFIED = -1,\n>  \tREBASE_APPLY,\n> -\tREBASE_MERGE,\n> -\tREBASE_PRESERVE_MERGES\n> +\tREBASE_MERGE\n>  };\n\nThis definitely doesn't require a re-roll, but just in case you didn't\nknow, from CodingGuidelines:\n\n   . since early 2012 with e1327023ea, we have been using an enum\n     definition whose last element is followed by a comma.  This, like\n     an array initializer that ends with a trailing comma, can be used\n     to reduce the patch noise when adding a new identifier at the end.\n\n(That was added in cc0c42975a2 (CodingGuidelines: spell out post-C89\nrules, 2019-07-16))\n\nI.e. in case you're slavisly following this particular bit of C syntax\nfor C89 compatibility it's not needed anymore, which helps to make diffs\nsmaller, and writing code generation loops less annoying.\n"},{"id":"435448","messageId":"CABPp-BHWVO5VRhr1-Ou60F1wjKzJZ1e_dC01Mmzs+qB9kGayww@mail.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109101325410.59@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-09-10T17:16:17Z","receivedAt":"2021-09-10T17:16:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Sep 10, 2021 at 5:08 AM Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> Hi Elijah,\n>\n> On Tue, 7 Sep 2021, Elijah Newren wrote:\n>\n> > On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin\n> > <Johannes.Schindelin@gmx.de> wrote:\n> > >\n...\n> > > Thank you for clarifying.\n> > >\n> > > Yes, I remember how that idea came up, and I even tried that strategy for\n> > > a couple of merging rebases of Git for Windows' branch thicket. Sadly, it\n> > > did not work half as well as I had hoped.\n> > >\n> > > The best idea I had back then still is in want of being implemented: sort\n> > > of a \"four-way merge\". It is basically the same as a three-way merge, but\n> > > allows for the pre-images to differ in the context (and yes, this cannot\n> > > be represented using the current conflict markers). Definitely not\n> > > trivial.\n> >\n> > merge-ort opens a new possibility (since it does merges without\n> > touching the index or working tree): Take the merge commit, M, that\n> > you are trying to transplant.  Hold on to it for a minute.  Do what\n> > rebase-merges does now; namely, do a simple merge of the desired new\n> > branches that otherwise ignores M to get your new merge commit N.\n> > Hang on to N too for a minute.  Now use merge-ort to auto-remerge M\n> > (much like AUTO_MERGE or --remerge-diff does) to get a new merge\n> > commit that we'll call pre-M.  If M was a clean merge that the user\n> > didn't amend, then pre-M will match M.  If M wasn't a clean merge or\n> > was amended, then pre-M will otherwise differ from M by not including\n> > any manual changes the user made when they originally created M --\n> > such as removing conflict markers, fixing semantic conflicts, evil\n> > changes, etc.\n> >\n> > Now we've got three merge commits: pre-M, M, and N.  (Technically,\n> > pre-M and N might be toplevel trees rather than full commits, but\n> > whatever.)  The difference between pre-M and M represent the manual\n> > work the user did in order to create M.  Now, do a three-way\n> > (non-recursive) merge of those commits, to get the rebased result, R.\n> > This operation has the affect of applying the changes from pre-M to M\n> > on top of N.\n> >\n> > There's obviously some edge cases (e.g. nested conflict markers), but\n> > I think they're better than the edge cases presented by the\n> > alternatives:\n> >   * the first-parent difference idea silently discards intermediate\n> > changes from reapplying other patches (especially if other patches are\n> > added or dropped), which to me feels _very_ dangerous\n> >   * the current rebase-merges idea silently discards manual user\n> > changes within the original merge commit (i.e. it hopes that there is\n> > no difference between pre-M and M), which can also be lossy\n> >   * I don't think this idea drops any data, but it does run the risk\n> > of conflicts that are difficult to understand.  But I suspect less so\n> > than your five-way merge would entail.\n> >\n> > If the difficulty of conflicts in this scheme is too high, we could do\n> > a few things like providing multiple versions (e.g. if either\n> > pre-M:file or N:file had conflicts, or maybe if R:file has nested\n> > conflicts, then place both R:file and N:file in the working tree\n> > somewhere) or pointing at special commands that help users figure out\n> > what went on (e.g. 'git log -1 --remerge-diff M -- file').\n>\n> While I agree that `merge-ort` makes a lot of things much better, I think\n> in this context we need to keep in mind that those nested merge conflicts\n> can really hurt.\n\nYes, and I'm not sure you fully appreciate how much either.  Your\ndiscussion in the other thread of nested conflicts suggests you may\nnot be aware of a few facts; for regular merges (not talking about\nrebase-merges yet):\n\n* Merges can have nested conflicts DESPITE having unique merge bases\nand NOT using merge.conflictstyle=diff3\n* With unique merge bases (i.e. not a \"recursive\" merge), a merge will\nhave at most two layers of conflicts\n* non-unique merge-bases and merge.conflictstyle=diff3 make nested\nconflicts much more likely\n* There is no limit on the number of nestings of conflict markers for a merge\n\nNow, in terms of rebase-merges:\n\nYou noted in the other thread the possibility of being unable to\ndifferentiate conflict markers because they had the same length.\nHowever, increasing the length on the second merge by one or two\ncharacters is not sufficient in general, because that might just make\nyou match the length of one of the nested conflicts from the other\nmerge.  You need to programmatically determine the sizes of the\nconflict markers in the first merge, and then adjust based on it for\nyour other merge(s).\n\n\nI know this will sound like I'm scaring you off of my idea even\nfurther, but I actually think despite the above that my ideas for\nrebase-merges may have merit.  I just want people to actually\nunderstand the edge and corner cases.  From my reading of the previous\nthreads on rebasing merges, I'm concerned that there is no discussion\nof arbitrarily nested conflict markers and a complete omission of any\nconsiderations for path-based rather than content-based conflicts.\n\n> In my tests (I tried to implement a strategy where a 3-way merge is done\n> with M and N^, using the parent commits of M as merge parents\n> successively, see\n> https://lore.kernel.org/git/nycvar.QRO.7.76.6.1804130002090.65@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz/\n> for the nitty gritty), I ran into _nasty_ nested merge conflicts, even\n> with trivial examples. And I came to the conviction that treating the\n> merge conflict markers as Just Another Line was the main culprit.\n\nI agree that we should not treat merge conflict markers as Just\nAnother Line.  There are other issues I can mention besides the above\nhere, but I'm getting kind of long already.\n\nHowever, I think a big part of the problem you ran into was that the\nprevious suggestions only work nicely in _really_ simple cases.  In\nparticular, although I like Phillip's suggested sequence of merges[1]\na lot more than the other suggestions in that thread or from prior\nthreads, his suggestion is going to be prone to unnecessary nested\nconflict markers, as you found in your testcase.\n\n[1] https://lore.kernel.org/git/6c8749ca-ec5d-b4b7-f1a0-50d9ad2949a5@talktalk.net/\n\n> I wish I had the time to try out your proposed strategy with the\n> conconcted example I presented in that mail I linked above. Because now I\n> am curious what it would do...\n\nFor this simple testcase, as best I understood it (you didn't quite\ndescribe it fully so I had to take a guess or two), it provides a\nsimpler conflict than either of the two you showed you got (from\ndifferent merge orderings of Phillip's suggestion).   However, let me\ndouble check that I understood your testcase correctly; please correct\nany errors in my understanding.  I believe the commit graph you were\ndescribing was this:\n\n* rebase-of-original-merge\n|\\\n| * rebase-of-local-add-caller-of-core\n* | rebase-of-local-rename-to-hi\n|/\n* upstream\n|\n|\n|\n| * original-merge\n| |\\\n| | * local-add-caller-of-core\n| |/\n|/|\n| * local-rename-to-hi\n|/\n* initial-version\n\n\nFurther, the versions of main.c in each of those are as follows:\n\n==> initial-version:\nint core(void) {\n    printf(\"Hello, world!\\n\");\n}\n\n\n==> local-rename-to-hi:\nint hi(void) {\n    printf(\"Hello, world!\\n\");\n}\n\n\n==> local-add-caller-of-core:\nint core(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* caller */\nvoid caller(void) {\n    core();\n}\n\n\n==> what an automatic merge of the two local-* branches would give:\nint hi(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* caller */\nvoid caller(void) {\n    core();\n}\n\n\n==> original-merge (amended from above by s/core/hi/ in caller()):\nint hi(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* caller */\nvoid caller(void) {\n    hi();\n}\n\n\n==> upstream:\nint greeting(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* main event loop */\nvoid event_loop(void) {\n    /* TODO: place holder for now */\n}\n\n\n==> rebase-of-local-rename-to-hi (kept 'hi' over 'greeting'):\nint hi(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* main event loop */\nvoid event_loop(void) {\n    /* TODO: place holder for now */\n}\n\n\n==> rebase-of-local-add-caller-of-core (kept both new functions,\nupdated caller):\nint greeting(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* main event loop */\nvoid event_loop(void) {\n    /* TODO: place holder for now */\n}\n/* caller */\nvoid caller(void) {\n    greeting();\n}\n\n\n\nIf I've understood that all correctly, then my idea will give you the\nfollowing conflict to resolve:\n\n==> rebase-of-original-merge, before conflict resolution:\nint hi(void) {\n    printf(\"Hello, world!\\n\");\n}\n/* main event loop */\nvoid event_loop(void) {\n    /* TODO: place holder for now */\n}\n/* caller */\nvoid caller(void) {\n<<<<<<< HEAD\n    greeting();\n||||||| auto-remerge of original-merge\n    core();\n=======\n    hi();\n>>>>>>> original-merge\n}\n"},{"id":"435707","messageId":"nycvar.QRO.7.76.6.2109131319020.55@tvgsbejvaqbjf.bet","threadId":"52325","inReplyTo":"CABPp-BHWVO5VRhr1-Ou60F1wjKzJZ1e_dC01Mmzs+qB9kGayww@mail.gmail.com","subject":"merge-ort and --rebase-merges, was Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2021-09-13T11:24:30Z","receivedAt":"2021-09-13T11:24:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Elijah,\n\nOn Fri, 10 Sep 2021, Elijah Newren wrote:\n\n> On Fri, Sep 10, 2021 at 5:08 AM Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Tue, 7 Sep 2021, Elijah Newren wrote:\n> >\n> > > On Tue, Sep 7, 2021 at 11:51 AM Johannes Schindelin\n> > > <Johannes.Schindelin@gmx.de> wrote:\n> > >\n> > > [... talk about re-resolving merge conflicts when recreating merges\n> > >  in a `git rebase --rebase-merges` run ...]\n> ...\n> >\n> > While I agree that `merge-ort` makes a lot of things much better, I think\n> > in this context we need to keep in mind that those nested merge conflicts\n> > can really hurt.\n>\n> Yes, and I'm not sure you fully appreciate how much either.\n\n*grin*\n\n> [... a lot of insight that I totally agree with ...]\n>\n> I believe the commit graph you were describing was this:\n>\n> * rebase-of-original-merge\n> |\\\n> | * rebase-of-local-add-caller-of-core\n> * | rebase-of-local-rename-to-hi\n> |/\n> * upstream\n> |\n> |\n> |\n> | * original-merge\n> | |\\\n> | | * local-add-caller-of-core\n> | |/\n> |/|\n> | * local-rename-to-hi\n> |/\n> * initial-version\n>\n>\n> Further, the versions of main.c in each of those are as follows:\n>\n> ==> initial-version:\n> int core(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n>\n>\n> ==> local-rename-to-hi:\n> int hi(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n>\n>\n> ==> local-add-caller-of-core:\n> int core(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* caller */\n> void caller(void) {\n>     core();\n> }\n>\n>\n> ==> what an automatic merge of the two local-* branches would give:\n> int hi(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* caller */\n> void caller(void) {\n>     core();\n> }\n>\n>\n> ==> original-merge (amended from above by s/core/hi/ in caller()):\n> int hi(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* caller */\n> void caller(void) {\n>     hi();\n> }\n>\n>\n> ==> upstream:\n> int greeting(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* main event loop */\n> void event_loop(void) {\n>     /* TODO: place holder for now */\n> }\n>\n>\n> ==> rebase-of-local-rename-to-hi (kept 'hi' over 'greeting'):\n> int hi(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* main event loop */\n> void event_loop(void) {\n>     /* TODO: place holder for now */\n> }\n>\n>\n> ==> rebase-of-local-add-caller-of-core (kept both new functions,\n> updated caller):\n> int greeting(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* main event loop */\n> void event_loop(void) {\n>     /* TODO: place holder for now */\n> }\n> /* caller */\n> void caller(void) {\n>     greeting();\n> }\n\nThat all matches my recollection of what I wanted to drive at.\n\n> If I've understood that all correctly, then my idea will give you the\n> following conflict to resolve:\n>\n> ==> rebase-of-original-merge, before conflict resolution:\n> int hi(void) {\n>     printf(\"Hello, world!\\n\");\n> }\n> /* main event loop */\n> void event_loop(void) {\n>     /* TODO: place holder for now */\n> }\n> /* caller */\n> void caller(void) {\n> <<<<<<< HEAD\n>     greeting();\n> ||||||| auto-remerge of original-merge\n>     core();\n> =======\n>     hi();\n> >>>>>>> original-merge\n> }\n\nThat looks very intriguing! I would _love_ to play with this a bit, and I\nthink you provided enough guidance to get going. I am currently preparing\nto go mostly offline for the second half of September, read: I won't be\nable to play with this before October. But I am definitely interested,\nthis sounds very exciting.\n\nCiao,\nDscho\n"},{"id":"435743","messageId":"CABPp-BHp+d62dCyAaJfh1cZ8xVpGyb97mZryd02aCOX=Qn=Ltw@mail.gmail.com","threadId":"52325","inReplyTo":"nycvar.QRO.7.76.6.2109131319020.55@tvgsbejvaqbjf.bet","subject":"Re: merge-ort and --rebase-merges, was Re: [PATCH v2 0/7] Drop support for git rebase --preserve-merges","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-09-13T15:53:29Z","receivedAt":"2021-09-13T15:53:43Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Sep 13, 2021 at 4:24 AM Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> Hi Elijah,\n>\n> On Fri, 10 Sep 2021, Elijah Newren wrote:\n>\n> > On Fri, Sep 10, 2021 at 5:08 AM Johannes Schindelin\n> > <Johannes.Schindelin@gmx.de> wrote:\n> > >\n> > > On Tue, 7 Sep 2021, Elijah Newren wrote:\n> > >\n\n[...snip...]\n\n> > If I've understood that all correctly, then my idea will give you the\n> > following conflict to resolve:\n> >\n> > ==> rebase-of-original-merge, before conflict resolution:\n> > int hi(void) {\n> >     printf(\"Hello, world!\\n\");\n> > }\n> > /* main event loop */\n> > void event_loop(void) {\n> >     /* TODO: place holder for now */\n> > }\n> > /* caller */\n> > void caller(void) {\n> > <<<<<<< HEAD\n> >     greeting();\n> > ||||||| auto-remerge of original-merge\n> >     core();\n> > =======\n> >     hi();\n> > >>>>>>> original-merge\n> > }\n>\n> That looks very intriguing! I would _love_ to play with this a bit, and I\n> think you provided enough guidance to get going. I am currently preparing\n> to go mostly offline for the second half of September, read: I won't be\n> able to play with this before October. But I am definitely interested,\n> this sounds very exciting.\n\nIf you start working on it, let me know.  I was thinking of playing\nwith it, but don't know exactly when I'll get time to do so; very\nunlikely before October, and reasonably likely not even before the end\nof the year.\n\nWhile I've provided the high level details in this thread which are\ngood enough to handle the simple cases, I think that the interesting\nbits are the non-simple cases.  I have not thought all of them\nthrough, but I'll include below some notes of mine that might be\nhelpful if you get to it first.  Note that I focus below on the\nnon-simple cases, and discuss content-based conflicts before covering\npath-based ones:\n\n\n* We're doing a three way merge of merges: pre-M, M, and N to get R; M\nis the original merge, pre-M is (automatic) remerge of M, and N is\nautomatic merge of rebased parents of M.\n\n* Note that N is what current rebase-merges uses, so we have all\ninformation from that merge and can provide it to the user when or if\nit is helpful.\n\n* Both pre-M and N may themselves have conflicts.\n\n* We need to programmatically handle conflict marker length when pre-M\nand/or N have nested conflicts.  (must modify merge routines to return\nthe maximal conflict marker depth used)\n\n* Special case that pre-M matches N (per hunk): If both pre-M and N\nhave conflict markers, but they happen to match, then we know to take\nthe version from M and the result IS clean (at least for that hunk).\nSo, you can still get a clean merge even if there are conflicts in\nboth pre-M and N.\n\n* Special case that pre-M matches M (per hunk): Usually in the\nthree-way merge of \"Base, Left, Right => Result\", if Base matches\neither side then you get a clean merge.  However, if pre-M matches M\nbut N has conflicts, the result is NOT clean.  Another way to look at\nthis is that conflict markers are special and should be treated\ndifferently than other lines.  (And path-based conflicts probably need\nspecial handling too, as discussed below.)\n\n* In the case of complicated conflicts, consider providing user with\nboth R:resulting-file and N:resulting-file (and point them at `git log\n-1 --remerge-diff M [-- resulting-file]`)\n\n* Having either binary files or path-based conflicts (e.g.\nmodify/delete, file vs. directory vs. submodule, switch to symlink vs.\nswitch to executable, rename/add, rename/rename -- either 1to2 or\n2to1, directory rename detection, etc.) in either pre-M or N -- or\nboth -- are going to need special care.\n\n* One example of path-based conflicts:  Let's say pre-M had no\nconflict at path P, and that pre-M:P and M:P matched.  Let's say that\nN:P had a modify/delete conflict.  Note that for modify/delete\nconflicts we tend to print a message to the console and leave the\nmodified version of the file in the working tree.  Here, despite the\nfact that pre-M:P and M:P matched, we cannot just take the modified\nfile from N at P as the merge result.  The modify/delete conflict\nshould persist and the user given an opportunity to resolve it.\nRepresenting the modify/delete might be an interesting question,\nthough since...\n\n* If both pre-M and N have conflicts, then pre-M would have had up to\nthree versions of file in the index at higher stages, N would have had\nup to three versions of file in the index at higher stages, and M\nwould have one.  We cannot represent all 7 versions of the file in the\nindex at the end, which means conflict representation might be tricky.\ncontent-based conflicts are easier to handle here than path-based\nones, since content-based conflicts can just do similar to what\nrename/rename(2to1) conflicts do today: just stick the result of the\npreliminary three-way merges into the index.  path-based conflicts get\nmore interesting because you can't do a preliminary merge of binary\nfiles or a preliminary merge of a modify/delete, etc.\n\n* If both pre-M and N have path-based conflicts, but of different\ntypes, how exactly do we mention that to the user?  Just list all the\ntypes?  (This probably qualifies as a case of a \"complicated\" conflict\nwhere we want to (also?) provide the user with N:resulting-file\ninstead of (just?) R:resulting-file.)  We may also need to modify\nmerge machinery to return types of conflicts per-path, an extension of\nwhat my \"merge-into\" series (not yet submitted) provides.\n"},{"id":"459684","messageId":"220721.86wnc6s2uh.gmgdl@evledraar.gmail.com","threadId":"52325","inReplyTo":"2d7a4a2c564aaafbf8da97cf017766163c77b70b.1631048713.git.gitgitgadget@gmail.com","subject":"re-mentioning --preserve-merges in the docs (was: [PATCH v3 05/11] rebase: drop support for `--preserve-merges`)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-07-21T19:02:14Z","receivedAt":"2022-07-21T19:06:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:\n\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> [...]\n> --p::\n> ---preserve-merges::\n> -\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n> -\tinstead of flattening the history by replaying commits a merge commit\n> -\tintroduces. Merge conflict resolutions or manual amendments to merge\n> -\tcommits are not preserved.\n\n[In reply to an old commit]\n\nI opened \"man git-rebase\" today due to an on-list discussion and went\nthrough pretty much:\n\n 1. /preserve-merges # fails\n 2. skimming the SYNOPSIS, forgetting what the new thing is called\n 3. Paging down, eventually findinging & remembering the new thing is\n    \"--rebase-merges\".\n\nI wonder if there's objections to reinstating this in the docs\nsomewhere, just as something like:\n\n\t--preserve-merges:\n\t\tAn old \"rebase\" backend which is no longer supported,\n\t\tand which was removed from git in version v2.35.0.\n\nWe don't do that with all flags that we've dropped, but perhaps this one\nwas well known enough to not leave readers hanging...\n\n\n"},{"id":"459722","messageId":"xmqqwnc6fcik.fsf@gitster.g","threadId":"52325","inReplyTo":"220721.86wnc6s2uh.gmgdl@evledraar.gmail.com","subject":"Re: re-mentioning --preserve-merges in the docs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-07-21T20:15:31Z","receivedAt":"2022-07-21T20:15:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:\n>\n>> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n>> [...]\n>> --p::\n>> ---preserve-merges::\n>> -\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n>> -\tinstead of flattening the history by replaying commits a merge commit\n>> -\tintroduces. Merge conflict resolutions or manual amendments to merge\n>> -\tcommits are not preserved.\n>\n> [In reply to an old commit]\n>\n> I opened \"man git-rebase\" today due to an on-list discussion and went\n> through pretty much:\n>\n>  1. /preserve-merges # fails\n>  2. skimming the SYNOPSIS, forgetting what the new thing is called\n>  3. Paging down, eventually findinging & remembering the new thing is\n>     \"--rebase-merges\".\n>\n> I wonder if there's objections to reinstating this in the docs\n> somewhere, just as something like:\n>\n> \t--preserve-merges:\n> \t\tAn old \"rebase\" backend which is no longer supported,\n> \t\tand which was removed from git in version v2.35.0.\n>\n> We don't do that with all flags that we've dropped, but perhaps this one\n> was well known enough to not leave readers hanging...\n\nMy impression is that we consider that we have done so already for a\nfew releases by keeping \"DEPRECATED: use rebase-merges\", exactly\nbecause \"this one was well known enough\", and now it is time to go\none step further, i.e. drop it from the document like the quoted\npatch does, while recognising an attempt to use the option and\ngiving a custom message than the bog-standard \"unknown option\".\n\n    $ git rebase --preserve-merges\n    fatal: --preserve-merges was replaced by --rebase-merges\n    Note: Your `pull.rebase` configuration may also be set to 'preserve',\n    which is no longer supported; use 'merges' instead\n\nThe next step will be to drop that custom error support, I think.\n"},{"id":"460214","messageId":"084n300p-4qp2-qp6n-232o-qs7po3q375n7@tzk.qr","threadId":"52325","inReplyTo":"xmqqwnc6fcik.fsf@gitster.g","subject":"Re: re-mentioning --preserve-merges in the docs","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2022-07-29T13:24:51Z","receivedAt":"2022-07-29T13:25:13Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Thu, 21 Jul 2022, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n> > On Tue, Sep 07 2021, Johannes Schindelin via GitGitGadget wrote:\n> >\n> >> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >> [...]\n> >> --p::\n> >> ---preserve-merges::\n> >> -\t[DEPRECATED: use `--rebase-merges` instead] Recreate merge commits\n> >> -\tinstead of flattening the history by replaying commits a merge commit\n> >> -\tintroduces. Merge conflict resolutions or manual amendments to merge\n> >> -\tcommits are not preserved.\n> >\n> > [In reply to an old commit]\n> >\n> > I opened \"man git-rebase\" today due to an on-list discussion and went\n> > through pretty much:\n> >\n> >  1. /preserve-merges # fails\n> >  2. skimming the SYNOPSIS, forgetting what the new thing is called\n> >  3. Paging down, eventually findinging & remembering the new thing is\n> >     \"--rebase-merges\".\n> >\n> > I wonder if there's objections to reinstating this in the docs\n> > somewhere, just as something like:\n> >\n> > \t--preserve-merges:\n> > \t\tAn old \"rebase\" backend which is no longer supported,\n> > \t\tand which was removed from git in version v2.35.0.\n> >\n> > We don't do that with all flags that we've dropped, but perhaps this one\n> > was well known enough to not leave readers hanging...\n>\n> My impression is that we consider that we have done so already for a\n> few releases by keeping \"DEPRECATED: use rebase-merges\", exactly\n> because \"this one was well known enough\", and now it is time to go\n> one step further, i.e. drop it from the document like the quoted\n> patch does, while recognising an attempt to use the option and\n> giving a custom message than the bog-standard \"unknown option\".\n>\n>     $ git rebase --preserve-merges\n>     fatal: --preserve-merges was replaced by --rebase-merges\n>     Note: Your `pull.rebase` configuration may also be set to 'preserve',\n>     which is no longer supported; use 'merges' instead\n>\n> The next step will be to drop that custom error support, I think.\n\nFully agree.\n\nI _could_ see us introducing a sentence in the explanation of\n`--rebase-merges` that leaves a historical note about superseding the\nnow-removed `--preserve-merges` option. But such historical notes tend to\ngo pretty stale pretty quickly, and eventually cause more confusion than\nclarification.\n\nSo just like you said, I'd rather not re-introduce any text mentioning\n`--preserve-merges` into the manual page.\n\nCiao,\nDscho\n"}]}