summaryrefslogtreecommitdiff
path: root/t/t3427-rebase-subtree.sh
AgeCommit message (Collapse)AuthorFilesLines
2020-02-16rebase (interactive-backend): fix handling of commits that become emptyLibravatar Elijah Newren1-4/+4
As established in the previous commit and commit b00bf1c9a8dd (git-rebase: make --allow-empty-message the default, 2018-06-27), the behavior for rebase with different backends in various edge or corner cases is often more happenstance than design. This commit addresses another such corner case: commits which "become empty". A careful reader may note that there are two types of commits which would become empty due to a rebase: * [clean cherry-pick] Commits which are clean cherry-picks of upstream commits, as determined by `git log --cherry-mark ...`. Re-applying these commits would result in an empty set of changes and a duplicative commit message; i.e. these are commits that have "already been applied" upstream. * [become empty] Commits which are not empty to start, are not clean cherry-picks of upstream commits, but which still become empty after being rebased. This happens e.g. when a commit has changes which are a strict subset of the changes in an upstream commit, or when the changes of a commit can be found spread across or among several upstream commits. Clearly, in both cases the changes in the commit in question are found upstream already, but the commit message may not be in the latter case. When cherry-mark can determine a commit is already upstream, then because of how cherry-mark works this means the upstream commit message was about the *exact* same set of changes. Thus, the commit messages can be assumed to be fully interchangeable (and are in fact likely to be completely identical). As such, the clean cherry-pick case represents a case when there is no information to be gained by keeping the extra commit around. All rebase types have always dropped these commits, and no one to my knowledge has ever requested that we do otherwise. For many of the become empty cases (and likely even most), we will also be able to drop the commit without loss of information -- but this isn't quite always the case. Since these commits represent cases that were not clean cherry-picks, there is no upstream commit message explaining the same set of changes. Projects with good commit message hygiene will likely have the explanation from our commit message contained within or spread among the relevant upstream commits, but not all projects run that way. As such, the commit message of the commit being rebased may have reasoning that suggests additional changes that should be made to adapt to the new base, or it may have information that someone wants to add as a note to another commit, or perhaps someone even wants to create an empty commit with the commit message as-is. Junio commented on the "become-empty" types of commits as follows[1]: WRT a change that ends up being empty (as opposed to a change that is empty from the beginning), I'd think that the current behaviour is desireable one. "am" based rebase is solely to transplant an existing history and want to stop much less than "interactive" one whose purpose is to polish a series before making it publishable, and asking for confirmation ("this has become empty--do you want to drop it?") is more appropriate from the workflow point of view. [1] https://lore.kernel.org/git/xmqqfu1fswdh.fsf@gitster-ct.c.googlers.com/ I would simply add that his arguments for "am"-based rebases actually apply to all non-explicitly-interactive rebases. Also, since we are stating that different cases should have different defaults, it may be worth providing a flag to allow users to select which behavior they want for these commits. Introduce a new command line flag for selecting the desired behavior: --empty={drop,keep,ask} with the definitions: drop: drop commits which become empty keep: keep commits which become empty ask: provide the user a chance to interact and pick what to do with commits which become empty on a case-by-case basis In line with Junio's suggestion, if the --empty flag is not specified, pick defaults as follows: explicitly interactive: ask otherwise: drop Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-16rebase (interactive-backend): make --keep-empty the defaultLibravatar Elijah Newren1-6/+6
Different rebase backends have different treatment for commits which start empty (i.e. have no changes relative to their parent), and the --keep-empty option was added at some point to allow adjusting behavior. The handling of commits which start empty is actually quite similar to commit b00bf1c9a8dd (git-rebase: make --allow-empty-message the default, 2018-06-27), which pointed out that the behavior for various backends is often more happenstance than design. The specific change made in that commit is actually quite relevant as well and much of the logic there directly applies here. It makes a lot of sense in 'git commit' to error out on the creation of empty commits, unless an override flag is provided. However, once someone determines that there is a rare case that merits using the manual override to create such a commit, it is somewhere between annoying and harmful to have to take extra steps to keep such intentional commits around. Granted, empty commits are quite rare, which is why handling of them doesn't get considered much and folks tend to defer to existing (accidental) behavior and assume there was a reason for it, leading them to just add flags (--keep-empty in this case) that allow them to override the bad defaults. Fix the interactive backend so that --keep-empty is the default, much like we did with --allow-empty-message. The am backend should also be fixed to have --keep-empty semantics for commits that start empty, but that is not included in this patch other than a testcase documenting the failure. Note that there was one test in t3421 which appears to have been written expecting --keep-empty to not be the default as correct behavior. This test was introduced in commit 00b8be5a4d38 ("add tests for rebasing of empty commits", 2013-06-06), which was part of a series focusing on rebase topology and which had an interesting original cover letter at https://lore.kernel.org/git/1347949878-12578-1-git-send-email-martinvonz@gmail.com/ which noted Your input especially appreciated on whether you agree with the intent of the test cases. and then went into a long example about how one of the many tests added had several questions about whether it was correct. As such, I believe most the tests in that series were about testing rebase topology with as many different flags as possible and were not trying to state in general how those flags should behave otherwise. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-05t3427: accelerate this test by using fast-export and fast-importLibravatar Elijah Newren1-1/+4
fast-export and fast-import can easily handle the simple rewrite that was being done by filter-branch, and should be faster on systems with a slow fork. Measuring the overall time taken for all of t3427 (not just the difference between filter-branch and fast-export/fast-import) shows a speedup of about 5% on Linux and 11% on Mac. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`Libravatar Johannes Schindelin1-0/+11
When rebasing a complete commit history onto a given commit, it is pretty obvious that the root commits should be rebased on top of said given commit. To test this, let's kill two birds with one stone and add a test case to t3427-rebase-subtree.sh that not only demonstrates that this works, but also that `git rebase -r` works with merge strategies now. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: fix another incorrect assumptionLibravatar Johannes Schindelin1-3/+4
The test case that concerns `git rebase -Xsubtree` (with the default rebase backend, not with `--preserve-merges`) starts out with a pre-rebase commit history that begins with a commit that introduces three files: master1.t, master2.t and master3.t. This commit was generated by passing a subtree merge commit through `git filter-branch --subdirectory-filter`, so it looks as if this commit really introduces all those files. The commit history onto which this commit is then rebased, however, introduced those files in individual commits. For that reason, the rebase will fail, it _must_ fail, because the first `pick` results in no changes to be committed. Let's fix the test case to expect exactly this situation. With this change, we can mark the original bug that this test case tried to demonstrate as fixed. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: accommodate for the `rebase --merge` backend having been replacedLibravatar Johannes Schindelin1-2/+2
Since 68aa495b590 (rebase: implement --merge via the interactive machinery, 2018-12-11), the job of the old `--merge` backend is now performed by the `--interactive` backend, too. One consequence is that empty commits are no longer rebased by default. Meaning that the test case that calls `git rebase -Xsubtree` (which used to be handled by the `--merge` backend) now needs to ask explicitly for the empty commit to be rebased. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: fix erroneous assumptionLibravatar Johannes Schindelin1-3/+3
Apart from the `setup` test case, `t3427-rebase-subtree.sh` is made up exclusively of demonstrations of breakages. The tricky thing about such demonstrations is that they are often buggy themselves. In this instance, somewhere over the course of the six iterations of the patch that eventually made it into Git's `master` as 5f35900849e (contrib/subtree: Add a test for subtree rebase that loses commits, 2016-06-28), the commit message "files_subtree/master4" was changed to just "master4", but the test cases still expected the old commit message. Let's fix this, at long last. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: condense the unnecessarily repetitive test cases into threeLibravatar Johannes Schindelin1-50/+11
Previously, this test script performed essentially three rebases and verified breakages by testing the post-rebase commits' messages. To do so, the rebases were performed multiple times, though, once per commit message to test. This wastes electricity (and CO2) and time. Let's condense the test cases to the essential number: the number of different rebases to validate. On Windows, where the scripted nature of the `--preserve-merges` backend hurts performance rather badly, this reduces the overall runtime in this developer's setup from ~1m to ~28s while still performing the exact same testing as before. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: move the `filter-branch` invocation into the `setup` caseLibravatar Johannes Schindelin1-25/+13
The step to prepare a pre-rebase commit history is _identical_ in _all_ of the test cases (except of course the `setup` case). It should therefore clearly a part of the `setup` test case instead. As the `git filter-branch` command is quite costly on platforms where Unix shell scripting is simply slow (meaning: on Windows), this shaves off a noticeable part of the runtime: in this developer's setup, the time was reduced from ~1m25s to ~1m. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: simplify the `setup` test case significantlyLibravatar Johannes Schindelin1-21/+15
It still does the very same thing as before, but expresses it in a much more succinct (and still quite readable) manner. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-31t3427: add a clarifying commentLibravatar Johannes Schindelin1-0/+28
The flow of this test script is outright confusing, and to start the endeavor to address that, let's describe what this test is all about, and how it tries to do it. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-05-28tests: mark a couple more test cases as requiring `rebase -p`Libravatar Johannes Schindelin1-5/+10
The `--preserve-merges` option has been deprecated, and as a consequence we started to mark test cases that require that option to be supported, in preparation for removing that support eventually. Since we marked those test cases, a couple more crept into the test suite, and with this patch, we mark them, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-28contrib/subtree: Add a test for subtree rebase that loses commitsLibravatar David A. Greene1-0/+119
This test merges an external tree in as a subtree, makes some commits on top of it and splits it back out. In the process the added commits are lost or the rebase aborts with an internal error. The tests are marked to expect failure so that we don't forget to fix it. Signed-off-by: David A. Greene <greened@obbligato.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>