{"thread":{"id":"51522","subject":"[PATCH 00/12] rebase -r: support merge strategies other than recursive","startedAt":"2019-07-25T10:11:17Z","lastAt":"2019-09-09T21:06:36Z","messageCount":39,"participants":["Johannes Schindelin via GitGitGadget","Junio C Hamano","brian m. carlson","Johannes Schindelin","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":12},"messages":[{"id":"379251","messageId":"pull.294.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":null,"subject":"[PATCH 00/12] rebase -r: support merge strategies other than recursive","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:14Z","receivedAt":"2019-07-25T10:11:17Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This is the most notable shortcoming that --rebase-merges has, still,\nrelative to --preserve-merges' capabilities: it does not support passing\ncustom merge strategies or custom merge strategy options.\n\nLet's fix this.\n\nWhile working on this patch series, of course I tried to copy-edit the test\ncases we have, to cover --preserve-merges' support for merge strategies. Oh\nmy, did I regret this decision as soon as my eyes set sight on \nt3427-rebase-subtree.sh!\n\nAt first I tried my best to make heads or tails of t3427, for way too long.\nIn the end the only way to understand what the heck it tries to do was to\nactually fix it. That's why this patch series looks as if it focuses on\nt3427 rather than on adding support for custom merge strategies to the \n--rebase-merges mode.\n\nAs a consolation to myself, this work was actually worth it, surprising as\nthat may look. Not only is t3427 now really easy to understand, adding that\ntest case for --rebase-merges -Xsubtree tickled the sequencer enough to\nreveal a long-standing bug: the --onto option was simply ignored when passed\ntogether with --rebase-merges and --root. For good measure, this patch\nseries addresses this bug, too.\n\nJohannes Schindelin (12):\n  t3427: add a clarifying comment\n  t3427: simplify the `setup` test case significantly\n  t3427: move the `filter-branch` invocation into the `setup` case\n  t3427: condense the unnecessarily repetitive test cases into three\n  t3427: fix erroneous assumption\n  t3427: accommodate for the `rebase --merge` backend having been\n    replaced\n  t3427: fix another incorrect assumption\n  t3427: mark two test cases as requiring support for `git rebase -p`\n  rebase -r: support merge strategies other than `recursive`\n  t/lib-rebase: prepare for testing `git rebase --rebase-merges`\n  t3418: test `rebase -r` with merge strategies\n  rebase -r: do not (re-)generate root commits with `--root` *and*\n    `--onto`\n\n Documentation/git-rebase.txt           |   2 -\n builtin/rebase.c                       |  16 +--\n sequencer.c                            |  18 ++-\n sequencer.h                            |   6 +\n t/lib-rebase.sh                        |   8 +-\n t/t3418-rebase-continue.sh             |  14 +++\n t/t3422-rebase-incompatible-options.sh |  10 --\n t/t3427-rebase-subtree.sh              | 150 ++++++++++++-------------\n t/t3430-rebase-merges.sh               |  21 ++++\n 9 files changed, 134 insertions(+), 111 deletions(-)\n\n\nbase-commit: 082ef75b7bfc90ac236afbb857a9552a026832b8\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-294%2Fdscho%2Frebase-r-with-strategies-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-294/dscho/rebase-r-with-strategies-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/294\n-- \ngitgitgadget\n"},{"id":"379252","messageId":"df096e054d7b1646c489af8a7360de328d00c1c0.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 02/12] t3427: simplify the `setup` test case significantly","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:16Z","receivedAt":"2019-07-25T10:11: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\nIt still does the very same thing as before, but expresses it in a much\nmore succinct (and still quite readable) manner.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 36 +++++++++++++++---------------------\n 1 file changed, 15 insertions(+), 21 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex a9b93c39d0..f41a08e436 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -41,27 +41,21 @@ commit_message() {\n \n test_expect_success 'setup' '\n \ttest_commit README &&\n-\tmkdir files &&\n-\t(\n-\t\tcd files &&\n-\t\tgit init &&\n-\t\ttest_commit master1 &&\n-\t\ttest_commit master2 &&\n-\t\ttest_commit master3\n-\t) &&\n-\tgit fetch files master &&\n-\tgit branch files-master FETCH_HEAD &&\n-\tgit read-tree --prefix=files_subtree files-master &&\n-\tgit checkout -- files_subtree &&\n-\ttree=$(git write-tree) &&\n-\thead=$(git rev-parse HEAD) &&\n-\trev=$(git rev-parse --verify files-master^0) &&\n-\tcommit=$(git commit-tree -p $head -p $rev -m \"Add subproject master\" $tree) &&\n-\tgit update-ref HEAD $commit &&\n-\t(\n-\t\tcd files_subtree &&\n-\t\ttest_commit master4\n-\t) &&\n+\n+\tgit init files &&\n+\ttest_commit -C files master1 &&\n+\ttest_commit -C files master2 &&\n+\ttest_commit -C files master3 &&\n+\n+\t: perform subtree merge into files_subtree/ &&\n+\tgit fetch files refs/heads/master:refs/heads/files-master &&\n+\tgit merge -s ours --no-commit --allow-unrelated-histories \\\n+\t\tfiles-master &&\n+\tgit read-tree --prefix=files_subtree -u files-master &&\n+\tgit commit -m \"Add subproject master\" &&\n+\n+\t: add two extra commits to rebase &&\n+\ttest_commit -C files_subtree master4 &&\n \ttest_commit files_subtree/master5\n '\n \n-- \ngitgitgadget\n\n"},{"id":"379253","messageId":"05be92d9213bf16b479cc95af520eea038748567.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 01/12] t3427: add a clarifying comment","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:15Z","receivedAt":"2019-07-25T10:11:20Z","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 flow of this test script is outright confusing, and to start the\nendeavor to address that, let's describe what this test is all about,\nand how it tries to do it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 28 ++++++++++++++++++++++++++++\n 1 file changed, 28 insertions(+)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 3780877e4e..a9b93c39d0 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -11,6 +11,34 @@ commit_message() {\n \tgit log --pretty=format:%s -1 \"$1\"\n }\n \n+# There are a few bugs in the rebase with regards to the subtree strategy, and\n+# this test script tries to document them.  First, the following commit history\n+# is generated (the onelines are shown, time flows from left to right):\n+#\n+# master1 - master2 - master3\n+#                             \\\n+# README ---------------------- Add subproject master - master4 - files_subtree/master5\n+#\n+# Where the merge moves the files master[123].t into the subdirectory\n+# files_subtree/ and master4 as well as files_subtree/master5 add files to that\n+# directory directly.\n+#\n+# Then, in subsequent test cases, `git filter-branch` is used to distill just\n+# the commits that touch files_subtree/. To give it a final pre-rebase touch,\n+# an empty commit is added on top. The pre-rebase commit history looks like\n+# this:\n+#\n+# Add subproject master - master4 - files_subtree/master5 - Empty commit\n+#\n+# where the root commit adds three files: master1.t, master2.t and master3.t.\n+#\n+# This commit history is then rebased onto `master3` 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+\n test_expect_success 'setup' '\n \ttest_commit README &&\n \tmkdir files &&\n-- \ngitgitgadget\n\n"},{"id":"379254","messageId":"9aeb57fa8f5c882f00c349e01a4459ce21c6cd24.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 04/12] t3427: condense the unnecessarily repetitive test cases into three","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:18Z","receivedAt":"2019-07-25T10:11:23Z","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\nPreviously, this test script performed essentially three rebases and\nverified breakages by testing the post-rebase commits' messages.\n\nTo do so, the rebases were performed multiple times, though, once per\ncommit message to test. This wastes electricity (and CO2) and time.\n\nLet's condense the test cases to the essential number: the number of\ndifferent rebases to validate.\n\nOn Windows, where the scripted nature of the `--preserve-merges` backend\nhurts performance rather badly, this reduces the overall runtime in this\ndeveloper's setup from ~1m to ~28s while still performing the exact same\ntesting as before.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 56 ++++++++-------------------------------\n 1 file changed, 11 insertions(+), 45 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex c0e6a49b61..7d3ba766de 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -64,65 +64,31 @@ test_expect_success 'setup' '\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n+test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: Does not preserve master5.\n-test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-5 to-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~)\" = \"files_subtree/master4\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n+test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: Does not preserve master5.\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-5 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n-'\n-\n-# FAILURE: Does not preserve Empty.\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-empty to-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)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n # FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-onto-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-onto-5 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n-'\n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto empty commit' '\n+test_expect_failure 'Rebase -Xsubtree --onto commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-empty to-rebase &&\n+\tgit checkout -b rebase-onto to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n+\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n-- \ngitgitgadget\n\n"},{"id":"379255","messageId":"3196413c2af972f5ba9745b6bc9f2f9e764e8116.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 05/12] t3427: fix erroneous assumption","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:18Z","receivedAt":"2019-07-25T10:11: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\nApart from the `setup` test case, `t3427-rebase-subtree.sh` is made up\nexclusively of demonstrations of breakages. The tricky thing about such\ndemonstrations is that they are often buggy themselves.\n\nIn this instance, somewhere over the course of the six iterations\nof the patch that eventually made it into Git's `master` as 5f35900849e\n(contrib/subtree: Add a test for subtree rebase that loses commits,\n2016-06-28), the commit message \"files_subtree/master4\" was changed to\njust \"master4\", but the test cases still expected the old commit\nmessage.\n\nLet's fix this, at long last.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 7d3ba766de..8c4ddd3408 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -68,7 +68,7 @@ test_expect_failure '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~)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"master4\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n \n@@ -77,7 +77,7 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm\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)\" = \"files_subtree/master4\" &&\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@@ -87,7 +87,7 @@ test_expect_failure 'Rebase -Xsubtree --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\" &&\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-- \ngitgitgadget\n\n"},{"id":"379256","messageId":"f7452d3740fc6183256f2d2cd5435421d8743ea4.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 07/12] t3427: fix another incorrect assumption","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:20Z","receivedAt":"2019-07-25T10:11: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\nThe test case that concerns `git rebase -Xsubtree` (with the\ndefault rebase backend, not with `--preserve-merges`) starts out with a\npre-rebase commit history that begins with a commit that introduces\nthree files: master1.t, master2.t and master3.t.\n\nThis commit was generated by passing a subtree merge commit through `git\nfilter-branch --subdirectory-filter`, so it looks as if this commit\nreally introduces all those files.\n\nThe commit history onto which this commit is then rebased, however,\nintroduced those files in individual commits. For that reason, the\nrebase will fail, it _must_ fail, because the first `pick` results in no\nchanges to be committed.\n\nLet's fix the test case to expect exactly this situation.\n\nWith this change, we can mark the original bug that this test case tried\nto demonstrate as fixed.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex b490919c60..c0ff3241e4 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -82,11 +82,12 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --onto commit' '\n+test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&\n+\ttest_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&\n+\t: first pick results in no changes &&\n+\tgit rebase --continue &&\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-- \ngitgitgadget\n\n"},{"id":"379257","messageId":"a3944c54802670d6a0cceba1921b67a1d01ff555.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 03/12] t3427: move the `filter-branch` invocation into the `setup` case","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:17Z","receivedAt":"2019-07-25T10:11: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\nThe step to prepare a pre-rebase commit history is _identical_ in _all_\nof the test cases (except of course the `setup` case). It should\ntherefore clearly a part of the `setup` test case instead.\n\nAs the `git filter-branch` command is quite costly on platforms where\nUnix shell scripting is simply slow (meaning: on Windows), this shaves\noff a noticeable part of the runtime: in this developer's setup, the\ntime was reduced from ~1m25s to ~1m.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 38 +++++++++++++-------------------------\n 1 file changed, 13 insertions(+), 25 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex f41a08e436..c0e6a49b61 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -56,15 +56,17 @@ test_expect_success 'setup' '\n \n \t: add two extra commits to rebase &&\n \ttest_commit -C files_subtree master4 &&\n-\ttest_commit files_subtree/master5\n+\ttest_commit files_subtree/master5 &&\n+\n+\tgit checkout -b to-rebase &&\n+\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n+\tgit commit -m \"Empty commit\" --allow-empty\n '\n \n # FAILURE: Does not preserve master4.\n test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-preserve-merges-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master4\"\n '\n@@ -72,9 +74,7 @@ test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n # FAILURE: Does not preserve master5.\n test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-preserve-merges-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n@@ -82,9 +82,7 @@ test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n # FAILURE: Does not preserve master4.\n test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n '\n@@ -92,9 +90,7 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm\n # FAILURE: Does not preserve master5.\n test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n '\n@@ -102,9 +98,7 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm\n # FAILURE: Does not preserve Empty.\n test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-empty master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-empty to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n@@ -112,9 +106,7 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empt\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n '\n@@ -122,18 +114,14 @@ test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n '\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto empty commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-empty master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-empty to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n-- \ngitgitgadget\n\n"},{"id":"379258","messageId":"30405df99ff38466987e64c1dea007ff6fb9b8c8.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 09/12] rebase -r: support merge strategies other than `recursive`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:21Z","receivedAt":"2019-07-25T10:11: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\nWe already support merge strategies in the sequencer, but only for\n`pick` commands.\n\nWith this commit, we now also support them in `merge` commands. The\napproach is simple: if any merge strategy option is specified, or if any\nmerge strategy other than `recursive` is specified, we simply spawn the\n`git merge` command. Otherwise, we handle the merge in-process just as\nbefore.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-rebase.txt           |  2 --\n builtin/rebase.c                       |  9 ---------\n sequencer.c                            | 14 ++++++++++++--\n t/t3422-rebase-incompatible-options.sh | 10 ----------\n t/t3430-rebase-merges.sh               | 21 +++++++++++++++++++++\n 5 files changed, 33 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex f5e6ae3907..f67f96425c 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -543,8 +543,6 @@ In addition, the following pairs of options are incompatible:\n  * --preserve-merges and --interactive\n  * --preserve-merges and --signoff\n  * --preserve-merges and --rebase-merges\n- * --rebase-merges and --strategy\n- * --rebase-merges and --strategy-option\n \n BEHAVIORAL DIFFERENCES\n -----------------------\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 9c52144fc4..c1ea617125 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1815,15 +1815,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t      \"'--reschedule-failed-exec'\"));\n \t}\n \n-\tif (options.rebase_merges) {\n-\t\tif (strategy_options.nr)\n-\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n-\t\t\t      \"'--strategy-option'\"));\n-\t\tif (options.strategy)\n-\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n-\t\t\t      \"'--strategy'\"));\n-\t}\n-\n \tif (!options.root) {\n \t\tif (argc < 1) {\n \t\t\tstruct branch *branch;\ndiff --git a/sequencer.c b/sequencer.c\nindex 334de14542..d228448cd8 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3256,6 +3256,9 @@ static int do_merge(struct repository *r,\n \tstruct commit *head_commit, *merge_commit, *i;\n \tstruct commit_list *bases, *j, *reversed = NULL;\n \tstruct commit_list *to_merge = NULL, **tail = &to_merge;\n+\tconst char *strategy = !opts->xopts_nr &&\n+\t\t(!opts->strategy || !strcmp(opts->strategy, \"recursive\")) ?\n+\t\tNULL : opts->strategy;\n \tstruct merge_options o;\n \tint merge_arg_len, oneline_offset, can_fast_forward, ret, k;\n \tstatic struct lock_file lock;\n@@ -3404,7 +3407,7 @@ static int do_merge(struct repository *r,\n \t\tgoto leave_merge;\n \t}\n \n-\tif (to_merge->next) {\n+\tif (strategy || to_merge->next) {\n \t\t/* Octopus merge */\n \t\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \n@@ -3418,7 +3421,14 @@ static int do_merge(struct repository *r,\n \t\tcmd.git_cmd = 1;\n \t\targv_array_push(&cmd.args, \"merge\");\n \t\targv_array_push(&cmd.args, \"-s\");\n-\t\targv_array_push(&cmd.args, \"octopus\");\n+\t\tif (!strategy)\n+\t\t\targv_array_push(&cmd.args, \"octopus\");\n+\t\telse {\n+\t\t\targv_array_push(&cmd.args, strategy);\n+\t\t\tfor (k = 0; k < opts->xopts_nr; k++)\n+\t\t\t\targv_array_pushf(&cmd.args,\n+\t\t\t\t\t\t \"-X%s\", opts->xopts[k]);\n+\t\t}\n \t\targv_array_push(&cmd.args, \"--no-edit\");\n \t\targv_array_push(&cmd.args, \"--no-ff\");\n \t\targv_array_push(&cmd.args, \"--no-log\");\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex bb78a6ec86..596caf168a 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -75,14 +75,4 @@ test_expect_success '--preserve-merges incompatible with --rebase-merges' '\n \ttest_must_fail git rebase --preserve-merges --rebase-merges A\n '\n \n-test_expect_success '--rebase-merges incompatible with --strategy' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --rebase-merges -s resolve A\n-'\n-\n-test_expect_success '--rebase-merges incompatible with --strategy-option' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --rebase-merges -Xignore-space-change A\n-'\n-\n test_done\ndiff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh\nindex 42ba5b9f09..8ea6ff3548 100755\n--- a/t/t3430-rebase-merges.sh\n+++ b/t/t3430-rebase-merges.sh\n@@ -412,4 +412,25 @@ test_expect_success '--continue after resolving conflicts after a merge' '\n \ttest_path_is_missing .git/MERGE_HEAD\n '\n \n+test_expect_success '--rebase-merges with strategies' '\n+\tgit checkout -b with-a-strategy F &&\n+\ttest_tick &&\n+\tgit merge -m \"Merge conflicting-G\" conflicting-G &&\n+\n+\t: first, test with a merge strategy option &&\n+\tgit rebase -ir -Xtheirs G &&\n+\techo conflicting-G >expect &&\n+\ttest_cmp expect G.t &&\n+\n+\t: now, try with a merge strategy other than recursive &&\n+\tgit reset --hard @{1} &&\n+\twrite_script git-merge-override <<-\\EOF &&\n+\techo overridden$1 >>G.t\n+\tgit add G.t\n+\tEOF\n+\tPATH=\"$PWD:$PATH\" git rebase -ir -s override -Xxopt G &&\n+\ttest_write_lines G overridden--xopt >expect &&\n+\ttest_cmp expect G.t\n+'\n+\n test_done\n-- \ngitgitgadget\n\n"},{"id":"379259","messageId":"ae9e72b73bf2da0de3a5369748ebd358656588d9.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 10/12] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:22Z","receivedAt":"2019-07-25T10:11: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\nThe format of the todo list is quite a bit different in the\n`--rebase-merges` mode; Let's prepare the fake editor to handle those\ntodo lists properly, too.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/lib-rebase.sh | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\nindex 7ea30e5006..662a958575 100644\n--- a/t/lib-rebase.sh\n+++ b/t/lib-rebase.sh\n@@ -44,10 +44,10 @@ set_fake_editor () {\n \trm -f \"$1\"\n \techo 'rebase -i script before editing:'\n \tcat \"$1\".tmp\n-\taction=pick\n+\taction=\\&\n \tfor line in $FAKE_LINES; do\n \t\tcase $line in\n-\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n+\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)\n \t\t\taction=\"$line\";;\n \t\texec_*|x_*|break|b)\n \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n@@ -61,8 +61,8 @@ set_fake_editor () {\n \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n \t\t\taction=pick;;\n \t\t*)\n-\t\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n-\t\t\taction=pick;;\n+\t\t\tsed -n \"${line}s/^[a-z][a-z]*/$action/p\" < \"$1\".tmp >> \"$1\"\n+\t\t\taction=\\&;;\n \t\tesac\n \tdone\n \techo 'rebase -i script after editing:'\n-- \ngitgitgadget\n\n"},{"id":"379260","messageId":"e6713568dc9170acd671d3c737939c829937b5b5.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 12/12] rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:23Z","receivedAt":"2019-07-25T10:11:29Z","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\nWhen rebasing a complete commit history onto a given commit, it is\npretty obvious that the root commits should be rebased on top of said\ngiven commit.\n\nTo test this, let's kill two birds with one stone and add a test case to\nt3427-rebase-subtree.sh that not only demonstrates that this works, but\nalso that `git rebase -r` works with merge strategies now.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c          |  7 +++++--\n sequencer.c               |  4 +++-\n sequencer.h               |  6 ++++++\n t/t3427-rebase-subtree.sh | 11 +++++++++++\n 4 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex c1ea617125..6a789c4421 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -62,7 +62,7 @@ struct rebase_options {\n \tconst char *onto_name;\n \tconst char *revisions;\n \tconst char *switch_to;\n-\tint root;\n+\tint root, root_with_onto;\n \tstruct object_id *squash_onto;\n \tstruct commit *restrict_revision;\n \tint dont_finish_rebase;\n@@ -374,6 +374,7 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \tflags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;\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 \n \tswitch (command) {\n@@ -1845,7 +1846,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\toptions.squash_onto = &squash_onto;\n \t\t\toptions.onto_name = squash_onto_name =\n \t\t\t\txstrdup(oid_to_hex(&squash_onto));\n-\t\t}\n+\t\t} else\n+\t\t\toptions.root_with_onto = 1;\n+\n \t\toptions.upstream_name = NULL;\n \t\toptions.upstream = NULL;\n \t\tif (argc > 1)\ndiff --git a/sequencer.c b/sequencer.c\nindex d228448cd8..ca119c84e5 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4440,6 +4440,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,\n {\n \tint keep_empty = flags & TODO_LIST_KEEP_EMPTY;\n \tint rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;\n+\tint root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;\n \tstruct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;\n \tstruct strbuf label = STRBUF_INIT;\n \tstruct commit_list *commits = NULL, **tail = &commits, *iter;\n@@ -4606,7 +4607,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,\n \n \t\tif (!commit)\n \t\t\tstrbuf_addf(out, \"%s %s\\n\", cmd_reset,\n-\t\t\t\t    rebase_cousins ? \"onto\" : \"[new root]\");\n+\t\t\t\t    rebase_cousins || root_with_onto ?\n+\t\t\t\t    \"onto\" : \"[new root]\");\n \t\telse {\n \t\t\tconst char *to = NULL;\n \ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d4..d506081d3c 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -142,6 +142,12 @@ int sequencer_remove_state(struct replay_opts *opts);\n  */\n #define TODO_LIST_REBASE_COUSINS (1U << 4)\n #define TODO_LIST_APPEND_TODO_HELP (1U << 5)\n+/*\n+ * When generating a script that rebases merges with `--root` *and* with\n+ * `--onto`, we do not want to re-generate the root commits.\n+ */\n+#define TODO_LIST_ROOT_WITH_ONTO (1U << 6)\n+\n \n int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,\n \t\t\t  const char **argv, unsigned flags);\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 7a37235768..39e348de16 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -93,4 +93,15 @@ test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n+test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '\n+\treset_rebase &&\n+\tgit checkout -b rebase-merges-onto to-rebase &&\n+\ttest_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&\n+\t: first pick results in no changes &&\n+\tgit rebase --continue &&\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_done\n-- \ngitgitgadget\n"},{"id":"379261","messageId":"7f60b8e745bd1e1c556c28510ee4211e975d9b6a.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 08/12] t3427: mark two test cases as requiring support for `git rebase -p`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:20Z","receivedAt":"2019-07-25T10:11: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\nTo prepare for the long game, where the `--preserve-merges` backend will\nbe dropped eventually, we already introduced the `REBASE_P` prerequisite\nto allow saving time by skipping the now-almost-pointless test cases\nthat verify that that backend works as expected.\n\nDue to the nature of the tests in t3427 (`test_expect_failure` is happy\nas long as the scriptlet fails, whether it is for the intended reason or\nbecause `git-rebase--preserve-merges.sh` was deleted), these two test\ncases were missed.\n\nWhen running with GIT_TEST_SKIP_REBASE_P=OhYesPlease, this drops the\noverall run time of t3427 on this developer's machine from ~28s to\n~8.5s.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex c0ff3241e4..7a37235768 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -64,7 +64,7 @@ test_expect_success 'setup' '\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit' '\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@@ -73,7 +73,7 @@ test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit' '\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\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-- \ngitgitgadget\n\n"},{"id":"379262","messageId":"a326be77aa05b88bfa9fc036b1551e7c2ae3ab2a.1564049474.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 11/12] t3418: test `rebase -r` with merge strategies","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:23Z","receivedAt":"2019-07-25T10:11:31Z","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\nThere is a test case in this script that verifies that `git rebase\n--preserve-merges` works all right with non-default merge strategies or\nnon-default merge strategy options.\n\nNow that `git rebase --rebase-merges` learned about merge strategies,\nlet's copy-edit this test case to verify that that works as intended,\ntoo.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3418-rebase-continue.sh | 14 ++++++++++++++\n 1 file changed, 14 insertions(+)\n\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex bdaa511bb0..fbf9addfd1 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -120,6 +120,20 @@ test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '\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+\ttest_commit merge-theirs &&\n+\tgit reset --hard HEAD^ &&\n+\ttest_commit some-other-commit &&\n+\ttest_tick &&\n+\tgit merge --no-ff merge-theirs &&\n+\tFAKE_LINES=\"1 3 edit 4 5 7 8 9\" git rebase -i -f -r -m \\\n+\t\t-s recursive --strategy-option=theirs HEAD~2 &&\n+\ttest_commit force-change-ours &&\n+\tgit rebase --continue\n+'\n+\n test_expect_success '--skip after failed fixup cleans commit message' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n \tgit checkout -b with-conflicting-fixup &&\n-- \ngitgitgadget\n\n"},{"id":"379263","messageId":"261825fe442a428ea0724ab6ae9d8d351bda8d3e.1564049473.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH 06/12] t3427: accommodate for the `rebase --merge` backend having been replaced","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-25T10:11:19Z","receivedAt":"2019-07-25T10:11: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\nSince 68aa495b590 (rebase: implement --merge via the interactive\nmachinery, 2018-12-11), the job of the old `--merge` backend is now\nperformed by the `--interactive` backend, too.\n\nOne consequence is that empty commits are no longer rebased by default.\n\nMeaning that the test case that calls `git rebase -Xsubtree` (which used\nto be handled by the `--merge` backend) now needs to ask explicitly for\nthe empty commit to be rebased.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 8c4ddd3408..b490919c60 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -83,10 +83,10 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm\n '\n \n # FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit' '\n+test_expect_failure 'Rebase -Xsubtree --keep-empty --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n+\tgit rebase -Xsubtree=files_subtree --keep-empty --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-- \ngitgitgadget\n\n"},{"id":"379282","messageId":"xmqqftmuoxa1.fsf@gitster-ct.c.googlers.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/12] rebase -r: support merge strategies other than recursive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-07-25T17:10:30Z","receivedAt":"2019-07-25T17:10:39Z","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> ... As a consolation to myself, this work was actually worth it, surprising as\n> that may look. Not only is t3427 now really easy to understand, adding that\n> test case for --rebase-merges -Xsubtree tickled the sequencer enough to\n> reveal a long-standing bug: the --onto option was simply ignored when passed\n> together with --rebase-merges and --root. For good measure, this patch\n> series addresses this bug, too.\n\nVery nice.\n\n> base-commit: 082ef75b7bfc90ac236afbb857a9552a026832b8\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-294%2Fdscho%2Frebase-r-with-strategies-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-294/dscho/rebase-r-with-strategies-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/294\n"},{"id":"379329","messageId":"20190726074317.GD9319@genre.crustytoothpaste.net","threadId":"51522","inReplyTo":"ae9e72b73bf2da0de3a5369748ebd358656588d9.1564049474.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 10/12] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2019-07-26T07:43:17Z","receivedAt":"2019-07-26T07:43:28Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2019-07-25 at 10:11:22, Johannes Schindelin via GitGitGadget wrote:\n> From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> \n> The format of the todo list is quite a bit different in the\n> `--rebase-merges` mode; Let's prepare the fake editor to handle those\n> todo lists properly, too.\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  t/lib-rebase.sh | 8 ++++----\n>  1 file changed, 4 insertions(+), 4 deletions(-)\n> \n> diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\n> index 7ea30e5006..662a958575 100644\n> --- a/t/lib-rebase.sh\n> +++ b/t/lib-rebase.sh\n> @@ -44,10 +44,10 @@ set_fake_editor () {\n>  \trm -f \"$1\"\n>  \techo 'rebase -i script before editing:'\n>  \tcat \"$1\".tmp\n> -\taction=pick\n> +\taction=\\&\n\nSo we set action to \"&\" so we can use it as the result in the sed\nexpression below…\n\n>  \tfor line in $FAKE_LINES; do\n>  \t\tcase $line in\n> -\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n> +\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)\n>  \t\t\taction=\"$line\";;\n>  \t\texec_*|x_*|break|b)\n>  \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n> @@ -61,8 +61,8 @@ set_fake_editor () {\n>  \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n\nbut then here it doesn't look like \"&\" is a thing we'd want to use. Is\nthere something I'm missing about this particular case?\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"379330","messageId":"20190726075210.GE9319@genre.crustytoothpaste.net","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/12] rebase -r: support merge strategies other than recursive","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2019-07-26T07:52:11Z","receivedAt":"2019-07-26T07:52:18Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2019-07-25 at 10:11:14, Johannes Schindelin via GitGitGadget wrote:\n> This is the most notable shortcoming that --rebase-merges has, still,\n> relative to --preserve-merges' capabilities: it does not support passing\n> custom merge strategies or custom merge strategy options.\n> \n> Let's fix this.\n\nThis looks like a great improvement. I'm glad to see --rebase-merges\ngaining feature parity with --preserve-merges.\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"379339","messageId":"nycvar.QRO.7.76.6.1907261555410.21907@tvgsbejvaqbjf.bet","threadId":"51522","inReplyTo":"20190726074317.GD9319@genre.crustytoothpaste.net","subject":"Re: [PATCH 10/12] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-07-26T14:01:03Z","receivedAt":"2019-07-26T14:01:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi brian,\n\nOn Fri, 26 Jul 2019, brian m. carlson wrote:\n\n> On 2019-07-25 at 10:11:22, Johannes Schindelin via GitGitGadget wrote:\n> > From: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > The format of the todo list is quite a bit different in the\n> > `--rebase-merges` mode; Let's prepare the fake editor to handle those\n> > todo lists properly, too.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  t/lib-rebase.sh | 8 ++++----\n> >  1 file changed, 4 insertions(+), 4 deletions(-)\n> >\n> > diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\n> > index 7ea30e5006..662a958575 100644\n> > --- a/t/lib-rebase.sh\n> > +++ b/t/lib-rebase.sh\n> > @@ -44,10 +44,10 @@ set_fake_editor () {\n> >  \trm -f \"$1\"\n> >  \techo 'rebase -i script before editing:'\n> >  \tcat \"$1\".tmp\n> > -\taction=pick\n> > +\taction=\\&\n>\n> So we set action to \"&\" so we can use it as the result in the sed\n> expression below…\n>\n> >  \tfor line in $FAKE_LINES; do\n> >  \t\tcase $line in\n> > -\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n> > +\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)\n> >  \t\t\taction=\"$line\";;\n> >  \t\texec_*|x_*|break|b)\n> >  \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n> > @@ -61,8 +61,8 @@ set_fake_editor () {\n> >  \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n>\n> but then here it doesn't look like \"&\" is a thing we'd want to use. Is\n> there something I'm missing about this particular case?\n\nActually, the part that uses it is not shown in the patch (one of the\nmany, many reasons why I try to discourage patch review and encourage\ncode review instead). The relevant section currently looks somewhat like\nthis:\n\n-- snip --\nset_fake_editor () {\n\twrite_script fake-editor.sh <<-\\EOF\n\tcase \"$1\" in\n\t*/COMMIT_EDITMSG)\n\t\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n\t\t\ttest \"$EXPECT_HEADER_COUNT\" = \"$(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\")\" ||\n\t\t\ttest \"# # GETTEXT POISON #\" = \"$(sed -n '1p' < \"$1\")\" ||\n\t\t\texit\n\t\ttest -z \"$FAKE_COMMIT_MESSAGE\" || echo \"$FAKE_COMMIT_MESSAGE\" > \"$1\"\n\t\ttest -z \"$FAKE_COMMIT_AMEND\" || echo \"$FAKE_COMMIT_AMEND\" >> \"$1\"\n\t\texit\n\t\t;;\n\tesac\n\ttest -z \"$EXPECT_COUNT\" ||\n\t\ttest \"$EXPECT_COUNT\" = $(sed -e '/^#/d' -e '/^$/d' < \"$1\" | wc -l) ||\n\t\texit\n\ttest -z \"$FAKE_LINES\" && exit\n\tgrep -v '^#' < \"$1\" > \"$1\".tmp\n\trm -f \"$1\"\n\techo 'rebase -i script before editing:'\n\tcat \"$1\".tmp\n\taction=pick\n\tfor line in $FAKE_LINES; do\n\t\tcase $line in\n\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n\t\t\taction=\"$line\";;\n\t\texec_*|x_*|break|b)\n\t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n\t\t\"#\")\n\t\t\techo '# comment' >> \"$1\";;\n\t\t\">\")\n\t\t\techo >> \"$1\";;\n\t\tbad)\n\t\t\taction=\"badcmd\";;\n\t\tfakesha)\n\t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n\t\t\taction=pick;;\n\t\t*)\n\t\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n\t\t\taction=pick;;\n\t\tesac\n\tdone\n\techo 'rebase -i script after editing:'\n\tcat \"$1\"\n\tEOF\n\n\ttest_set_editor \"$(pwd)/fake-editor.sh\"\n}\n-- snap --\n\nMost importantly, `action` is used here:\n\n                        sed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n\nand I changed it to\n\n\t\t\tsed -n \"${line}s/^[a-z][a-z]*/$action/p\" < \"$1\".tmp >> \"$1\"\n\nIn other words, rather than expecting the lines that are used by the\nfake editor to start with `pick`, after this patch, the tests expect the\ntodo lists to start with a command consisting of lower-case ASCII\nletters (which catches `pick`, of course, but also `label`, `reset` and\n`merge`).\n\nAfter this patch, the fake editor also does not try to replace whatever\ncommand it finds by `pick`, but it keeps it as-is instead.\n\nCiao,\nDscho\n"},{"id":"379402","messageId":"20190726210820.GF9319@genre.crustytoothpaste.net","threadId":"51522","inReplyTo":"nycvar.QRO.7.76.6.1907261555410.21907@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 10/12] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2019-07-26T21:08:20Z","receivedAt":"2019-07-26T21:08:28Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2019-07-26 at 14:01:03, Johannes Schindelin wrote:\n> Actually, the part that uses it is not shown in the patch (one of the\n> many, many reasons why I try to discourage patch review and encourage\n> code review instead). The relevant section currently looks somewhat like\n> this:\n\nI feel like I may have communicated poorly earlier, so let me retry\nasking this in a different way.\n\n> -- snip --\n> set_fake_editor () {\n> \twrite_script fake-editor.sh <<-\\EOF\n> \tcase \"$1\" in\n> \t*/COMMIT_EDITMSG)\n> \t\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n> \t\t\ttest \"$EXPECT_HEADER_COUNT\" = \"$(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\")\" ||\n> \t\t\ttest \"# # GETTEXT POISON #\" = \"$(sed -n '1p' < \"$1\")\" ||\n> \t\t\texit\n> \t\ttest -z \"$FAKE_COMMIT_MESSAGE\" || echo \"$FAKE_COMMIT_MESSAGE\" > \"$1\"\n> \t\ttest -z \"$FAKE_COMMIT_AMEND\" || echo \"$FAKE_COMMIT_AMEND\" >> \"$1\"\n> \t\texit\n> \t\t;;\n> \tesac\n> \ttest -z \"$EXPECT_COUNT\" ||\n> \t\ttest \"$EXPECT_COUNT\" = $(sed -e '/^#/d' -e '/^$/d' < \"$1\" | wc -l) ||\n> \t\texit\n> \ttest -z \"$FAKE_LINES\" && exit\n> \tgrep -v '^#' < \"$1\" > \"$1\".tmp\n> \trm -f \"$1\"\n> \techo 'rebase -i script before editing:'\n> \tcat \"$1\".tmp\n> \taction=pick\n\nI believe you changed this line to \"action=\\&\".\n\n> \tfor line in $FAKE_LINES; do\n> \t\tcase $line in\n> \t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n> \t\t\taction=\"$line\";;\n> \t\texec_*|x_*|break|b)\n> \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n> \t\t\"#\")\n> \t\t\techo '# comment' >> \"$1\";;\n> \t\t\">\")\n> \t\t\techo >> \"$1\";;\n> \t\tbad)\n> \t\t\taction=\"badcmd\";;\n> \t\tfakesha)\n> \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n\nAnd my question was about this line.\n\n> \t\t\taction=pick;;\n> \t\t*)\n> \t\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n> \t\t\taction=pick;;\n> \t\tesac\n> \tdone\n> \techo 'rebase -i script after editing:'\n> \tcat \"$1\"\n> \tEOF\n> \n> \ttest_set_editor \"$(pwd)/fake-editor.sh\"\n> }\n> -- snap --\n> \n> Most importantly, `action` is used here:\n> \n>                         sed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n> \n> and I changed it to\n> \n> \t\t\tsed -n \"${line}s/^[a-z][a-z]*/$action/p\" < \"$1\".tmp >> \"$1\"\n> \n> In other words, rather than expecting the lines that are used by the\n> fake editor to start with `pick`, after this patch, the tests expect the\n> todo lists to start with a command consisting of lower-case ASCII\n> letters (which catches `pick`, of course, but also `label`, `reset` and\n> `merge`).\n> \n> After this patch, the fake editor also does not try to replace whatever\n> command it finds by `pick`, but it keeps it as-is instead.\n\nRight, that's how I read it, and that part I agree with. I think my\nquestion is this: in what case do we execute the \"fakesha\" case? Are we\nguaranteed that when we do, action isn't \"&\"? \"&\" seems fine for the\nright-hand side of a sed s-statement, but not as the beginning of a\ntypical line in a sequencer file.\n\nI ask because if we're testing a failure case, we want it to fail for\nthe right reason (e.g., the commit doesn't exist), and not because we're\nproducing invalid data. If the answer in this case is, \"Well, we'll\nalways have something else before it which will set $action properly,\"\nthen that's fine. This is test code, so it need not be bulletproof, but\nI did want to ask.\n\nIf I'm still misunderstanding something, I apologize.\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"379658","messageId":"nycvar.QRO.7.76.6.1907311306360.21907@tvgsbejvaqbjf.bet","threadId":"51522","inReplyTo":"20190726210820.GF9319@genre.crustytoothpaste.net","subject":"Re: [PATCH 10/12] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-07-31T11:25:42Z","receivedAt":"2019-07-31T11:25:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi brian,\n\nOn Fri, 26 Jul 2019, brian m. carlson wrote:\n\n> On 2019-07-26 at 14:01:03, Johannes Schindelin wrote:\n> > Actually, the part that uses it is not shown in the patch (one of the\n> > many, many reasons why I try to discourage patch review and encourage\n> > code review instead). The relevant section currently looks somewhat like\n> > this:\n>\n> I feel like I may have communicated poorly earlier, so let me retry\n> asking this in a different way.\n\nActually, your communication was just fine, the misunderstanding was\nentirely on my side. My apologies.\n\n> > -- snip --\n> > set_fake_editor () {\n> > \twrite_script fake-editor.sh <<-\\EOF\n> > \tcase \"$1\" in\n> > \t*/COMMIT_EDITMSG)\n> > \t\ttest -z \"$EXPECT_HEADER_COUNT\" ||\n> > \t\t\ttest \"$EXPECT_HEADER_COUNT\" = \"$(sed -n '1s/^# This is a combination of \\(.*\\) commits\\./\\1/p' < \"$1\")\" ||\n> > \t\t\ttest \"# # GETTEXT POISON #\" = \"$(sed -n '1p' < \"$1\")\" ||\n> > \t\t\texit\n> > \t\ttest -z \"$FAKE_COMMIT_MESSAGE\" || echo \"$FAKE_COMMIT_MESSAGE\" > \"$1\"\n> > \t\ttest -z \"$FAKE_COMMIT_AMEND\" || echo \"$FAKE_COMMIT_AMEND\" >> \"$1\"\n> > \t\texit\n> > \t\t;;\n> > \tesac\n> > \ttest -z \"$EXPECT_COUNT\" ||\n> > \t\ttest \"$EXPECT_COUNT\" = $(sed -e '/^#/d' -e '/^$/d' < \"$1\" | wc -l) ||\n> > \t\texit\n> > \ttest -z \"$FAKE_LINES\" && exit\n> > \tgrep -v '^#' < \"$1\" > \"$1\".tmp\n> > \trm -f \"$1\"\n> > \techo 'rebase -i script before editing:'\n> > \tcat \"$1\".tmp\n> > \taction=pick\n>\n> I believe you changed this line to \"action=\\&\".\n>\n> > \tfor line in $FAKE_LINES; do\n> > \t\tcase $line in\n> > \t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n> > \t\t\taction=\"$line\";;\n> > \t\texec_*|x_*|break|b)\n> > \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n> > \t\t\"#\")\n> > \t\t\techo '# comment' >> \"$1\";;\n> > \t\t\">\")\n> > \t\t\techo >> \"$1\";;\n> > \t\tbad)\n> > \t\t\taction=\"badcmd\";;\n> > \t\tfakesha)\n> > \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n>\n> And my question was about this line.\n\nRight. It would append `& XXXXXXX False commit`, which is not a valid\ntodo command.\n\nSo something like\n\n-\t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n+\t\t\ttest \\& = \"$action\" && c=pick || c=$action\n+\t\t\techo \"$c XXXXXXX False commit\" >>\"$1\"\n\nwould be needed.\n\nHowever, what makes me really worried now is that our test suite did not\nhave a fit about this. The CI build passes the test suite on Windows,\nmacOS and Linux: https://github.com/gitgitgadget/git/runs/176651523.\n>\n> > \t\t\taction=pick;;\n> > \t\t*)\n> > \t\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n> > \t\t\taction=pick;;\n> > \t\tesac\n> > \tdone\n> > \techo 'rebase -i script after editing:'\n> > \tcat \"$1\"\n> > \tEOF\n> >\n> > \ttest_set_editor \"$(pwd)/fake-editor.sh\"\n> > }\n> > -- snap --\n> >\n> > Most importantly, `action` is used here:\n> >\n> >                         sed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n> >\n> > and I changed it to\n> >\n> > \t\t\tsed -n \"${line}s/^[a-z][a-z]*/$action/p\" < \"$1\".tmp >> \"$1\"\n> >\n> > In other words, rather than expecting the lines that are used by the\n> > fake editor to start with `pick`, after this patch, the tests expect the\n> > todo lists to start with a command consisting of lower-case ASCII\n> > letters (which catches `pick`, of course, but also `label`, `reset` and\n> > `merge`).\n> >\n> > After this patch, the fake editor also does not try to replace whatever\n> > command it finds by `pick`, but it keeps it as-is instead.\n>\n> Right, that's how I read it, and that part I agree with. I think my\n> question is this: in what case do we execute the \"fakesha\" case? Are we\n> guaranteed that when we do, action isn't \"&\"? \"&\" seems fine for the\n> right-hand side of a sed s-statement, but not as the beginning of a\n> typical line in a sequencer file.\n\nIndeed, the sequencer should throw a real tantrum about this and not\neven bother to start.\n\nBut then, the same would hold true for an obviously invalid commit hash.\n\n> I ask because if we're testing a failure case, we want it to fail for\n> the right reason (e.g., the commit doesn't exist), and not because we're\n> producing invalid data.\n\nIndeed. I have even come to the conclusion that our\n`test_expect_failure` command encourages exactly this type of problem:\nin the beginning, those test cases might actually be correct, but over\ntime they are prone to fail for all the wrong reasons, because we do not\nactually test for a specific failure more, we just say that we expect\nthis test case to fail (and that this indicates a bug).\n\n> If the answer in this case is, \"Well, we'll always have something else\n> before it which will set $action properly,\" then that's fine. This is\n> test code, so it need not be bulletproof, but I did want to ask.\n\nI think you are perfectly sane to question this, and to expect me to\ndouble check.\n\nSo, double check I did. Turns out there is a single user of the\n`fakesha` thing, and it is hidden deep in t3404, prefixed by\n`test_must_fail`:\n\n-- snip --\ntest_expect_success 'static check of bad SHA-1' '\n\trebase_setup_and_clean bad-sha &&\n\tset_fake_editor &&\n\ttest_must_fail env FAKE_LINES=\"1 2 edit fakesha 3 4 5 #\" \\\n\t\tgit rebase -i --root 2>actual &&\n\ttest_i18ngrep \"edit XXXXXXX False commit\" actual &&\n\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" actual &&\n\tFAKE_LINES=\"1 2 4 5 6\" git rebase --edit-todo &&\n\tgit rebase --continue &&\n\ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n'\n-- snap --\n\nAs you can see, contrary to my expectations it does verify the output.\nIt *also* changes the action to `edit`, which is the reason why there is\nno `&` ;-)\n\nBut I think you are correct, I should make sure that the fake editor is\nstill correct with respect to the `pick` command.\n\n> If I'm still misunderstanding something, I apologize.\n\nI am really impressed and inspired by your gentle language. Thank you\nfor this.\n\nCiao,\nDscho\n"},{"id":"379669","messageId":"6e8be7d87352cdd01d92cf4d608b4e32097db27d.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 02/16] t3400: stop referring to the scripted rebase","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:39Z","receivedAt":"2019-07-31T15:18:43Z","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\nOne test case's title mentioned the then-current implementation detail\nthat the `--am` backend was implemented in `git-rebase--am.sh`.\n\nThis is no longer the case, so let's update the title to reflect the\ncurrent reality.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t3400-rebase.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 42f147858d..80b23fd326 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -285,7 +285,7 @@ EOF\n \ttest_cmp From_.msg out\n '\n \n-test_expect_success 'rebase--am.sh and --show-current-patch' '\n+test_expect_success 'rebase --am and --show-current-patch' '\n \ttest_create_repo conflict-apply &&\n \t(\n \t\tcd conflict-apply &&\n-- \ngitgitgadget\n\n"},{"id":"379670","messageId":"9e00e66dc70cf6600180a63e44737456d335f7b9.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 03/16] .gitignore: there is no longer a built-in `git-rebase--interactive`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:40Z","receivedAt":"2019-07-31T15:18: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\nThis went away in 0609b741a4 (rebase -i: combine rebase--interactive.c\nwith rebase.c, 2019-04-17).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n .gitignore | 1 -\n 1 file changed, 1 deletion(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 875f3fc6e8..bcee4fda81 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -123,7 +123,6 @@\n /git-read-tree\n /git-rebase\n /git-rebase--common\n-/git-rebase--interactive\n /git-rebase--preserve-merges\n /git-receive-pack\n /git-reflog\n-- \ngitgitgadget\n\n"},{"id":"379671","messageId":"b3daf078e8804dc7bb9099fa1a0b723c8357ac76.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 06/16] t3427: add a clarifying comment","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:42Z","receivedAt":"2019-07-31T15:18: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\nThe flow of this test script is outright confusing, and to start the\nendeavor to address that, let's describe what this test is all about,\nand how it tries to do it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 28 ++++++++++++++++++++++++++++\n 1 file changed, 28 insertions(+)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex d8640522a0..3a2ae7b55d 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -11,6 +11,34 @@ commit_message() {\n \tgit log --pretty=format:%s -1 \"$1\"\n }\n \n+# There are a few bugs in the rebase with regards to the subtree strategy, and\n+# this test script tries to document them.  First, the following commit history\n+# is generated (the onelines are shown, time flows from left to right):\n+#\n+# master1 - master2 - master3\n+#                             \\\n+# README ---------------------- Add subproject master - master4 - files_subtree/master5\n+#\n+# Where the merge moves the files master[123].t into the subdirectory\n+# files_subtree/ and master4 as well as files_subtree/master5 add files to that\n+# directory directly.\n+#\n+# Then, in subsequent test cases, `git filter-branch` is used to distill just\n+# the commits that touch files_subtree/. To give it a final pre-rebase touch,\n+# an empty commit is added on top. The pre-rebase commit history looks like\n+# this:\n+#\n+# Add subproject master - master4 - files_subtree/master5 - Empty commit\n+#\n+# where the root commit adds three files: master1.t, master2.t and master3.t.\n+#\n+# This commit history is then rebased onto `master3` 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+\n test_expect_success 'setup' '\n \ttest_commit README &&\n \tmkdir files &&\n-- \ngitgitgadget\n\n"},{"id":"379672","messageId":"db9ec248e1be7144602b7dfff7972249851d30e1.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 04/16] sequencer: the `am` and `rebase--interactive` scripts are gone","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:40Z","receivedAt":"2019-07-31T15:18:47Z","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\nUpdate a code comment that referred to those files as if they were still\nthere.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sequencer.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex f88a97fb10..334de14542 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -767,7 +767,7 @@ static int parse_key_value_squoted(char *buf, struct string_list *list)\n  *\tGIT_AUTHOR_DATE='$author_date'\n  *\n  * where $author_name, $author_email and $author_date are quoted. We are strict\n- * with our parsing, as the file was meant to be eval'd in the old\n+ * with our parsing, as the file was meant to be eval'd in the now-removed\n  * git-am.sh/git-rebase--interactive.sh scripts, and thus if the file differs\n  * from what this function expects, it is better to bail out than to do\n  * something that the user does not expect.\n-- \ngitgitgadget\n\n"},{"id":"379674","messageId":"pull.294.v2.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.git.gitgitgadget@gmail.com","subject":"[PATCH v2 00/16] rebase -r: support merge strategies other than recursive","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:37Z","receivedAt":"2019-07-31T15:18:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This is the most notable shortcoming that --rebase-merges has, still,\nrelative to --preserve-merges' capabilities: it does not support passing\ncustom merge strategies or custom merge strategy options.\n\nLet's fix this.\n\nWhile working on this patch series, of course I tried to copy-edit the test\ncases we have, to cover --preserve-merges' support for merge strategies. Oh\nmy, did I regret this decision as soon as my eyes set sight on \nt3427-rebase-subtree.sh!\n\nAt first I tried my best to make heads or tails of t3427, for way too long.\nIn the end the only way to understand what the heck it tries to do was to\nactually fix it. That's why this patch series looks as if it focuses on\nt3427 rather than on adding support for custom merge strategies to the \n--rebase-merges mode.\n\nAs a consolation to myself, this work was actually worth it, surprising as\nthat may look. Not only is t3427 now really easy to understand, adding that\ntest case for --rebase-merges -Xsubtree tickled the sequencer enough to\nreveal a long-standing bug: the --onto option was simply ignored when passed\ntogether with --rebase-merges and --root. For good measure, this patch\nseries addresses this bug, too.\n\nChanges since v1:\n\n * Rebased to the current js/rebase-cleanup: that branch itself was rebased,\n   and as a consequence, one already-applied patch was dropped from this\n   patch series.\n * Forward-fixed the fakesha handling, just in case that anybody wants to\n   use it with a regular pick command in the future (thanks, brian).\n\nJohannes Schindelin (16):\n  Drop unused git-rebase--am.sh\n  t3400: stop referring to the scripted rebase\n  .gitignore: there is no longer a built-in `git-rebase--interactive`\n  sequencer: the `am` and `rebase--interactive` scripts are gone\n  rebase: fold git-rebase--common into the -p backend\n  t3427: add a clarifying comment\n  t3427: simplify the `setup` test case significantly\n  t3427: move the `filter-branch` invocation into the `setup` case\n  t3427: condense the unnecessarily repetitive test cases into three\n  t3427: fix erroneous assumption\n  t3427: accommodate for the `rebase --merge` backend having been\n    replaced\n  t3427: fix another incorrect assumption\n  rebase -r: support merge strategies other than `recursive`\n  t/lib-rebase: prepare for testing `git rebase --rebase-merges`\n  t3418: test `rebase -r` with merge strategies\n  rebase -r: do not (re-)generate root commits with `--root` *and*\n    `--onto`\n\n .gitignore                             |   3 -\n Documentation/git-rebase.txt           |   2 -\n Makefile                               |   2 -\n builtin/rebase.c                       |  23 +---\n git-rebase--am.sh                      |  85 --------------\n git-rebase--common.sh                  |  69 -----------\n git-rebase--preserve-merges.sh         |  55 +++++++++\n sequencer.c                            |  20 +++-\n sequencer.h                            |   6 +\n t/lib-rebase.sh                        |   9 +-\n t/t3400-rebase.sh                      |   2 +-\n t/t3418-rebase-continue.sh             |  14 +++\n t/t3422-rebase-incompatible-options.sh |  10 --\n t/t3427-rebase-subtree.sh              | 155 +++++++++++--------------\n t/t3430-rebase-merges.sh               |  21 ++++\n 15 files changed, 193 insertions(+), 283 deletions(-)\n delete mode 100644 git-rebase--am.sh\n delete mode 100644 git-rebase--common.sh\n\n\nbase-commit: 80dfc9242ebaba357ffedececd88641a1a752411\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-294%2Fdscho%2Frebase-r-with-strategies-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-294/dscho/rebase-r-with-strategies-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/294\n\nRange-diff vs v1:\n\n  -:  ---------- >  1:  e0645b3ad7 Drop unused git-rebase--am.sh\n  -:  ---------- >  2:  6e8be7d873 t3400: stop referring to the scripted rebase\n  -:  ---------- >  3:  9e00e66dc7 .gitignore: there is no longer a built-in `git-rebase--interactive`\n  -:  ---------- >  4:  db9ec248e1 sequencer: the `am` and `rebase--interactive` scripts are gone\n  -:  ---------- >  5:  38c8e3e284 rebase: fold git-rebase--common into the -p backend\n  1:  05be92d921 =  6:  b3daf078e8 t3427: add a clarifying comment\n  2:  df096e054d =  7:  c168c4499b t3427: simplify the `setup` test case significantly\n  3:  a3944c5480 !  8:  138ff362fb t3427: move the `filter-branch` invocation into the `setup` case\n     @@ -29,7 +29,8 @@\n       '\n       \n       # FAILURE: Does not preserve master4.\n     - test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n     + test_expect_failure REBASE_P \\\n     + \t'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-preserve-merges-4 master &&\n      -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n     @@ -39,8 +40,8 @@\n       \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master4\"\n       '\n      @@\n     - # FAILURE: Does not preserve master5.\n     - test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n     + test_expect_failure REBASE_P \\\n     + \t'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-preserve-merges-5 master &&\n      -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n     @@ -50,8 +51,8 @@\n       \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n       '\n      @@\n     - # FAILURE: Does not preserve master4.\n     - test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n     + test_expect_failure REBASE_P \\\n     + \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty-4 master &&\n      -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n     @@ -61,8 +62,8 @@\n       \tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n       '\n      @@\n     - # FAILURE: Does not preserve master5.\n     - test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n     + test_expect_failure REBASE_P \\\n     + \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty-5 master &&\n      -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n     @@ -72,8 +73,8 @@\n       \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n       '\n      @@\n     - # FAILURE: Does not preserve Empty.\n     - test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n     + test_expect_failure REBASE_P \\\n     + \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty-empty master &&\n      -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n  4:  9aeb57fa8f !  9:  46ef005365 t3427: condense the unnecessarily repetitive test cases into three\n     @@ -25,8 +25,9 @@\n       '\n       \n       # FAILURE: Does not preserve master4.\n     --test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n     -+test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit' '\n     +-test_expect_failure REBASE_P \\\n     +-\t'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n     ++test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n       \treset_rebase &&\n      -\tgit checkout -b rebase-preserve-merges-4 to-rebase &&\n      -\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n     @@ -34,7 +35,8 @@\n      -'\n      -\n      -# FAILURE: Does not preserve master5.\n     --test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n     +-test_expect_failure REBASE_P \\\n     +-\t'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n      -\treset_rebase &&\n      -\tgit checkout -b rebase-preserve-merges-5 to-rebase &&\n      +\tgit checkout -b rebase-preserve-merges to-rebase &&\n     @@ -44,8 +46,9 @@\n       '\n       \n       # FAILURE: Does not preserve master4.\n     --test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n     -+test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '\n     +-test_expect_failure REBASE_P \\\n     +-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 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-4 to-rebase &&\n      -\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n     @@ -53,7 +56,8 @@\n      -'\n      -\n      -# FAILURE: Does not preserve master5.\n     --test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n     +-test_expect_failure REBASE_P \\\n     +-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n      -\treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty-5 to-rebase &&\n      -\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n     @@ -61,7 +65,8 @@\n      -'\n      -\n      -# FAILURE: Does not preserve Empty.\n     --test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n     +-test_expect_failure REBASE_P \\\n     +-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n      -\treset_rebase &&\n      -\tgit checkout -b rebase-keep-empty-empty to-rebase &&\n      +\tgit checkout -b rebase-keep-empty to-rebase &&\n  5:  3196413c2a = 10:  8afec74cfc t3427: fix erroneous assumption\n  6:  261825fe44 = 11:  d73b0a05d9 t3427: accommodate for the `rebase --merge` backend having been replaced\n  7:  f7452d3740 = 12:  57c63309bf t3427: fix another incorrect assumption\n  8:  7f60b8e745 <  -:  ---------- t3427: mark two test cases as requiring support for `git rebase -p`\n  9:  30405df99f = 13:  75b1395dae rebase -r: support merge strategies other than `recursive`\n 10:  ae9e72b73b ! 14:  8f74bfbc53 t/lib-rebase: prepare for testing `git rebase --rebase-merges`\n     @@ -6,6 +6,26 @@\n          `--rebase-merges` mode; Let's prepare the fake editor to handle those\n          todo lists properly, too.\n      \n     +    The original idea was that we keep the original command unless\n     +    overridden, and because the original todo lists only had `pick` lines\n     +    anyway, we could be sloppy and \"override\" the command by the same\n     +    command (i.e. use the sed replacement pattern \"pick\" instead of \"&\").\n     +\n     +    This actually would not have worked with `fixup` and `squash` commands,\n     +    but it would appear that we never tried to use the fake editor with\n     +    `--autosquash`.\n     +\n     +    However, in the next commit we want to use the fake editor in\n     +    conjunction with `--rebase-merges`, so let's use the correct sed\n     +    replacement pattern.\n     +\n     +    Technically, it is not necessary to take care of the `fakesha` thing\n     +    (where we reuse the sed replacement pattern to craft a new todo\n     +    command), at least for now, as the only user of that thing overrides the\n     +    `action` anyway. Nevertheless, for completeness' sake, we do take care\n     +    of it.\n     +\n     +    Helped-by: brian m. carlson <sandals@crustytoothpaste.net>\n          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n      \n       diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\n     @@ -25,6 +45,10 @@\n       \t\texec_*|x_*|break|b)\n       \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n      @@\n     + \t\tbad)\n     + \t\t\taction=\"badcmd\";;\n     + \t\tfakesha)\n     ++\t\t\ttest \\& != \"$action\" || action=pick\n       \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n       \t\t\taction=pick;;\n       \t\t*)\n 11:  a326be77aa = 15:  0c938d02b3 t3418: test `rebase -r` with merge strategies\n 12:  e6713568dc = 16:  be62d267cb rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`\n\n-- \ngitgitgadget\n"},{"id":"379673","messageId":"38c8e3e284f1ac3574e157786fc0b1d76491fa17.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 05/16] rebase: fold git-rebase--common into the -p backend","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:41Z","receivedAt":"2019-07-31T15:18:48Z","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 only remaining scripted part of `git rebase` is the\n`--preserve-merges` backend. Meaning: there is little reason to keep the\n\"library of common rebase functions\" as a separate file.\n\nWhile moving the functions to `git-rebase--preserve-merges.sh`, we also\ndrop the `move_to_original_branch` function that is no longer used.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n .gitignore                     |  1 -\n Makefile                       |  1 -\n builtin/rebase.c               |  3 +-\n git-rebase--common.sh          | 69 ----------------------------------\n git-rebase--preserve-merges.sh | 55 +++++++++++++++++++++++++++\n 5 files changed, 56 insertions(+), 73 deletions(-)\n delete mode 100644 git-rebase--common.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex bcee4fda81..4470d7cfc0 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -122,7 +122,6 @@\n /git-range-diff\n /git-read-tree\n /git-rebase\n-/git-rebase--common\n /git-rebase--preserve-merges\n /git-receive-pack\n /git-reflog\ndiff --git a/Makefile b/Makefile\nindex 63e1973333..6c3bfb1733 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -624,7 +624,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--common\n SCRIPT_LIB += git-rebase--preserve-merges\n SCRIPT_LIB += git-sh-setup\n SCRIPT_LIB += git-sh-i18n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 4dd76ee576..74a60e8c83 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1163,8 +1163,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t}\n \n \tstrbuf_addf(&script_snippet,\n-\t\t    \". git-sh-setup && . git-rebase--common &&\"\n-\t\t    \" . %s && %s\", backend, backend_func);\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);\ndiff --git a/git-rebase--common.sh b/git-rebase--common.sh\ndeleted file mode 100644\nindex f00e13e5d0..0000000000\n--- a/git-rebase--common.sh\n+++ /dev/null\n@@ -1,69 +0,0 @@\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-move_to_original_branch () {\n-\tcase \"$head_name\" in\n-\trefs/*)\n-\t\tmessage=\"rebase finished: $head_name onto $onto\"\n-\t\tgit update-ref -m \"$message\" \\\n-\t\t\t$head_name $(git rev-parse HEAD) $orig_head &&\n-\t\tgit symbolic-ref \\\n-\t\t\t-m \"rebase finished: returning to $head_name\" \\\n-\t\t\tHEAD $head_name ||\n-\t\tdie \"$(eval_gettext \"Could not move back to \\$head_name\")\"\n-\t\t;;\n-\tesac\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-}\ndiff --git a/git-rebase--preserve-merges.sh b/git-rebase--preserve-merges.sh\nindex afbb65765d..dec90e9af6 100644\n--- a/git-rebase--preserve-merges.sh\n+++ b/git-rebase--preserve-merges.sh\n@@ -77,6 +77,61 @@ rewritten_pending=\"$state_dir\"/rewritten-pending\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-- \ngitgitgadget\n\n"},{"id":"379675","messageId":"138ff362fbf3d948e431489841602d787e360c69.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 08/16] t3427: move the `filter-branch` invocation into the `setup` case","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:43Z","receivedAt":"2019-07-31T15:18:49Z","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 step to prepare a pre-rebase commit history is _identical_ in _all_\nof the test cases (except of course the `setup` case). It should\ntherefore clearly a part of the `setup` test case instead.\n\nAs the `git filter-branch` command is quite costly on platforms where\nUnix shell scripting is simply slow (meaning: on Windows), this shaves\noff a noticeable part of the runtime: in this developer's setup, the\ntime was reduced from ~1m25s to ~1m.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 38 +++++++++++++-------------------------\n 1 file changed, 13 insertions(+), 25 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 36c4f92e06..64ba95f3e0 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -56,16 +56,18 @@ test_expect_success 'setup' '\n \n \t: add two extra commits to rebase &&\n \ttest_commit -C files_subtree master4 &&\n-\ttest_commit files_subtree/master5\n+\ttest_commit files_subtree/master5 &&\n+\n+\tgit checkout -b to-rebase &&\n+\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n+\tgit commit -m \"Empty commit\" --allow-empty\n '\n \n # FAILURE: Does not preserve master4.\n test_expect_failure REBASE_P \\\n \t'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-preserve-merges-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master4\"\n '\n@@ -74,9 +76,7 @@ test_expect_failure REBASE_P \\\n test_expect_failure REBASE_P \\\n \t'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-preserve-merges-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n@@ -85,9 +85,7 @@ test_expect_failure REBASE_P \\\n test_expect_failure REBASE_P \\\n \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n '\n@@ -96,9 +94,7 @@ test_expect_failure REBASE_P \\\n test_expect_failure REBASE_P \\\n \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n '\n@@ -107,9 +103,7 @@ test_expect_failure REBASE_P \\\n test_expect_failure REBASE_P \\\n \t'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-empty master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-keep-empty-empty to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n@@ -117,9 +111,7 @@ test_expect_failure REBASE_P \\\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-4 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-4 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n '\n@@ -127,18 +119,14 @@ test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto commit 5' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-5 master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-5 to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n '\n # FAILURE: fatal: Could not parse object\n test_expect_failure 'Rebase -Xsubtree --onto empty commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-empty master &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n-\tgit commit -m \"Empty commit\" --allow-empty &&\n+\tgit checkout -b rebase-onto-empty to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n-- \ngitgitgadget\n\n"},{"id":"379676","messageId":"e0645b3ad7e70519437e3b7a9ae6dc29488d13f2.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 01/16] Drop unused git-rebase--am.sh","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:38Z","receivedAt":"2019-07-31T15:18:49Z","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\nSince 21853626ea (built-in rebase: call `git am` directly, 2019-01-18),\nthe built-in rebase already uses the built-in `git am` directly.\n\nNow that d03ebd411c (rebase: remove the rebase.useBuiltin setting,\n2019-03-18) even removed the scripted rebase, there is no longer any\nuser of `git-rebase--am.sh`, so let's just remove it.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n .gitignore        |  1 -\n Makefile          |  1 -\n builtin/rebase.c  |  4 ---\n git-rebase--am.sh | 85 -----------------------------------------------\n 4 files changed, 91 deletions(-)\n delete mode 100644 git-rebase--am.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 2374f77a1a..875f3fc6e8 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -122,7 +122,6 @@\n /git-range-diff\n /git-read-tree\n /git-rebase\n-/git-rebase--am\n /git-rebase--common\n /git-rebase--interactive\n /git-rebase--preserve-merges\ndiff --git a/Makefile b/Makefile\nindex 8a7e235352..63e1973333 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -624,7 +624,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--am\n SCRIPT_LIB += git-rebase--common\n SCRIPT_LIB += git-rebase--preserve-merges\n SCRIPT_LIB += git-sh-setup\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 21681a551b..4dd76ee576 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1153,10 +1153,6 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)\n \t}\n \n \tswitch (opts->type) {\n-\tcase REBASE_AM:\n-\t\tbackend = \"git-rebase--am\";\n-\t\tbackend_func = \"git_rebase__am\";\n-\t\tbreak;\n \tcase REBASE_PRESERVE_MERGES:\n \t\tbackend = \"git-rebase--preserve-merges\";\n \t\tbackend_func = \"git_rebase__preserve_merges\";\ndiff --git a/git-rebase--am.sh b/git-rebase--am.sh\ndeleted file mode 100644\nindex 6416716ee6..0000000000\n--- a/git-rebase--am.sh\n+++ /dev/null\n@@ -1,85 +0,0 @@\n-# This shell script fragment is sourced by git-rebase to implement\n-# its default, fast, patch-based, non-interactive mode.\n-#\n-# Copyright (c) 2010 Junio C Hamano.\n-#\n-\n-git_rebase__am () {\n-\n-case \"$action\" in\n-continue)\n-\tgit am --resolved --resolvemsg=\"$resolvemsg\" \\\n-\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} &&\n-\tmove_to_original_branch\n-\treturn\n-\t;;\n-skip)\n-\tgit am --skip --resolvemsg=\"$resolvemsg\" &&\n-\tmove_to_original_branch\n-\treturn\n-\t;;\n-show-current-patch)\n-\texec git am --show-current-patch\n-\t;;\n-esac\n-\n-if test -z \"$rebase_root\"\n-\t# this is now equivalent to ! -z \"$upstream\"\n-then\n-\trevisions=$upstream...$orig_head\n-else\n-\trevisions=$onto...$orig_head\n-fi\n-\n-ret=0\n-rm -f \"$GIT_DIR/rebased-patches\"\n-\n-git format-patch -k --stdout --full-index --cherry-pick --right-only \\\n-\t--src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \\\n-\t--pretty=mboxrd --topo-order \\\n-\t$git_format_patch_opt \\\n-\t\"$revisions\" ${restrict_revision+^$restrict_revision} \\\n-\t>\"$GIT_DIR/rebased-patches\"\n-ret=$?\n-\n-if test 0 != $ret\n-then\n-\trm -f \"$GIT_DIR/rebased-patches\"\n-\tcase \"$head_name\" in\n-\trefs/heads/*)\n-\t\tgit checkout -q \"$head_name\"\n-\t\t;;\n-\t*)\n-\t\tgit checkout -q \"$orig_head\"\n-\t\t;;\n-\tesac\n-\n-\tcat >&2 <<-EOF\n-\n-\tgit encountered an error while preparing the patches to replay\n-\tthese revisions:\n-\n-\t    $revisions\n-\n-\tAs a result, git cannot rebase them.\n-\tEOF\n-\treturn $ret\n-fi\n-\n-git am $git_am_opt --rebasing --resolvemsg=\"$resolvemsg\" \\\n-\t--patch-format=mboxrd \\\n-\t$allow_rerere_autoupdate \\\n-\t${gpg_sign_opt:+\"$gpg_sign_opt\"} <\"$GIT_DIR/rebased-patches\"\n-ret=$?\n-\n-rm -f \"$GIT_DIR/rebased-patches\"\n-\n-if test 0 != $ret\n-then\n-\ttest -d \"$state_dir\" && write_basic_state\n-\treturn $ret\n-fi\n-\n-move_to_original_branch\n-\n-}\n-- \ngitgitgadget\n\n"},{"id":"379677","messageId":"be62d267cb688ee1ac3c308e7a2593f32bf8f49f.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 16/16] rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:49Z","receivedAt":"2019-07-31T15:18: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\nWhen rebasing a complete commit history onto a given commit, it is\npretty obvious that the root commits should be rebased on top of said\ngiven commit.\n\nTo test this, let's kill two birds with one stone and add a test case to\nt3427-rebase-subtree.sh that not only demonstrates that this works, but\nalso that `git rebase -r` works with merge strategies now.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/rebase.c          |  7 +++++--\n sequencer.c               |  4 +++-\n sequencer.h               |  6 ++++++\n t/t3427-rebase-subtree.sh | 11 +++++++++++\n 4 files changed, 25 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 625f50c637..ee2bc8b032 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -62,7 +62,7 @@ struct rebase_options {\n \tconst char *onto_name;\n \tconst char *revisions;\n \tconst char *switch_to;\n-\tint root;\n+\tint root, root_with_onto;\n \tstruct object_id *squash_onto;\n \tstruct commit *restrict_revision;\n \tint dont_finish_rebase;\n@@ -374,6 +374,7 @@ static int run_rebase_interactive(struct rebase_options *opts,\n \tflags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;\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 \n \tswitch (command) {\n@@ -1841,7 +1842,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\toptions.squash_onto = &squash_onto;\n \t\t\toptions.onto_name = squash_onto_name =\n \t\t\t\txstrdup(oid_to_hex(&squash_onto));\n-\t\t}\n+\t\t} else\n+\t\t\toptions.root_with_onto = 1;\n+\n \t\toptions.upstream_name = NULL;\n \t\toptions.upstream = NULL;\n \t\tif (argc > 1)\ndiff --git a/sequencer.c b/sequencer.c\nindex d228448cd8..ca119c84e5 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -4440,6 +4440,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,\n {\n \tint keep_empty = flags & TODO_LIST_KEEP_EMPTY;\n \tint rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;\n+\tint root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;\n \tstruct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;\n \tstruct strbuf label = STRBUF_INIT;\n \tstruct commit_list *commits = NULL, **tail = &commits, *iter;\n@@ -4606,7 +4607,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,\n \n \t\tif (!commit)\n \t\t\tstrbuf_addf(out, \"%s %s\\n\", cmd_reset,\n-\t\t\t\t    rebase_cousins ? \"onto\" : \"[new root]\");\n+\t\t\t\t    rebase_cousins || root_with_onto ?\n+\t\t\t\t    \"onto\" : \"[new root]\");\n \t\telse {\n \t\t\tconst char *to = NULL;\n \ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d4..d506081d3c 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -142,6 +142,12 @@ int sequencer_remove_state(struct replay_opts *opts);\n  */\n #define TODO_LIST_REBASE_COUSINS (1U << 4)\n #define TODO_LIST_APPEND_TODO_HELP (1U << 5)\n+/*\n+ * When generating a script that rebases merges with `--root` *and* with\n+ * `--onto`, we do not want to re-generate the root commits.\n+ */\n+#define TODO_LIST_ROOT_WITH_ONTO (1U << 6)\n+\n \n int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,\n \t\t\t  const char **argv, unsigned flags);\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 7a37235768..39e348de16 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -93,4 +93,15 @@ test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n+test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '\n+\treset_rebase &&\n+\tgit checkout -b rebase-merges-onto to-rebase &&\n+\ttest_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&\n+\t: first pick results in no changes &&\n+\tgit rebase --continue &&\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_done\n-- \ngitgitgadget\n"},{"id":"379678","messageId":"8f74bfbc534cc7a707462622ddf387c67c6de222.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 14/16] t/lib-rebase: prepare for testing `git rebase --rebase-merges`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:48Z","receivedAt":"2019-07-31T15:18:57Z","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 format of the todo list is quite a bit different in the\n`--rebase-merges` mode; Let's prepare the fake editor to handle those\ntodo lists properly, too.\n\nThe original idea was that we keep the original command unless\noverridden, and because the original todo lists only had `pick` lines\nanyway, we could be sloppy and \"override\" the command by the same\ncommand (i.e. use the sed replacement pattern \"pick\" instead of \"&\").\n\nThis actually would not have worked with `fixup` and `squash` commands,\nbut it would appear that we never tried to use the fake editor with\n`--autosquash`.\n\nHowever, in the next commit we want to use the fake editor in\nconjunction with `--rebase-merges`, so let's use the correct sed\nreplacement pattern.\n\nTechnically, it is not necessary to take care of the `fakesha` thing\n(where we reuse the sed replacement pattern to craft a new todo\ncommand), at least for now, as the only user of that thing overrides the\n`action` anyway. Nevertheless, for completeness' sake, we do take care\nof it.\n\nHelped-by: brian m. carlson <sandals@crustytoothpaste.net>\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/lib-rebase.sh | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\nindex 7ea30e5006..6d87961e41 100644\n--- a/t/lib-rebase.sh\n+++ b/t/lib-rebase.sh\n@@ -44,10 +44,10 @@ set_fake_editor () {\n \trm -f \"$1\"\n \techo 'rebase -i script before editing:'\n \tcat \"$1\".tmp\n-\taction=pick\n+\taction=\\&\n \tfor line in $FAKE_LINES; do\n \t\tcase $line in\n-\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d)\n+\t\tpick|p|squash|s|fixup|f|edit|e|reword|r|drop|d|label|l|reset|r|merge|m)\n \t\t\taction=\"$line\";;\n \t\texec_*|x_*|break|b)\n \t\t\techo \"$line\" | sed 's/_/ /g' >> \"$1\";;\n@@ -58,11 +58,12 @@ set_fake_editor () {\n \t\tbad)\n \t\t\taction=\"badcmd\";;\n \t\tfakesha)\n+\t\t\ttest \\& != \"$action\" || action=pick\n \t\t\techo \"$action XXXXXXX False commit\" >> \"$1\"\n \t\t\taction=pick;;\n \t\t*)\n-\t\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n-\t\t\taction=pick;;\n+\t\t\tsed -n \"${line}s/^[a-z][a-z]*/$action/p\" < \"$1\".tmp >> \"$1\"\n+\t\t\taction=\\&;;\n \t\tesac\n \tdone\n \techo 'rebase -i script after editing:'\n-- \ngitgitgadget\n\n"},{"id":"379679","messageId":"0c938d02b303b995f75cd7dbaa77eac01a06dc4d.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 15/16] t3418: test `rebase -r` with merge strategies","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:49Z","receivedAt":"2019-07-31T15:18:57Z","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\nThere is a test case in this script that verifies that `git rebase\n--preserve-merges` works all right with non-default merge strategies or\nnon-default merge strategy options.\n\nNow that `git rebase --rebase-merges` learned about merge strategies,\nlet's copy-edit this test case to verify that that works as intended,\ntoo.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3418-rebase-continue.sh | 14 ++++++++++++++\n 1 file changed, 14 insertions(+)\n\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex bdaa511bb0..fbf9addfd1 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -120,6 +120,20 @@ test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '\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+\ttest_commit merge-theirs &&\n+\tgit reset --hard HEAD^ &&\n+\ttest_commit some-other-commit &&\n+\ttest_tick &&\n+\tgit merge --no-ff merge-theirs &&\n+\tFAKE_LINES=\"1 3 edit 4 5 7 8 9\" git rebase -i -f -r -m \\\n+\t\t-s recursive --strategy-option=theirs HEAD~2 &&\n+\ttest_commit force-change-ours &&\n+\tgit rebase --continue\n+'\n+\n test_expect_success '--skip after failed fixup cleans commit message' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n \tgit checkout -b with-conflicting-fixup &&\n-- \ngitgitgadget\n\n"},{"id":"379680","messageId":"75b1395dae5f2fac28d3b200b12833821b7b1862.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 13/16] rebase -r: support merge strategies other than `recursive`","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:47Z","receivedAt":"2019-07-31T15:19:02Z","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 support merge strategies in the sequencer, but only for\n`pick` commands.\n\nWith this commit, we now also support them in `merge` commands. The\napproach is simple: if any merge strategy option is specified, or if any\nmerge strategy other than `recursive` is specified, we simply spawn the\n`git merge` command. Otherwise, we handle the merge in-process just as\nbefore.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/git-rebase.txt           |  2 --\n builtin/rebase.c                       |  9 ---------\n sequencer.c                            | 14 ++++++++++++--\n t/t3422-rebase-incompatible-options.sh | 10 ----------\n t/t3430-rebase-merges.sh               | 21 +++++++++++++++++++++\n 5 files changed, 33 insertions(+), 23 deletions(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 5e4e927647..bc620c44e9 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -543,8 +543,6 @@ In addition, the following pairs of options are incompatible:\n  * --preserve-merges and --interactive\n  * --preserve-merges and --signoff\n  * --preserve-merges and --rebase-merges\n- * --rebase-merges and --strategy\n- * --rebase-merges and --strategy-option\n \n BEHAVIORAL DIFFERENCES\n -----------------------\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 74a60e8c83..625f50c637 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1811,15 +1811,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \t\t\t      \"'--reschedule-failed-exec'\"));\n \t}\n \n-\tif (options.rebase_merges) {\n-\t\tif (strategy_options.nr)\n-\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n-\t\t\t      \"'--strategy-option'\"));\n-\t\tif (options.strategy)\n-\t\t\tdie(_(\"cannot combine '--rebase-merges' with \"\n-\t\t\t      \"'--strategy'\"));\n-\t}\n-\n \tif (!options.root) {\n \t\tif (argc < 1) {\n \t\t\tstruct branch *branch;\ndiff --git a/sequencer.c b/sequencer.c\nindex 334de14542..d228448cd8 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3256,6 +3256,9 @@ static int do_merge(struct repository *r,\n \tstruct commit *head_commit, *merge_commit, *i;\n \tstruct commit_list *bases, *j, *reversed = NULL;\n \tstruct commit_list *to_merge = NULL, **tail = &to_merge;\n+\tconst char *strategy = !opts->xopts_nr &&\n+\t\t(!opts->strategy || !strcmp(opts->strategy, \"recursive\")) ?\n+\t\tNULL : opts->strategy;\n \tstruct merge_options o;\n \tint merge_arg_len, oneline_offset, can_fast_forward, ret, k;\n \tstatic struct lock_file lock;\n@@ -3404,7 +3407,7 @@ static int do_merge(struct repository *r,\n \t\tgoto leave_merge;\n \t}\n \n-\tif (to_merge->next) {\n+\tif (strategy || to_merge->next) {\n \t\t/* Octopus merge */\n \t\tstruct child_process cmd = CHILD_PROCESS_INIT;\n \n@@ -3418,7 +3421,14 @@ static int do_merge(struct repository *r,\n \t\tcmd.git_cmd = 1;\n \t\targv_array_push(&cmd.args, \"merge\");\n \t\targv_array_push(&cmd.args, \"-s\");\n-\t\targv_array_push(&cmd.args, \"octopus\");\n+\t\tif (!strategy)\n+\t\t\targv_array_push(&cmd.args, \"octopus\");\n+\t\telse {\n+\t\t\targv_array_push(&cmd.args, strategy);\n+\t\t\tfor (k = 0; k < opts->xopts_nr; k++)\n+\t\t\t\targv_array_pushf(&cmd.args,\n+\t\t\t\t\t\t \"-X%s\", opts->xopts[k]);\n+\t\t}\n \t\targv_array_push(&cmd.args, \"--no-edit\");\n \t\targv_array_push(&cmd.args, \"--no-ff\");\n \t\targv_array_push(&cmd.args, \"--no-log\");\ndiff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh\nindex a5868ea152..50e7960702 100755\n--- a/t/t3422-rebase-incompatible-options.sh\n+++ b/t/t3422-rebase-incompatible-options.sh\n@@ -76,14 +76,4 @@ test_expect_success REBASE_P \\\n \ttest_must_fail git rebase --preserve-merges --rebase-merges A\n '\n \n-test_expect_success '--rebase-merges incompatible with --strategy' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --rebase-merges -s resolve A\n-'\n-\n-test_expect_success '--rebase-merges incompatible with --strategy-option' '\n-\tgit checkout B^0 &&\n-\ttest_must_fail git rebase --rebase-merges -Xignore-space-change A\n-'\n-\n test_done\ndiff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh\nindex 42ba5b9f09..8ea6ff3548 100755\n--- a/t/t3430-rebase-merges.sh\n+++ b/t/t3430-rebase-merges.sh\n@@ -412,4 +412,25 @@ test_expect_success '--continue after resolving conflicts after a merge' '\n \ttest_path_is_missing .git/MERGE_HEAD\n '\n \n+test_expect_success '--rebase-merges with strategies' '\n+\tgit checkout -b with-a-strategy F &&\n+\ttest_tick &&\n+\tgit merge -m \"Merge conflicting-G\" conflicting-G &&\n+\n+\t: first, test with a merge strategy option &&\n+\tgit rebase -ir -Xtheirs G &&\n+\techo conflicting-G >expect &&\n+\ttest_cmp expect G.t &&\n+\n+\t: now, try with a merge strategy other than recursive &&\n+\tgit reset --hard @{1} &&\n+\twrite_script git-merge-override <<-\\EOF &&\n+\techo overridden$1 >>G.t\n+\tgit add G.t\n+\tEOF\n+\tPATH=\"$PWD:$PATH\" git rebase -ir -s override -Xxopt G &&\n+\ttest_write_lines G overridden--xopt >expect &&\n+\ttest_cmp expect G.t\n+'\n+\n test_done\n-- \ngitgitgadget\n\n"},{"id":"379681","messageId":"46ef0053650d9bcc7c3218cfbf0cb729307c03f8.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 09/16] t3427: condense the unnecessarily repetitive test cases into three","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:44Z","receivedAt":"2019-07-31T15:19:08Z","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\nPreviously, this test script performed essentially three rebases and\nverified breakages by testing the post-rebase commits' messages.\n\nTo do so, the rebases were performed multiple times, though, once per\ncommit message to test. This wastes electricity (and CO2) and time.\n\nLet's condense the test cases to the essential number: the number of\ndifferent rebases to validate.\n\nOn Windows, where the scripted nature of the `--preserve-merges` backend\nhurts performance rather badly, this reduces the overall runtime in this\ndeveloper's setup from ~1m to ~28s while still performing the exact same\ntesting as before.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 61 +++++++--------------------------------\n 1 file changed, 11 insertions(+), 50 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 64ba95f3e0..b21925d279 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -64,70 +64,31 @@ test_expect_success 'setup' '\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure REBASE_P \\\n-\t'Rebase -Xsubtree --preserve-merges --onto commit 4' '\n+test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: Does not preserve master5.\n-test_expect_failure REBASE_P \\\n-\t'Rebase -Xsubtree --preserve-merges --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-preserve-merges-5 to-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~)\" = \"files_subtree/master4\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n \n # FAILURE: Does not preserve master4.\n-test_expect_failure REBASE_P \\\n-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 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-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: Does not preserve master5.\n-test_expect_failure REBASE_P \\\n-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-5 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n-'\n-\n-# FAILURE: Does not preserve Empty.\n-test_expect_failure REBASE_P \\\n-\t'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-keep-empty-empty to-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)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n # FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit 4' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-onto-4 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\"\n-'\n-\n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit 5' '\n-\treset_rebase &&\n-\tgit checkout -b rebase-onto-5 to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\"\n-'\n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto empty commit' '\n+test_expect_failure 'Rebase -Xsubtree --onto commit' '\n \treset_rebase &&\n-\tgit checkout -b rebase-onto-empty to-rebase &&\n+\tgit checkout -b rebase-onto to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n+\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"files_subtree/master5\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n-- \ngitgitgadget\n\n"},{"id":"379682","messageId":"57c63309bfaf1198fbf70c9dd992f36d9323dfcf.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 12/16] t3427: fix another incorrect assumption","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:46Z","receivedAt":"2019-07-31T15:19:18Z","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 test case that concerns `git rebase -Xsubtree` (with the\ndefault rebase backend, not with `--preserve-merges`) starts out with a\npre-rebase commit history that begins with a commit that introduces\nthree files: master1.t, master2.t and master3.t.\n\nThis commit was generated by passing a subtree merge commit through `git\nfilter-branch --subdirectory-filter`, so it looks as if this commit\nreally introduces all those files.\n\nThe commit history onto which this commit is then rebased, however,\nintroduced those files in individual commits. For that reason, the\nrebase will fail, it _must_ fail, because the first `pick` results in no\nchanges to be committed.\n\nLet's fix the test case to expect exactly this situation.\n\nWith this change, we can mark the original bug that this test case tried\nto demonstrate as fixed.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex a734716ea3..7a37235768 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -82,11 +82,12 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --\n \tverbose test \"$(commit_message HEAD)\" = \"Empty commit\"\n '\n \n-# FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --keep-empty --onto commit' '\n+test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&\n+\ttest_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&\n+\t: first pick results in no changes &&\n+\tgit rebase --continue &&\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-- \ngitgitgadget\n\n"},{"id":"379683","messageId":"8afec74cfc9907fff7379cc2d7b664deac6f93aa.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 10/16] t3427: fix erroneous assumption","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:45Z","receivedAt":"2019-07-31T15:19:21Z","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\nApart from the `setup` test case, `t3427-rebase-subtree.sh` is made up\nexclusively of demonstrations of breakages. The tricky thing about such\ndemonstrations is that they are often buggy themselves.\n\nIn this instance, somewhere over the course of the six iterations\nof the patch that eventually made it into Git's `master` as 5f35900849e\n(contrib/subtree: Add a test for subtree rebase that loses commits,\n2016-06-28), the commit message \"files_subtree/master4\" was changed to\njust \"master4\", but the test cases still expected the old commit\nmessage.\n\nLet's fix this, at long last.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex b21925d279..94cc532e10 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -68,7 +68,7 @@ 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~)\" = \"files_subtree/master4\" &&\n+\tverbose test \"$(commit_message HEAD~)\" = \"master4\" &&\n \tverbose test \"$(commit_message HEAD)\" = \"files_subtree/master5\"\n '\n \n@@ -77,7 +77,7 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --\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)\" = \"files_subtree/master4\" &&\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@@ -87,7 +87,7 @@ test_expect_failure 'Rebase -Xsubtree --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n \tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n-\tverbose test \"$(commit_message HEAD~2)\" = \"files_subtree/master4\" &&\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-- \ngitgitgadget\n\n"},{"id":"379684","messageId":"d73b0a05d90237253d0793580fe285df3aba689a.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 11/16] t3427: accommodate for the `rebase --merge` backend having been replaced","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:45Z","receivedAt":"2019-07-31T15:19:23Z","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\nSince 68aa495b590 (rebase: implement --merge via the interactive\nmachinery, 2018-12-11), the job of the old `--merge` backend is now\nperformed by the `--interactive` backend, too.\n\nOne consequence is that empty commits are no longer rebased by default.\n\nMeaning that the test case that calls `git rebase -Xsubtree` (which used\nto be handled by the `--merge` backend) now needs to ask explicitly for\nthe empty commit to be rebased.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 94cc532e10..a734716ea3 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -83,10 +83,10 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --\n '\n \n # FAILURE: fatal: Could not parse object\n-test_expect_failure 'Rebase -Xsubtree --onto commit' '\n+test_expect_failure 'Rebase -Xsubtree --keep-empty --onto commit' '\n \treset_rebase &&\n \tgit checkout -b rebase-onto to-rebase &&\n-\tgit rebase -Xsubtree=files_subtree --onto files-master master &&\n+\tgit rebase -Xsubtree=files_subtree --keep-empty --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-- \ngitgitgadget\n\n"},{"id":"379685","messageId":"c168c4499b674db3aefa4d0303c349a2464a3de1.1564586316.git.gitgitgadget@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 07/16] t3427: simplify the `setup` test case significantly","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-07-31T15:18:42Z","receivedAt":"2019-07-31T15:19:33Z","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 still does the very same thing as before, but expresses it in a much\nmore succinct (and still quite readable) manner.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t3427-rebase-subtree.sh | 36 +++++++++++++++---------------------\n 1 file changed, 15 insertions(+), 21 deletions(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 3a2ae7b55d..36c4f92e06 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -41,27 +41,21 @@ commit_message() {\n \n test_expect_success 'setup' '\n \ttest_commit README &&\n-\tmkdir files &&\n-\t(\n-\t\tcd files &&\n-\t\tgit init &&\n-\t\ttest_commit master1 &&\n-\t\ttest_commit master2 &&\n-\t\ttest_commit master3\n-\t) &&\n-\tgit fetch files master &&\n-\tgit branch files-master FETCH_HEAD &&\n-\tgit read-tree --prefix=files_subtree files-master &&\n-\tgit checkout -- files_subtree &&\n-\ttree=$(git write-tree) &&\n-\thead=$(git rev-parse HEAD) &&\n-\trev=$(git rev-parse --verify files-master^0) &&\n-\tcommit=$(git commit-tree -p $head -p $rev -m \"Add subproject master\" $tree) &&\n-\tgit update-ref HEAD $commit &&\n-\t(\n-\t\tcd files_subtree &&\n-\t\ttest_commit master4\n-\t) &&\n+\n+\tgit init files &&\n+\ttest_commit -C files master1 &&\n+\ttest_commit -C files master2 &&\n+\ttest_commit -C files master3 &&\n+\n+\t: perform subtree merge into files_subtree/ &&\n+\tgit fetch files refs/heads/master:refs/heads/files-master &&\n+\tgit merge -s ours --no-commit --allow-unrelated-histories \\\n+\t\tfiles-master &&\n+\tgit read-tree --prefix=files_subtree -u files-master &&\n+\tgit commit -m \"Add subproject master\" &&\n+\n+\t: add two extra commits to rebase &&\n+\ttest_commit -C files_subtree master4 &&\n \ttest_commit files_subtree/master5\n '\n \n-- \ngitgitgadget\n\n"},{"id":"381836","messageId":"20190904214048.29331-1-newren@gmail.com","threadId":"51522","inReplyTo":"pull.294.v2.git.gitgitgadget@gmail.com","subject":"[PATCH v2 17/16] t3427: accelerate this test by using fast-export and fast-import","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2019-09-04T21:40:48Z","receivedAt":"2019-09-04T21:40:56Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"fast-export and fast-import can easily handle the simple rewrite that\nwas being done by filter-branch, and should be faster on systems with a\nslow fork.  Measuring the overall time taken for all of t3427 (not just\nthe difference between filter-branch and fast-export/fast-import) shows\na speedup of about 5% on Linux and 11% on Mac.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\nThis patch is meant to be added onto the end of js/rebase-r-strategy; an\nearlier version of this patch conflicted js/rebase-r-strategy so now I'm\nbasing on top of that series.  The speedup is also less impressive now\nthat there is only one filter-branch invocation being replaced instead of\na handful.  Still a nice speedup, though.\n\n t/t3427-rebase-subtree.sh | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\nindex 39e348de16..bec48e6a1f 100755\n--- a/t/t3427-rebase-subtree.sh\n+++ b/t/t3427-rebase-subtree.sh\n@@ -59,7 +59,10 @@ test_expect_success 'setup' '\n \ttest_commit files_subtree/master5 &&\n \n \tgit checkout -b to-rebase &&\n-\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n+\tgit fast-export --no-data HEAD -- files_subtree/ |\n+\t\tsed -e \"s%\\([0-9a-f]\\{40\\} \\)files_subtree/%\\1%\" |\n+\t\tgit fast-import --force --quiet &&\n+\tgit reset --hard &&\n \tgit commit -m \"Empty commit\" --allow-empty\n '\n \n-- \n2.22.0.19.ga495766805\n\n"},{"id":"382098","messageId":"nycvar.QRO.7.76.6.1909092229040.5377@tvgsbejvaqbjf.bet","threadId":"51522","inReplyTo":"20190904214048.29331-1-newren@gmail.com","subject":"Re: [PATCH v2 17/16] t3427: accelerate this test by using fast-export and fast-import","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-09-09T20:29:30Z","receivedAt":"2019-09-09T20:29:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Elijah,\n\nOn Wed, 4 Sep 2019, Elijah Newren wrote:\n\n> fast-export and fast-import can easily handle the simple rewrite that\n> was being done by filter-branch, and should be faster on systems with a\n> slow fork.  Measuring the overall time taken for all of t3427 (not just\n> the difference between filter-branch and fast-export/fast-import) shows\n> a speedup of about 5% on Linux and 11% on Mac.\n>\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n> This patch is meant to be added onto the end of js/rebase-r-strategy; an\n> earlier version of this patch conflicted js/rebase-r-strategy so now I'm\n> basing on top of that series.  The speedup is also less impressive now\n> that there is only one filter-branch invocation being replaced instead of\n> a handful.  Still a nice speedup, though.\n\nACK!\n\nThanks,\nDscho\n\n>\n>  t/t3427-rebase-subtree.sh | 5 ++++-\n>  1 file changed, 4 insertions(+), 1 deletion(-)\n>\n> diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\n> index 39e348de16..bec48e6a1f 100755\n> --- a/t/t3427-rebase-subtree.sh\n> +++ b/t/t3427-rebase-subtree.sh\n> @@ -59,7 +59,10 @@ test_expect_success 'setup' '\n>  \ttest_commit files_subtree/master5 &&\n>\n>  \tgit checkout -b to-rebase &&\n> -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n> +\tgit fast-export --no-data HEAD -- files_subtree/ |\n> +\t\tsed -e \"s%\\([0-9a-f]\\{40\\} \\)files_subtree/%\\1%\" |\n> +\t\tgit fast-import --force --quiet &&\n> +\tgit reset --hard &&\n>  \tgit commit -m \"Empty commit\" --allow-empty\n>  '\n>\n> --\n> 2.22.0.19.ga495766805\n>\n>\n"},{"id":"382100","messageId":"xmqqa7bdi3hl.fsf@gitster-ct.c.googlers.com","threadId":"51522","inReplyTo":"nycvar.QRO.7.76.6.1909092229040.5377@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 17/16] t3427: accelerate this test by using fast-export and fast-import","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-09-09T21:06:30Z","receivedAt":"2019-09-09T21:06:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi Elijah,\n>\n> On Wed, 4 Sep 2019, Elijah Newren wrote:\n>\n>> fast-export and fast-import can easily handle the simple rewrite that\n>> was being done by filter-branch, and should be faster on systems with a\n>> slow fork.  Measuring the overall time taken for all of t3427 (not just\n>> the difference between filter-branch and fast-export/fast-import) shows\n>> a speedup of about 5% on Linux and 11% on Mac.\n>>\n>> Signed-off-by: Elijah Newren <newren@gmail.com>\n>> ---\n>> This patch is meant to be added onto the end of js/rebase-r-strategy; an\n>> earlier version of this patch conflicted js/rebase-r-strategy so now I'm\n>> basing on top of that series.  The speedup is also less impressive now\n>> that there is only one filter-branch invocation being replaced instead of\n>> a handful.  Still a nice speedup, though.\n>\n> ACK!\n>\n> Thanks,\n> Dscho\n\nThanks, both.  This indeed is a good update.\n\n>\n>>\n>>  t/t3427-rebase-subtree.sh | 5 ++++-\n>>  1 file changed, 4 insertions(+), 1 deletion(-)\n>>\n>> diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh\n>> index 39e348de16..bec48e6a1f 100755\n>> --- a/t/t3427-rebase-subtree.sh\n>> +++ b/t/t3427-rebase-subtree.sh\n>> @@ -59,7 +59,10 @@ test_expect_success 'setup' '\n>>  \ttest_commit files_subtree/master5 &&\n>>\n>>  \tgit checkout -b to-rebase &&\n>> -\tgit filter-branch --prune-empty -f --subdirectory-filter files_subtree &&\n>> +\tgit fast-export --no-data HEAD -- files_subtree/ |\n>> +\t\tsed -e \"s%\\([0-9a-f]\\{40\\} \\)files_subtree/%\\1%\" |\n>> +\t\tgit fast-import --force --quiet &&\n>> +\tgit reset --hard &&\n>>  \tgit commit -m \"Empty commit\" --allow-empty\n>>  '\n>>\n>> --\n>> 2.22.0.19.ga495766805\n>>\n>>\n"}]}