aboutsummaryrefslogtreecommitdiffstats
path: root/t/t6044-merge-unrelated-index-changes.sh (follow)
AgeCommit message (Collapse)AuthorFilesLines
2020-08-10Collect merge-related tests to t64xxElijah Newren1-216/+0
The tests for the merge machinery are spread over several places. Collect them into t64xx for simplicity. Some notes: t60[234]*.sh: Merge tests started in t602*, overgrew bisect and remote tracking tests in t6030, t6040, and t6041, and nearly overtook replace tests in t6050. This made picking out relevant tests that I wanted to run in a tighter loop slightly more annoying for years. t303*.sh: These started out as tests for the 'merge-recursive' toplevel command, but did not restrict to that and had lots of overlap with the underlying merge machinery. t7405, t7613: submodule-specific merge logic started out in submodule.c but was moved to merge-recursive.c in commit 18cfc08866 ("submodule.c: move submodule merging to merge-recursive.c", 2018-05-15). Since these tests are about the logic found in the merge machinery, moving these tests to be with the merge tests makes sense. t7607, t7609: Having tests spread all over the place makes it more likely that additional tests related to a certain piece of logic grow in all those other places. Much like t303*.sh, these two tests were about the underlying merge machinery rather than outer levels. Tests that were NOT moved: t76[01]*.sh: Other than the four tests mentioned above, the remaining tests in t76[01]*.sh are related to non-recursive merge strategies, parameter parsing, and other stuff associated with the highlevel builtin/merge.c rather than the recursive merge machinery. t3[45]*.sh: The rebase testcases in t34*.sh also test the merge logic pretty heavily; sometimes changes I make only trigger failures in the rebase tests. The rebase tests are already nicely coupled together, though, and I didn't want to mess that up. Similar comments apply for the cherry-pick tests in t35*.sh. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-11merge-recursive: enforce rule that index matches head before mergingElijah Newren1-11/+8
builtin/merge.c says that when we are about to perform a merge: ...the index must be in sync with the head commit. The strategies are responsible to ensure this. merge-recursive has always relied on unpack_trees() to enforce this requirement, except in the case of an "Already up to date!" merge. unpack-trees.c does not actually enforce this requirement, though. It allows for a pair of exceptions, in cases which it refers to as #14(ALT) and #2ALT. Documentation/technical/trivial-merge.txt can be consulted for the precise meanings of the various case numbers and their meanings for unpack-trees.c, but we have a high-level description of the intent behind these two exceptions in a combined and summarized form in Documentation/git-merge.txt: ...[merge will] abort if there are any changes registered in the index relative to the `HEAD` commit. (One exception is when the changed index entries are in the state that would result from the merge already.) While this high-level description does describe conditions under which it would be safe to allow the index to diverge from HEAD, it does not match what is actually implemented. In particular, unpack-trees.c has no knowledge of renames, and these two exceptions were written assuming that no renames take place. Once renames get into the mix, it is no longer safe to allow the index to not match for #2ALT. We could modify unpack-trees to only allow #14(ALT) as an exception, but that would be more strict than required for the resolve strategy (since the resolve strategy doesn't handle renames at all). Therefore, unpack_trees.c seems like the wrong place to fix this. Further, if someone fixes the combination of break and rename detection and modifies merge-recursive to take advantage of the combination, then it will also no longer be safe to allow the index to not match for #14(ALT) when the recursive strategy is in use. Therefore, leaving one of the exceptions in place with the recursive merge strategy feels like we are just leaving a latent bug in the code for folks in the future to stumble across. It may be possible to fix both unpack-trees and merge-recursive in a way that implements the exception as stated in Documentation/git-merge.txt, but it would be somewhat complex, possibly also buggy at first, and ultimately, not all that valuable. Instead, just enforce the requirement stated in builtin/merge.c; error out if the index does not match the HEAD commit, just like the 'ours' and 'octopus' strategies do. Some testcase fixups were in order: t7611: had many tests designed to show that `git merge --abort` could not always restore the index and working tree to the state they were in before the merge started. The tests that were associated with having changes in the index before the merge started are no longer applicable, so they have been removed. t7504: had a few tests that had stray staged changes that were not actually part of the test under consideration t6044: We no longer expect stray staged changes to sometimes result in the merge continuing. Also, fix a case where a merge didn't abort but should have. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-11t6044: add more testcases with staged changes before a merge is invokedElijah Newren1-0/+29
According to Documentation/git-merge.txt, ...[merge will] abort if there are any changes registered in the index relative to the `HEAD` commit. (One exception is when the changed index entries are in the state that would result from the merge already.) Add some tests showing that this exception, while it does accurately state what would be a safe condition under which we could allow the merge to proceed, is not what is actually implemented. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-11merge-recursive: fix assumption that head tree being merged is HEADElijah Newren1-1/+1
`git merge-recursive` does a three-way merge between user-specified trees base, head, and remote. Since the user is allowed to specify head, we can not necesarily assume that head == HEAD. Modify index_has_changes() to take an extra argument specifying the tree to compare against. If NULL, it will compare to HEAD. We then use this from merge-recursive to make sure we compare to the user-specified head. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-11merge-recursive: make sure when we say we abort that we actually abortElijah Newren1-1/+1
In commit 65170c07d4 ("merge-recursive: avoid incorporating uncommitted changes in a merge", 2017-12-21), it was noted that there was a special case when merge-recursive didn't rely on unpack_trees() to enforce the index == HEAD requirement, and thus that it needed to do that enforcement itself. Unfortunately, it returned the wrong exit status, signalling that the merge completed but had conflicts, rather than that it was aborted. Fix the return code, and while we're at it, change the error message to match what unpack_trees() would have printed. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-11t6044: add a testcase for index matching head, when head doesn't match HEADElijah Newren1-0/+11
The `git merge-recursive` command allows the user to directly specify three commits to merge -- base, head, and remote. (More than three can be specified in the case of multiple merge bases.) Note that since the user is allowed to specify head, it need not match HEAD. Virtually every test and script in the current git.git codebase calls `git merge-recursive` with head=HEAD, and likely external callers do as well, which is why this has gone unnoticed. There is one notable counter-example: git-stash.sh. However, git-stash called `git merge-recursive` with an index that matches the expected merge result, which happens to be a currently allowed exception to the "index must match head" rule, so this never triggered an error previously. Since we would like to tighten up the "index must match head" rule, we need to make sure we are comparing to the correct head. Add a testcase that demonstrates the failure when we check the wrong HEAD. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-03t6044: verify that merges expected to abort actually abortElijah Newren1-11/+21
t6044 has lots of tests for verifying that merge will abort as expected when there are changes staged before the merge starts. However, it only checked for non-zero exit code, which could mean that the merge ran to completion with conflicts. Check that the merge was actually correctly aborted, i.e. that .git/MERGE_HEAD is not present. This changes one of the tests from expect_success to expect_failure. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-22merge-recursive: avoid incorporating uncommitted changes in a mergeElijah Newren1-1/+1
builtin/merge.c contains this important requirement for merge strategies: /* * At this point, we need a real merge. No matter what strategy * we use, it would operate on the index, possibly affecting the * working tree, and when resolved cleanly, have the desired * tree in the index -- this means that the index must be in * sync with the head commit. The strategies are responsible * to ensure this. */ merge-recursive does not do this check directly, instead it relies on unpack_trees() to do it. However, merge_trees() has a special check for the merge branch exactly matching the merge base; when it detects that situation, it returns early without calling unpack_trees(), because it knows that the HEAD commit already has the correct result. Unfortunately, it didn't check that the index matched HEAD, so after it returned, the outer logic ended up creating a merge commit that included something other than HEAD. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-22t6044: recursive can silently incorporate dirty changes in a mergeElijah Newren1-5/+21
The recursive merge strategy has some special handling when the tree for the merge branch exactly matches the merge base, but that code path is missing checks for the index having changes relative to HEAD. Add a testcase covering this scenario. Reported-by: Andreas Krey <a.krey@gmx.de> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-29Merge branch 'js/t6044-use-test-seq'Junio C Hamano1-2/+2
Test portability fix. * js/t6044-use-test-seq: t6044: replace seq by test_seq
2016-05-18t6044: replace seq by test_seqJohannes Sixt1-2/+2
seq is not available everywhere. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-12t6044: new merge testcases for when index doesn't match HEADElijah Newren1-0/+153
With one exception, we require the index to exactly match the current HEAD commit at the time git merge is invoked. This expectation was even documented in git-merge.txt until commit ebef7e5 (Documentation: simplify How Merge Works, 2010-01-23). Most merge strategies enforced this requirement, but it turns out not all did. The current exceptions were the following two: * ff updates * octopus merges ff updates actually will error out if the staged change is to a path modified between HEAD and the commit being merged. If the path(s) that are staged are files unrelated to the changes between these two commits, though, then an ff update will just keep these staged changes around after the merge. This is the one exception we expected to the abort-merge-if- index-doesn't-match-HEAD rule. For octopus merges, the rule should be enforced. Unfortunately, the current behavior of the code is to ignore the difference and use the staged changes in place of whatever is in HEAD as it proceeds to perform the merge. So if the staged changes can be cleanly merged with all the other heads, then the staged changes will just be incorported into the resulting commit. If the staged changes cannot be cleanly merged with all the other heads, the merge is not aborted -- merge conflicts are simply reported as if HEAD had originally contained whatever the index did. Add testcases that check our expectations. A subsequent commit will correct the erroneous octopus merge behavior. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-12merge-octopus: abort if index does not match HEADElijah Newren1-3/+3
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>