/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
16
7479.2.1 by Jelmer Vernooij
Drop python2 support.
17
import contextlib
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
18
import os
19
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
20
from .. import (
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
21
    branch as _mod_branch,
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
22
    conflicts,
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
23
    errors,
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
24
    memorytree,
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
25
    merge as _mod_merge,
26
    option,
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
27
    revision as _mod_revision,
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
28
    tests,
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
29
    transform,
6670.4.1 by Jelmer Vernooij
Update imports.
30
    )
31
from ..bzr import (
32
    inventory,
33
    knit,
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
34
    versionedfile,
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
35
    )
7490.129.3 by Jelmer Vernooij
Split out bzr-specific Conflicts code.
36
from ..conflicts import ConflictList
37
from ..bzr.conflicts import TextConflict, MissingParent, UnversionedParent, DeletingParent, ContentsConflict
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
38
from ..errors import UnrelatedBranches, NoCommits
39
from ..merge import transform_tree, merge_inner, _PlanMerge
40
from ..osutils import basename, pathjoin, file_kind
41
from . import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
42
    features,
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
43
    TestCaseWithMemoryTransport,
44
    TestCaseWithTransport,
45
    test_merge_core,
46
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
47
from ..workingtree import WorkingTree
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
48
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
49
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
50
class TestMerge(TestCaseWithTransport):
974.1.56 by aaron.bentley at utoronto
Added merge test
51
    """Test appending more than one revision"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
52
974.1.56 by aaron.bentley at utoronto
Added merge test
53
    def test_pending(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
54
        wt = self.make_branch_and_tree('.')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
55
        rev_a = wt.commit("lala!")
56
        self.assertEqual([rev_a], wt.get_parent_ids())
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
57
        self.assertRaises(errors.PointlessMerge, wt.merge_from_branch,
58
                          wt.branch)
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
59
        self.assertEqual([rev_a], wt.get_parent_ids())
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
60
        return wt
974.1.80 by Aaron Bentley
Improved merge error handling and testing
61
1558.4.11 by Aaron Bentley
Allow merge against self, make fetching self a noop
62
    def test_undo(self):
63
        wt = self.make_branch_and_tree('.')
64
        wt.commit("lala!")
65
        wt.commit("haha!")
66
        wt.commit("blabla!")
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
67
        wt.merge_from_branch(wt.branch, wt.branch.get_rev_id(2),
68
                             wt.branch.get_rev_id(1))
1558.4.11 by Aaron Bentley
Allow merge against self, make fetching self a noop
69
974.1.80 by Aaron Bentley
Improved merge error handling and testing
70
    def test_nocommits(self):
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
71
        wt = self.test_pending()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
72
        wt2 = self.make_branch_and_tree('branch2')
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
73
        self.assertRaises(NoCommits, wt.merge_from_branch, wt2.branch)
74
        return wt, wt2
974.1.80 by Aaron Bentley
Improved merge error handling and testing
75
76
    def test_unrelated(self):
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
77
        wt, wt2 = self.test_nocommits()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
78
        wt2.commit("blah")
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
79
        self.assertRaises(UnrelatedBranches, wt.merge_from_branch, wt2.branch)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
80
        return wt2
974.1.80 by Aaron Bentley
Improved merge error handling and testing
81
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
82
    def test_merge_one_file(self):
83
        """Do a partial merge of a tree which should not affect tree parents."""
1645.1.1 by Aaron Bentley
Implement single-file merge
84
        wt1 = self.make_branch_and_tree('branch1')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
85
        tip = wt1.commit('empty commit')
1645.1.1 by Aaron Bentley
Implement single-file merge
86
        wt2 = self.make_branch_and_tree('branch2')
87
        wt2.pull(wt1.branch)
6973.7.5 by Jelmer Vernooij
s/file/open.
88
        with open('branch1/foo', 'wb') as f:
89
            f.write(b'foo')
90
        with open('branch1/bar', 'wb') as f:
91
            f.write(b'bar')
1645.1.1 by Aaron Bentley
Implement single-file merge
92
        wt1.add('foo')
93
        wt1.add('bar')
94
        wt1.commit('add foobar')
6423.1.1 by Vincent Ladeuil
Cleanup old blackbox tests and then some. Remove os.chdir() calls, caught a few bugs, make sure we don't leave file handles opened.
95
        self.run_bzr('merge ../branch1/baz', retcode=3, working_dir='branch2')
96
        self.run_bzr('merge ../branch1/foo', working_dir='branch2')
97
        self.assertPathExists('branch2/foo')
98
        self.assertPathDoesNotExist('branch2/bar')
99
        wt2 = WorkingTree.open('branch2')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
100
        self.assertEqual([tip], wt2.get_parent_ids())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
101
974.1.88 by Aaron Bentley
Set a pending_merge if the merge base is forced to revno 0
102
    def test_pending_with_null(self):
1551.8.25 by Aaron Bentley
Fix deprecated use of pending_merges
103
        """When base is forced to revno 0, parent_ids are set"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
104
        wt2 = self.test_unrelated()
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
105
        wt1 = WorkingTree.open('.')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
106
        br1 = wt1.branch
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
107
        br1.fetch(wt2.branch)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
108
        # merge all of branch 2 into branch 1 even though they
1390 by Robert Collins
pair programming worx... merge integration and weave
109
        # are not related.
6973.14.6 by Jelmer Vernooij
Fix some more tests.
110
        wt1.merge_from_branch(wt2.branch, wt2.last_revision(), b'null:')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
111
        self.assertEqual([br1.last_revision(), wt2.branch.last_revision()],
7143.15.2 by Jelmer Vernooij
Run autopep8.
112
                         wt1.get_parent_ids())
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
113
        return (wt1, wt2.branch)
974.1.89 by Aaron Bentley
Fixed merging with multiple roots, by using null as graph root.
114
115
    def test_two_roots(self):
116
        """Merge base is sane when two unrelated branches are merged"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
117
        wt1, br2 = self.test_pending_with_null()
118
        wt1.commit("blah")
3228.4.15 by John Arbash Meinel
Stop using common_ancestor
119
        wt1.lock_read()
120
        try:
121
            last = wt1.branch.last_revision()
122
            last2 = br2.last_revision()
123
            graph = wt1.branch.repository.get_graph()
124
            self.assertEqual(last2, graph.find_unique_lca(last, last2))
125
        finally:
126
            wt1.unlock()
1185.46.1 by Aaron Bentley
Test case when file to be renamed is also deleted
127
5954.4.2 by Aaron Bentley
Support merging into null tree.
128
    def test_merge_into_null_tree(self):
129
        wt = self.make_branch_and_tree('tree')
130
        null_tree = wt.basis_tree()
131
        self.build_tree(['tree/file'])
132
        wt.add('file')
133
        wt.commit('tree with root')
134
        merger = _mod_merge.Merge3Merger(null_tree, null_tree, null_tree, wt,
135
                                         this_branch=wt.branch,
136
                                         do_merge=False)
137
        with merger.make_preview_transform() as tt:
7490.129.2 by Jelmer Vernooij
Move cook conflict implementation into breezy.bzr.transform.
138
            self.assertEqual([], tt.find_raw_conflicts())
5954.4.2 by Aaron Bentley
Support merging into null tree.
139
            preview = tt.get_preview_tree()
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
140
            self.assertEqual(wt.path2id(''), preview.path2id(''))
5954.4.2 by Aaron Bentley
Support merging into null tree.
141
6011.1.1 by Aaron Bentley
Merging an unrelated tree retains root.
142
    def test_merge_unrelated_retains_root(self):
143
        wt = self.make_branch_and_tree('tree')
6024.1.2 by Aaron Bentley
Explicitly test transform in test case.
144
        other_tree = self.make_branch_and_tree('other')
145
        self.addCleanup(other_tree.lock_read().unlock)
6011.1.7 by Vincent Ladeuil
Change test order to get a better diff.
146
        merger = _mod_merge.Merge3Merger(wt, wt, wt.basis_tree(), other_tree,
147
                                         this_branch=wt.branch,
148
                                         do_merge=False)
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
149
        with wt.preview_transform() as merger.tt:
6024.1.2 by Aaron Bentley
Explicitly test transform in test case.
150
            merger._compute_transform()
151
            new_root_id = merger.tt.final_file_id(merger.tt.root)
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
152
            self.assertEqual(wt.path2id(''), new_root_id)
6011.1.7 by Vincent Ladeuil
Change test order to get a better diff.
153
1185.46.1 by Aaron Bentley
Test case when file to be renamed is also deleted
154
    def test_create_rename(self):
155
        """Rename an inventory entry while creating the file"""
7143.15.2 by Jelmer Vernooij
Run autopep8.
156
        tree = self.make_branch_and_tree('.')
157
        with open('name1', 'wb') as f:
158
            f.write(b'Hello')
1185.46.1 by Aaron Bentley
Test case when file to be renamed is also deleted
159
        tree.add('name1')
160
        tree.commit(message="hello")
161
        tree.rename_one('name1', 'name2')
162
        os.unlink('name2')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
163
        transform_tree(tree, tree.branch.basis_tree())
1185.46.2 by Aaron Bentley
Added test for renaming both parent and child
164
165
    def test_layered_rename(self):
166
        """Rename both child and parent at same time"""
7143.15.2 by Jelmer Vernooij
Run autopep8.
167
        tree = self.make_branch_and_tree('.')
1185.46.2 by Aaron Bentley
Added test for renaming both parent and child
168
        os.mkdir('dirname1')
169
        tree.add('dirname1')
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
170
        filename = pathjoin('dirname1', 'name1')
7143.15.2 by Jelmer Vernooij
Run autopep8.
171
        with open(filename, 'wb') as f:
172
            f.write(b'Hello')
1185.46.2 by Aaron Bentley
Added test for renaming both parent and child
173
        tree.add(filename)
174
        tree.commit(message="hello")
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
175
        filename2 = pathjoin('dirname1', 'name2')
1185.46.2 by Aaron Bentley
Added test for renaming both parent and child
176
        tree.rename_one(filename, filename2)
177
        tree.rename_one('dirname1', 'dirname2')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
178
        transform_tree(tree, tree.branch.basis_tree())
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
179
180
    def test_ignore_zero_merge_inner(self):
1907.4.1 by Matthieu Moy
Fixed merge to work nicely with -r revno:N:path
181
        # Test that merge_inner's ignore zero parameter is effective
7143.15.2 by Jelmer Vernooij
Run autopep8.
182
        tree_a = self.make_branch_and_tree('a')
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
183
        tree_a.commit(message="hello")
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
184
        dir_b = tree_a.controldir.sprout('b')
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
185
        tree_b = dir_b.open_workingtree()
3146.4.4 by Aaron Bentley
Add write lock, so merge_inner works properly
186
        tree_b.lock_write()
187
        self.addCleanup(tree_b.unlock)
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
188
        tree_a.commit(message="hello again")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
189
        merge_inner(tree_b.branch, tree_a, tree_b.basis_tree(),
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
190
                    this_tree=tree_b, ignore_zero=True)
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
191
        self.assertTrue('All changes applied successfully.\n' not in
7143.15.2 by Jelmer Vernooij
Run autopep8.
192
                        self.get_log())
2796.1.3 by Aaron Bentley
update new test case
193
        tree_b.revert()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
194
        merge_inner(tree_b.branch, tree_a, tree_b.basis_tree(),
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
195
                    this_tree=tree_b, ignore_zero=False)
7143.15.2 by Jelmer Vernooij
Run autopep8.
196
        self.assertTrue(
197
            'All changes applied successfully.\n' in self.get_log())
1551.7.10 by Aaron Bentley
Remerge doesn't clear unrelated conflicts
198
199
    def test_merge_inner_conflicts(self):
200
        tree_a = self.make_branch_and_tree('a')
7490.129.3 by Jelmer Vernooij
Split out bzr-specific Conflicts code.
201
        tree_a.set_conflicts([TextConflict('patha')])
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
202
        merge_inner(tree_a.branch, tree_a, tree_a, this_tree=tree_a)
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
203
        self.assertEqual(1, len(tree_a.conflicts()))
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
204
205
    def test_rmdir_conflict(self):
206
        tree_a = self.make_branch_and_tree('a')
207
        self.build_tree(['a/b/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
208
        tree_a.add('b', b'b-id')
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
209
        tree_a.commit('added b')
2255.7.12 by John Arbash Meinel
Some comments on merge code, fix merge tests that
210
        # basis_tree() is only guaranteed to be valid as long as it is actually
211
        # the basis tree. This mutates the tree after grabbing basis, so go to
212
        # the repository.
7143.15.2 by Jelmer Vernooij
Run autopep8.
213
        base_tree = tree_a.branch.repository.revision_tree(
214
            tree_a.last_revision())
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
215
        tree_z = tree_a.controldir.sprout('z').open_workingtree()
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
216
        self.build_tree(['a/b/c'])
217
        tree_a.add('b/c')
218
        tree_a.commit('added c')
219
        os.rmdir('z/b')
220
        tree_z.commit('removed b')
221
        merge_inner(tree_z.branch, tree_a, base_tree, this_tree=tree_z)
222
        self.assertEqual([
7490.129.3 by Jelmer Vernooij
Split out bzr-specific Conflicts code.
223
            MissingParent('Created directory', 'b', b'b-id'),
224
            UnversionedParent('Versioned directory', 'b', b'b-id')],
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
225
            tree_z.conflicts())
2255.2.216 by Robert Collins
simplify merge_nested tests.
226
        merge_inner(tree_a.branch, tree_z.basis_tree(), base_tree,
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
227
                    this_tree=tree_a)
228
        self.assertEqual([
7490.129.3 by Jelmer Vernooij
Split out bzr-specific Conflicts code.
229
            DeletingParent('Not deleting', 'b', b'b-id'),
230
            UnversionedParent('Versioned directory', 'b', b'b-id')],
1551.8.22 by Aaron Bentley
Improve message when OTHER deletes an in-use tree
231
            tree_a.conflicts())
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
232
2100.3.29 by Aaron Bentley
Get merge working initially
233
    def test_nested_merge(self):
6700.1.3 by Jelmer Vernooij
Drop support for committing using record_entr_contents.
234
        self.knownFailure(
235
            'iter_changes doesn\'t work with changes in nested trees')
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
236
        tree = self.make_branch_and_tree('tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
237
                                         format='development-subtree')
2100.3.29 by Aaron Bentley
Get merge working initially
238
        sub_tree = self.make_branch_and_tree('tree/sub-tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
239
                                             format='development-subtree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
240
        sub_tree.set_root_id(b'sub-tree-root')
241
        self.build_tree_contents([('tree/sub-tree/file', b'text1')])
2100.3.29 by Aaron Bentley
Get merge working initially
242
        sub_tree.add('file')
243
        sub_tree.commit('foo')
244
        tree.add_reference(sub_tree)
245
        tree.commit('set text to 1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
246
        tree2 = tree.controldir.sprout('tree2').open_workingtree()
2255.2.217 by Martin Pool
docs
247
        # modify the file in the subtree
6855.4.1 by Jelmer Vernooij
Yet more bees.
248
        self.build_tree_contents([('tree2/sub-tree/file', b'text2')])
2255.2.217 by Martin Pool
docs
249
        # and merge the changes from the diverged subtree into the containing
250
        # tree
2255.2.216 by Robert Collins
simplify merge_nested tests.
251
        tree2.commit('changed file text')
2100.3.29 by Aaron Bentley
Get merge working initially
252
        tree.merge_from_branch(tree2.branch)
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
253
        self.assertFileEqual(b'text2', 'tree/sub-tree/file')
2100.3.29 by Aaron Bentley
Get merge working initially
254
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
255
    def test_merge_with_missing(self):
256
        tree_a = self.make_branch_and_tree('tree_a')
6855.4.1 by Jelmer Vernooij
Yet more bees.
257
        self.build_tree_contents([('tree_a/file', b'content_1')])
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
258
        tree_a.add('file')
259
        tree_a.commit('commit base')
2255.7.12 by John Arbash Meinel
Some comments on merge code, fix merge tests that
260
        # basis_tree() is only guaranteed to be valid as long as it is actually
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
261
        # the basis tree. This test commits to the tree after grabbing basis,
262
        # so we go to the repository.
7143.15.2 by Jelmer Vernooij
Run autopep8.
263
        base_tree = tree_a.branch.repository.revision_tree(
264
            tree_a.last_revision())
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
265
        tree_b = tree_a.controldir.sprout('tree_b').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
266
        self.build_tree_contents([('tree_a/file', b'content_2')])
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
267
        tree_a.commit('commit other')
268
        other_tree = tree_a.basis_tree()
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
269
        # 'file' is now missing but isn't altered in any commit in b so no
270
        # change should be applied.
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
271
        os.unlink('tree_b/file')
272
        merge_inner(tree_b.branch, other_tree, base_tree, this_tree=tree_b)
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
273
274
    def test_merge_kind_change(self):
275
        tree_a = self.make_branch_and_tree('tree_a')
6855.4.1 by Jelmer Vernooij
Yet more bees.
276
        self.build_tree_contents([('tree_a/file', b'content_1')])
277
        tree_a.add('file', b'file-id')
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
278
        tree_a.commit('added file')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
279
        tree_b = tree_a.controldir.sprout('tree_b').open_workingtree()
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
280
        os.unlink('tree_a/file')
281
        self.build_tree(['tree_a/file/'])
282
        tree_a.commit('changed file to directory')
283
        tree_b.merge_from_branch(tree_a.branch)
284
        self.assertEqual('directory', file_kind('tree_b/file'))
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
285
        tree_b.revert()
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
286
        self.assertEqual('file', file_kind('tree_b/file'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
287
        self.build_tree_contents([('tree_b/file', b'content_2')])
1959.4.6 by Aaron Bentley
Ensure merge works across kind changes
288
        tree_b.commit('content change')
289
        tree_b.merge_from_branch(tree_a.branch)
290
        self.assertEqual(tree_b.conflicts(),
7490.129.3 by Jelmer Vernooij
Split out bzr-specific Conflicts code.
291
                         [ContentsConflict('file', file_id=b'file-id')])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
292
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
293
    def test_merge_type_registry(self):
294
        merge_type_option = option.Option.OPTIONS['merge-type']
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
295
        self.assertFalse('merge4' in [x[0] for x in
7143.15.2 by Jelmer Vernooij
Run autopep8.
296
                                      merge_type_option.iter_switches()])
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
297
        registry = _mod_merge.get_merge_type_registry()
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
298
        registry.register_lazy('merge4', 'breezy.merge', 'Merge4Merger',
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
299
                               'time-travelling merge')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
300
        self.assertTrue('merge4' in [x[0] for x in
7143.15.2 by Jelmer Vernooij
Run autopep8.
301
                                     merge_type_option.iter_switches()])
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
302
        registry.remove('merge4')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
303
        self.assertFalse('merge4' in [x[0] for x in
7143.15.2 by Jelmer Vernooij
Run autopep8.
304
                                      merge_type_option.iter_switches()])
1551.16.2 by Aaron Bentley
Don't crash on merging renamed deleted files (#110279)
305
1551.16.3 by Aaron Bentley
Rename test case
306
    def test_merge_other_moves_we_deleted(self):
1551.16.2 by Aaron Bentley
Don't crash on merging renamed deleted files (#110279)
307
        tree_a = self.make_branch_and_tree('A')
308
        tree_a.lock_write()
309
        self.addCleanup(tree_a.unlock)
310
        self.build_tree(['A/a'])
311
        tree_a.add('a')
6855.4.1 by Jelmer Vernooij
Yet more bees.
312
        tree_a.commit('1', rev_id=b'rev-1')
1551.16.2 by Aaron Bentley
Don't crash on merging renamed deleted files (#110279)
313
        tree_a.flush()
314
        tree_a.rename_one('a', 'b')
315
        tree_a.commit('2')
6973.5.2 by Jelmer Vernooij
Add more bees.
316
        bzrdir_b = tree_a.controldir.sprout('B', revision_id=b'rev-1')
1551.16.2 by Aaron Bentley
Don't crash on merging renamed deleted files (#110279)
317
        tree_b = bzrdir_b.open_workingtree()
318
        tree_b.lock_write()
319
        self.addCleanup(tree_b.unlock)
320
        os.unlink('B/a')
321
        tree_b.commit('3')
322
        try:
323
            tree_b.merge_from_branch(tree_a.branch)
324
        except AttributeError:
325
            self.fail('tried to join a path when name was None')
2644.1.1 by Wouter van Heyst
Fix bug #127115 by checking for self.other_rev_id being None in Merger.set_pending()
326
4685.2.1 by Gary van der Merwe
Revert rename of test_merge_uncommitted_otherbasis_ancestor_of_thisbasis.
327
    def test_merge_uncommitted_otherbasis_ancestor_of_thisbasis(self):
2644.1.1 by Wouter van Heyst
Fix bug #127115 by checking for self.other_rev_id being None in Merger.set_pending()
328
        tree_a = self.make_branch_and_tree('a')
2644.1.2 by Wouter van Heyst
As Aaron explained #127115 is more general, failing whenever other's basis is an ancestor of this' basis.
329
        self.build_tree(['a/file_1', 'a/file_2'])
2644.1.1 by Wouter van Heyst
Fix bug #127115 by checking for self.other_rev_id being None in Merger.set_pending()
330
        tree_a.add(['file_1'])
331
        tree_a.commit('commit 1')
2644.1.2 by Wouter van Heyst
As Aaron explained #127115 is more general, failing whenever other's basis is an ancestor of this' basis.
332
        tree_a.add(['file_2'])
333
        tree_a.commit('commit 2')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
334
        tree_b = tree_a.controldir.sprout('b').open_workingtree()
2644.1.2 by Wouter van Heyst
As Aaron explained #127115 is more general, failing whenever other's basis is an ancestor of this' basis.
335
        tree_b.rename_one('file_1', 'renamed')
4961.2.9 by Martin Pool
Rip out most remaining uses of DummyProgressBar
336
        merger = _mod_merge.Merger.from_uncommitted(tree_a, tree_b)
1551.15.72 by Aaron Bentley
remove builtins._merge_helper
337
        merger.merge_type = _mod_merge.Merge3Merger
338
        merger.do_merge()
2644.1.2 by Wouter van Heyst
As Aaron explained #127115 is more general, failing whenever other's basis is an ancestor of this' basis.
339
        self.assertEqual(tree_a.get_parent_ids(), [tree_b.last_revision()])
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
340
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
341
    def test_merge_uncommitted_otherbasis_ancestor_of_thisbasis_weave(self):
342
        tree_a = self.make_branch_and_tree('a')
343
        self.build_tree(['a/file_1', 'a/file_2'])
344
        tree_a.add(['file_1'])
345
        tree_a.commit('commit 1')
346
        tree_a.add(['file_2'])
347
        tree_a.commit('commit 2')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
348
        tree_b = tree_a.controldir.sprout('b').open_workingtree()
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
349
        tree_b.rename_one('file_1', 'renamed')
4961.2.9 by Martin Pool
Rip out most remaining uses of DummyProgressBar
350
        merger = _mod_merge.Merger.from_uncommitted(tree_a, tree_b)
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
351
        merger.merge_type = _mod_merge.WeaveMerger
352
        merger.do_merge()
353
        self.assertEqual(tree_a.get_parent_ids(), [tree_b.last_revision()])
354
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
355
    def prepare_cherrypick(self):
3062.2.13 by Aaron Bentley
Update prepare_cherrypick docstring
356
        """Prepare a pair of trees for cherrypicking tests.
357
358
        Both trees have a file, 'file'.
359
        rev1 sets content to 'a'.
360
        rev2b adds 'b'.
361
        rev3b adds 'c'.
362
        A full merge of rev2b and rev3b into this_tree would add both 'b' and
363
        'c'.  A successful cherrypick of rev2b-rev3b into this_tree will add
364
        'c', but not 'b'.
365
        """
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
366
        this_tree = self.make_branch_and_tree('this')
6855.4.1 by Jelmer Vernooij
Yet more bees.
367
        self.build_tree_contents([('this/file', b"a\n")])
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
368
        this_tree.add('file')
369
        this_tree.commit('rev1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
370
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
371
        self.build_tree_contents([('other/file', b"a\nb\n")])
372
        other_tree.commit('rev2b', rev_id=b'rev2b')
373
        self.build_tree_contents([('other/file', b"c\na\nb\n")])
374
        other_tree.commit('rev3b', rev_id=b'rev3b')
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
375
        this_tree.lock_write()
376
        self.addCleanup(this_tree.unlock)
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
377
        return this_tree, other_tree
378
379
    def test_weave_cherrypick(self):
380
        this_tree, other_tree = self.prepare_cherrypick()
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
381
        merger = _mod_merge.Merger.from_revision_ids(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
382
            this_tree, b'rev3b', b'rev2b', other_tree.branch)
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
383
        merger.merge_type = _mod_merge.WeaveMerger
384
        merger.do_merge()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
385
        self.assertFileEqual(b'c\na\n', 'this/file')
3062.2.6 by Aaron Bentley
Get cherrypick-on-weave working
386
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
387
    def test_weave_cannot_reverse_cherrypick(self):
388
        this_tree, other_tree = self.prepare_cherrypick()
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
389
        merger = _mod_merge.Merger.from_revision_ids(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
390
            this_tree, b'rev2b', b'rev3b', other_tree.branch)
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
391
        merger.merge_type = _mod_merge.WeaveMerger
392
        self.assertRaises(errors.CannotReverseCherrypick, merger.do_merge)
393
394
    def test_merge3_can_reverse_cherrypick(self):
395
        this_tree, other_tree = self.prepare_cherrypick()
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
396
        merger = _mod_merge.Merger.from_revision_ids(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
397
            this_tree, b'rev2b', b'rev3b', other_tree.branch)
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
398
        merger.merge_type = _mod_merge.Merge3Merger
399
        merger.do_merge()
400
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
401
    def test_merge3_will_detect_cherrypick(self):
402
        this_tree = self.make_branch_and_tree('this')
6855.4.1 by Jelmer Vernooij
Yet more bees.
403
        self.build_tree_contents([('this/file', b"a\n")])
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
404
        this_tree.add('file')
405
        this_tree.commit('rev1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
406
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
407
        self.build_tree_contents([('other/file', b"a\nb\n")])
408
        other_tree.commit('rev2b', rev_id=b'rev2b')
409
        self.build_tree_contents([('other/file', b"a\nb\nc\n")])
410
        other_tree.commit('rev3b', rev_id=b'rev3b')
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
411
        this_tree.lock_write()
412
        self.addCleanup(this_tree.unlock)
413
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
414
        merger = _mod_merge.Merger.from_revision_ids(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
415
            this_tree, b'rev3b', b'rev2b', other_tree.branch)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
416
        merger.merge_type = _mod_merge.Merge3Merger
417
        merger.do_merge()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
418
        self.assertFileEqual(b'a\n'
419
                             b'<<<<<<< TREE\n'
420
                             b'=======\n'
421
                             b'c\n'
422
                             b'>>>>>>> MERGE-SOURCE\n',
6973.11.9 by Jelmer Vernooij
Fix tests.
423
                             'this/file')
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
424
5954.4.2 by Aaron Bentley
Support merging into null tree.
425
    def test_merge_reverse_revision_range(self):
426
        tree = self.make_branch_and_tree(".")
427
        tree.lock_write()
428
        self.addCleanup(tree.unlock)
429
        self.build_tree(['a'])
430
        tree.add('a')
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
431
        first_rev = tree.commit("added a")
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
432
        merger = _mod_merge.Merger.from_revision_ids(tree,
7143.15.2 by Jelmer Vernooij
Run autopep8.
433
                                                     _mod_revision.NULL_REVISION,
434
                                                     first_rev)
5954.4.2 by Aaron Bentley
Support merging into null tree.
435
        merger.merge_type = _mod_merge.Merge3Merger
436
        merger.interesting_files = 'a'
437
        conflict_count = merger.do_merge()
438
        self.assertEqual(0, conflict_count)
439
440
        self.assertPathDoesNotExist("a")
441
        tree.revert()
442
        self.assertPathExists("a")
443
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
444
    def test_make_merger(self):
445
        this_tree = self.make_branch_and_tree('this')
6855.4.1 by Jelmer Vernooij
Yet more bees.
446
        this_tree.commit('rev1', rev_id=b'rev1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
447
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
448
        this_tree.commit('rev2', rev_id=b'rev2a')
449
        other_tree.commit('rev2', rev_id=b'rev2b')
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
450
        this_tree.lock_write()
451
        self.addCleanup(this_tree.unlock)
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
452
        merger = _mod_merge.Merger.from_revision_ids(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
453
            this_tree, b'rev2b', other_branch=other_tree.branch)
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
454
        merger.merge_type = _mod_merge.Merge3Merger
455
        tree_merger = merger.make_merger()
456
        self.assertIs(_mod_merge.Merge3Merger, tree_merger.__class__)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
457
        self.assertEqual(b'rev2b',
7143.15.2 by Jelmer Vernooij
Run autopep8.
458
                         tree_merger.other_tree.get_revision_id())
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
459
        self.assertEqual(b'rev1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
460
                         tree_merger.base_tree.get_revision_id())
6410.1.1 by Jelmer Vernooij
Add other_branch argument to Merge3Merger.
461
        self.assertEqual(other_tree.branch, tree_merger.other_branch)
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
462
463
    def test_make_preview_transform(self):
464
        this_tree = self.make_branch_and_tree('this')
6855.4.1 by Jelmer Vernooij
Yet more bees.
465
        self.build_tree_contents([('this/file', b'1\n')])
466
        this_tree.add('file', b'file-id')
467
        this_tree.commit('rev1', rev_id=b'rev1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
468
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
469
        self.build_tree_contents([('this/file', b'1\n2a\n')])
470
        this_tree.commit('rev2', rev_id=b'rev2a')
471
        self.build_tree_contents([('other/file', b'2b\n1\n')])
472
        other_tree.commit('rev2', rev_id=b'rev2b')
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
473
        this_tree.lock_write()
474
        self.addCleanup(this_tree.unlock)
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
475
        merger = _mod_merge.Merger.from_revision_ids(
6855.4.1 by Jelmer Vernooij
Yet more bees.
476
            this_tree, b'rev2b', other_branch=other_tree.branch)
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
477
        merger.merge_type = _mod_merge.Merge3Merger
478
        tree_merger = merger.make_merger()
7350.3.4 by Jelmer Vernooij
Use context managers.
479
        with tree_merger.make_preview_transform() as tt:
480
            preview_tree = tt.get_preview_tree()
481
            with this_tree.get_file('file') as tree_file:
482
                self.assertEqual(b'1\n2a\n', tree_file.read())
483
            with preview_tree.get_file('file') as preview_file:
484
                self.assertEqual(b'2b\n1\n2a\n', preview_file.read())
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
485
3008.1.22 by Aaron Bentley
Get do_merge under test
486
    def test_do_merge(self):
487
        this_tree = self.make_branch_and_tree('this')
6855.4.1 by Jelmer Vernooij
Yet more bees.
488
        self.build_tree_contents([('this/file', b'1\n')])
489
        this_tree.add('file', b'file-id')
490
        this_tree.commit('rev1', rev_id=b'rev1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
491
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
492
        self.build_tree_contents([('this/file', b'1\n2a\n')])
493
        this_tree.commit('rev2', rev_id=b'rev2a')
494
        self.build_tree_contents([('other/file', b'2b\n1\n')])
495
        other_tree.commit('rev2', rev_id=b'rev2b')
3008.1.22 by Aaron Bentley
Get do_merge under test
496
        this_tree.lock_write()
497
        self.addCleanup(this_tree.unlock)
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
498
        merger = _mod_merge.Merger.from_revision_ids(
6855.4.1 by Jelmer Vernooij
Yet more bees.
499
            this_tree, b'rev2b', other_branch=other_tree.branch)
3008.1.22 by Aaron Bentley
Get do_merge under test
500
        merger.merge_type = _mod_merge.Merge3Merger
501
        tree_merger = merger.make_merger()
502
        tt = tree_merger.do_merge()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
503
        with this_tree.get_file('file') as tree_file:
504
            self.assertEqual(b'2b\n1\n2a\n', tree_file.read())
3008.1.22 by Aaron Bentley
Get do_merge under test
505
5993.2.3 by Jelmer Vernooij
Update NEWS, consistently use require_tree_root as argument everywhere.
506
    def test_merge_require_tree_root(self):
5993.2.2 by Jelmer Vernooij
Fix fixing up root ids.
507
        tree = self.make_branch_and_tree(".")
508
        tree.lock_write()
509
        self.addCleanup(tree.unlock)
510
        self.build_tree(['a'])
511
        tree.add('a')
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
512
        first_rev = tree.commit("added a")
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
513
        old_root_id = tree.path2id('')
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
514
        merger = _mod_merge.Merger.from_revision_ids(tree,
7143.15.2 by Jelmer Vernooij
Run autopep8.
515
                                                     _mod_revision.NULL_REVISION,
516
                                                     first_rev)
5993.2.2 by Jelmer Vernooij
Fix fixing up root ids.
517
        merger.merge_type = _mod_merge.Merge3Merger
518
        conflict_count = merger.do_merge()
519
        self.assertEqual(0, conflict_count)
6825.5.1 by Jelmer Vernooij
Implement Tree.all_versioned_paths.
520
        self.assertEqual({''}, set(tree.all_versioned_paths()))
5993.2.2 by Jelmer Vernooij
Fix fixing up root ids.
521
        tree.set_parent_ids([])
522
1551.19.32 by Aaron Bentley
Don't traceback when adding files to a deleted root (abentley, #210092)
523
    def test_merge_add_into_deleted_root(self):
524
        # Yes, people actually do this.  And report bugs if it breaks.
525
        source = self.make_branch_and_tree('source', format='rich-root-pack')
526
        self.build_tree(['source/foo/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
527
        source.add('foo', b'foo-id')
1551.19.32 by Aaron Bentley
Don't traceback when adding files to a deleted root (abentley, #210092)
528
        source.commit('Add foo')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
529
        target = source.controldir.sprout('target').open_workingtree()
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
530
        subtree = target.extract('foo')
1551.19.32 by Aaron Bentley
Don't traceback when adding files to a deleted root (abentley, #210092)
531
        subtree.commit('Delete root')
532
        self.build_tree(['source/bar'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
533
        source.add('bar', b'bar-id')
1551.19.32 by Aaron Bentley
Don't traceback when adding files to a deleted root (abentley, #210092)
534
        source.commit('Add bar')
535
        subtree.merge_from_branch(source.branch)
536
3649.3.1 by Jelmer Vernooij
Merging from a previously joined branch will no longer cause a traceback.
537
    def test_merge_joined_branch(self):
538
        source = self.make_branch_and_tree('source', format='rich-root-pack')
539
        self.build_tree(['source/foo'])
540
        source.add('foo')
541
        source.commit('Add foo')
542
        target = self.make_branch_and_tree('target', format='rich-root-pack')
543
        self.build_tree(['target/bla'])
544
        target.add('bla')
545
        target.commit('Add bla')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
546
        nested = source.controldir.sprout('target/subtree').open_workingtree()
3649.3.1 by Jelmer Vernooij
Merging from a previously joined branch will no longer cause a traceback.
547
        target.subsume(nested)
548
        target.commit('Join nested')
549
        self.build_tree(['source/bar'])
550
        source.add('bar')
551
        source.commit('Add bar')
552
        target.merge_from_branch(source.branch)
553
        target.commit('Merge source')
554
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
555
556
class TestPlanMerge(TestCaseWithMemoryTransport):
557
558
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
559
        super(TestPlanMerge, self).setUp()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
560
        mapper = versionedfile.PrefixMapper()
561
        factory = knit.make_file_factory(True, mapper)
562
        self.vf = factory(self.get_transport())
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
563
        self.plan_merge_vf = versionedfile._PlanMergeVersionedFile(b'root')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
564
        self.plan_merge_vf.fallback_versionedfiles.append(self.vf)
565
566
    def add_version(self, key, parents, text):
7479.2.1 by Jelmer Vernooij
Drop python2 support.
567
        self.vf.add_lines(
568
            key, parents, [bytes([c]) + b'\n' for c in bytearray(text)])
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
569
3514.2.10 by John Arbash Meinel
Handle more edge cases.
570
    def add_rev(self, prefix, revision_id, parents, text):
571
        self.add_version((prefix, revision_id), [(prefix, p) for p in parents],
572
                         text)
573
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
574
    def add_uncommitted_version(self, key, parents, text):
575
        self.plan_merge_vf.add_lines(key, parents,
7479.2.1 by Jelmer Vernooij
Drop python2 support.
576
                                     [bytes([c]) + b'\n' for c in bytearray(text)])
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
577
578
    def setup_plan_merge(self):
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
579
        self.add_rev(b'root', b'A', [], b'abc')
580
        self.add_rev(b'root', b'B', [b'A'], b'acehg')
581
        self.add_rev(b'root', b'C', [b'A'], b'fabg')
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
582
        return _PlanMerge(b'B', b'C', self.plan_merge_vf, (b'root',))
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
583
584
    def setup_plan_merge_uncommitted(self):
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
585
        self.add_version((b'root', b'A'), [], b'abc')
7143.15.2 by Jelmer Vernooij
Run autopep8.
586
        self.add_uncommitted_version(
587
            (b'root', b'B:'), [(b'root', b'A')], b'acehg')
588
        self.add_uncommitted_version(
589
            (b'root', b'C:'), [(b'root', b'A')], b'fabg')
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
590
        return _PlanMerge(b'B:', b'C:', self.plan_merge_vf, (b'root',))
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
591
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
592
    def test_base_from_plan(self):
593
        self.setup_plan_merge()
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
594
        plan = self.plan_merge_vf.plan_merge(b'B', b'C')
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
595
        pwm = versionedfile.PlanWeaveMerge(plan)
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
596
        self.assertEqual([b'a\n', b'b\n', b'c\n'], pwm.base_from_plan())
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
597
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
598
    def test_unique_lines(self):
599
        plan = self.setup_plan_merge()
600
        self.assertEqual(plan._unique_lines(
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
601
            plan._get_matching_blocks(b'B', b'C')),
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
602
            ([1, 2, 3], [0, 2]))
603
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
604
    def test_plan_merge(self):
605
        self.setup_plan_merge()
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
606
        plan = self.plan_merge_vf.plan_merge(b'B', b'C')
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
607
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
608
            ('new-b', b'f\n'),
609
            ('unchanged', b'a\n'),
610
            ('killed-a', b'b\n'),
611
            ('killed-b', b'c\n'),
612
            ('new-a', b'e\n'),
613
            ('new-a', b'h\n'),
614
            ('new-a', b'g\n'),
615
            ('new-b', b'g\n')],
616
            list(plan))
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
617
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
618
    def test_plan_merge_cherrypick(self):
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
619
        self.add_rev(b'root', b'A', [], b'abc')
620
        self.add_rev(b'root', b'B', [b'A'], b'abcde')
621
        self.add_rev(b'root', b'C', [b'A'], b'abcefg')
622
        self.add_rev(b'root', b'D', [b'A', b'B', b'C'], b'abcdegh')
623
        my_plan = _PlanMerge(b'B', b'D', self.plan_merge_vf, (b'root',))
3514.2.11 by John Arbash Meinel
Shortcut the case when one revision is in the ancestry of the other.
624
        # We shortcut when one text supersedes the other in the per-file graph.
625
        # We don't actually need to compare the texts at this point.
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
626
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
627
            ('new-b', b'a\n'),
628
            ('new-b', b'b\n'),
629
            ('new-b', b'c\n'),
630
            ('new-b', b'd\n'),
631
            ('new-b', b'e\n'),
632
            ('new-b', b'g\n'),
633
            ('new-b', b'h\n')],
634
            list(my_plan.plan_merge()))
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
635
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
636
    def test_plan_merge_no_common_ancestor(self):
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
637
        self.add_rev(b'root', b'A', [], b'abc')
638
        self.add_rev(b'root', b'B', [], b'xyz')
639
        my_plan = _PlanMerge(b'A', b'B', self.plan_merge_vf, (b'root',))
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
640
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
641
            ('new-a', b'a\n'),
642
            ('new-a', b'b\n'),
643
            ('new-a', b'c\n'),
644
            ('new-b', b'x\n'),
645
            ('new-b', b'y\n'),
646
            ('new-b', b'z\n')],
647
            list(my_plan.plan_merge()))
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
648
3514.2.10 by John Arbash Meinel
Handle more edge cases.
649
    def test_plan_merge_tail_ancestors(self):
650
        # The graph looks like this:
651
        #       A       # Common to all ancestors
652
        #      / \
653
        #     B   C     # Ancestors of E, only common to one side
654
        #     |\ /|
655
        #     D E F     # D, F are unique to G, H respectively
656
        #     |/ \|     # E is the LCA for G & H, and the unique LCA for
657
        #     G   H     # I, J
658
        #     |\ /|
659
        #     | X |
660
        #     |/ \|
661
        #     I   J     # criss-cross merge of G, H
662
        #
663
        # In this situation, a simple pruning of ancestors of E will leave D &
664
        # F "dangling", which looks like they introduce lines different from
665
        # the ones in E, but in actuality C&B introduced the lines, and they
666
        # are already present in E
667
668
        # Introduce the base text
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
669
        self.add_rev(b'root', b'A', [], b'abc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
670
        # Introduces a new line B
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
671
        self.add_rev(b'root', b'B', [b'A'], b'aBbc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
672
        # Introduces a new line C
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
673
        self.add_rev(b'root', b'C', [b'A'], b'abCc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
674
        # Introduce new line D
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
675
        self.add_rev(b'root', b'D', [b'B'], b'DaBbc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
676
        # Merges B and C by just incorporating both
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
677
        self.add_rev(b'root', b'E', [b'B', b'C'], b'aBbCc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
678
        # Introduce new line F
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
679
        self.add_rev(b'root', b'F', [b'C'], b'abCcF')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
680
        # Merge D & E by just combining the texts
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
681
        self.add_rev(b'root', b'G', [b'D', b'E'], b'DaBbCc')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
682
        # Merge F & E by just combining the texts
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
683
        self.add_rev(b'root', b'H', [b'F', b'E'], b'aBbCcF')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
684
        # Merge G & H by just combining texts
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
685
        self.add_rev(b'root', b'I', [b'G', b'H'], b'DaBbCcF')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
686
        # Merge G & H but supersede an old line in B
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
687
        self.add_rev(b'root', b'J', [b'H', b'G'], b'DaJbCcF')
688
        plan = self.plan_merge_vf.plan_merge(b'I', b'J')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
689
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
690
            ('unchanged', b'D\n'),
691
            ('unchanged', b'a\n'),
692
            ('killed-b', b'B\n'),
693
            ('new-b', b'J\n'),
694
            ('unchanged', b'b\n'),
695
            ('unchanged', b'C\n'),
696
            ('unchanged', b'c\n'),
697
            ('unchanged', b'F\n')],
698
            list(plan))
3514.2.10 by John Arbash Meinel
Handle more edge cases.
699
700
    def test_plan_merge_tail_triple_ancestors(self):
701
        # The graph looks like this:
702
        #       A       # Common to all ancestors
703
        #      / \
704
        #     B   C     # Ancestors of E, only common to one side
705
        #     |\ /|
706
        #     D E F     # D, F are unique to G, H respectively
707
        #     |/|\|     # E is the LCA for G & H, and the unique LCA for
708
        #     G Q H     # I, J
709
        #     |\ /|     # Q is just an extra node which is merged into both
710
        #     | X |     # I and J
711
        #     |/ \|
712
        #     I   J     # criss-cross merge of G, H
713
        #
714
        # This is the same as the test_plan_merge_tail_ancestors, except we add
715
        # a third LCA that doesn't add new lines, but will trigger our more
716
        # involved ancestry logic
717
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
718
        self.add_rev(b'root', b'A', [], b'abc')
719
        self.add_rev(b'root', b'B', [b'A'], b'aBbc')
720
        self.add_rev(b'root', b'C', [b'A'], b'abCc')
721
        self.add_rev(b'root', b'D', [b'B'], b'DaBbc')
722
        self.add_rev(b'root', b'E', [b'B', b'C'], b'aBbCc')
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
723
        self.add_rev(b'root', b'F', [b'C'], b'abCcF')
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
724
        self.add_rev(b'root', b'G', [b'D', b'E'], b'DaBbCc')
725
        self.add_rev(b'root', b'H', [b'F', b'E'], b'aBbCcF')
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
726
        self.add_rev(b'root', b'Q', [b'E'], b'aBbCc')
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
727
        self.add_rev(b'root', b'I', [b'G', b'Q', b'H'], b'DaBbCcF')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
728
        # Merge G & H but supersede an old line in B
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
729
        self.add_rev(b'root', b'J', [b'H', b'Q', b'G'], b'DaJbCcF')
730
        plan = self.plan_merge_vf.plan_merge(b'I', b'J')
3514.2.10 by John Arbash Meinel
Handle more edge cases.
731
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
732
            ('unchanged', b'D\n'),
733
            ('unchanged', b'a\n'),
734
            ('killed-b', b'B\n'),
735
            ('new-b', b'J\n'),
736
            ('unchanged', b'b\n'),
737
            ('unchanged', b'C\n'),
738
            ('unchanged', b'c\n'),
739
            ('unchanged', b'F\n')],
740
            list(plan))
3514.2.10 by John Arbash Meinel
Handle more edge cases.
741
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
742
    def test_plan_merge_2_tail_triple_ancestors(self):
743
        # The graph looks like this:
744
        #     A   B     # 2 tails going back to NULL
745
        #     |\ /|
746
        #     D E F     # D, is unique to G, F to H
747
        #     |/|\|     # E is the LCA for G & H, and the unique LCA for
748
        #     G Q H     # I, J
749
        #     |\ /|     # Q is just an extra node which is merged into both
750
        #     | X |     # I and J
751
        #     |/ \|
752
        #     I   J     # criss-cross merge of G, H (and Q)
753
        #
754
755
        # This is meant to test after hitting a 3-way LCA, and multiple tail
756
        # ancestors (only have NULL_REVISION in common)
757
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
758
        self.add_rev(b'root', b'A', [], b'abc')
759
        self.add_rev(b'root', b'B', [], b'def')
760
        self.add_rev(b'root', b'D', [b'A'], b'Dabc')
761
        self.add_rev(b'root', b'E', [b'A', b'B'], b'abcdef')
762
        self.add_rev(b'root', b'F', [b'B'], b'defF')
763
        self.add_rev(b'root', b'G', [b'D', b'E'], b'Dabcdef')
764
        self.add_rev(b'root', b'H', [b'F', b'E'], b'abcdefF')
765
        self.add_rev(b'root', b'Q', [b'E'], b'abcdef')
766
        self.add_rev(b'root', b'I', [b'G', b'Q', b'H'], b'DabcdefF')
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
767
        # Merge G & H but supersede an old line in B
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
768
        self.add_rev(b'root', b'J', [b'H', b'Q', b'G'], b'DabcdJfF')
769
        plan = self.plan_merge_vf.plan_merge(b'I', b'J')
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
770
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
771
            ('unchanged', b'D\n'),
772
            ('unchanged', b'a\n'),
773
            ('unchanged', b'b\n'),
774
            ('unchanged', b'c\n'),
775
            ('unchanged', b'd\n'),
776
            ('killed-b', b'e\n'),
777
            ('new-b', b'J\n'),
778
            ('unchanged', b'f\n'),
779
            ('unchanged', b'F\n')],
780
            list(plan))
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
781
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
782
    def test_plan_merge_uncommitted_files(self):
3062.1.13 by Aaron Bentley
Make _PlanMerge an implementation detail of _PlanMergeVersionedFile
783
        self.setup_plan_merge_uncommitted()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
784
        plan = self.plan_merge_vf.plan_merge(b'B:', b'C:')
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
785
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
786
            ('new-b', b'f\n'),
787
            ('unchanged', b'a\n'),
788
            ('killed-a', b'b\n'),
789
            ('killed-b', b'c\n'),
790
            ('new-a', b'e\n'),
791
            ('new-a', b'h\n'),
792
            ('new-a', b'g\n'),
793
            ('new-b', b'g\n')],
794
            list(plan))
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
795
796
    def test_plan_merge_insert_order(self):
797
        """Weave merges are sensitive to the order of insertion.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
798
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
799
        Specifically for overlapping regions, it effects which region gets put
800
        'first'. And when a user resolves an overlapping merge, if they use the
801
        same ordering, then the lines match the parents, if they don't only
802
        *some* of the lines match.
803
        """
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
804
        self.add_rev(b'root', b'A', [], b'abcdef')
805
        self.add_rev(b'root', b'B', [b'A'], b'abwxcdef')
806
        self.add_rev(b'root', b'C', [b'A'], b'abyzcdef')
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
807
        # Merge, and resolve the conflict by adding *both* sets of lines
808
        # If we get the ordering wrong, these will look like new lines in D,
809
        # rather than carried over from B, C
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
810
        self.add_rev(b'root', b'D', [b'B', b'C'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
811
                     b'abwxyzcdef')
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
812
        # Supersede the lines in B and delete the lines in C, which will
813
        # conflict if they are treated as being in D
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
814
        self.add_rev(b'root', b'E', [b'C', b'B'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
815
                     b'abnocdef')
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
816
        # Same thing for the lines in C
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
817
        self.add_rev(b'root', b'F', [b'C'], b'abpqcdef')
818
        plan = self.plan_merge_vf.plan_merge(b'D', b'E')
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
819
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
820
            ('unchanged', b'a\n'),
821
            ('unchanged', b'b\n'),
822
            ('killed-b', b'w\n'),
823
            ('killed-b', b'x\n'),
824
            ('killed-b', b'y\n'),
825
            ('killed-b', b'z\n'),
826
            ('new-b', b'n\n'),
827
            ('new-b', b'o\n'),
828
            ('unchanged', b'c\n'),
829
            ('unchanged', b'd\n'),
830
            ('unchanged', b'e\n'),
831
            ('unchanged', b'f\n')],
832
            list(plan))
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
833
        plan = self.plan_merge_vf.plan_merge(b'E', b'D')
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
834
        # Going in the opposite direction shows the effect of the opposite plan
835
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
836
            ('unchanged', b'a\n'),
837
            ('unchanged', b'b\n'),
838
            ('new-b', b'w\n'),
839
            ('new-b', b'x\n'),
840
            ('killed-a', b'y\n'),
841
            ('killed-a', b'z\n'),
842
            ('killed-both', b'w\n'),
843
            ('killed-both', b'x\n'),
844
            ('new-a', b'n\n'),
845
            ('new-a', b'o\n'),
846
            ('unchanged', b'c\n'),
847
            ('unchanged', b'd\n'),
848
            ('unchanged', b'e\n'),
849
            ('unchanged', b'f\n')],
850
            list(plan))
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
851
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
852
    def test_plan_merge_criss_cross(self):
853
        # This is specificly trying to trigger problems when using limited
854
        # ancestry and weaves. The ancestry graph looks like:
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
855
        #       XX      unused ancestor, should not show up in the weave
856
        #       |
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
857
        #       A       Unique LCA
858
        #       |\
859
        #       B \     Introduces a line 'foo'
860
        #      / \ \
861
        #     C   D E   C & D both have 'foo', E has different changes
862
        #     |\ /| |
863
        #     | X | |
864
        #     |/ \|/
865
        #     F   G      All of C, D, E are merged into F and G, so they are
866
        #                all common ancestors.
867
        #
868
        # The specific issue with weaves:
869
        #   B introduced a text ('foo') that is present in both C and D.
870
        #   If we do not include B (because it isn't an ancestor of E), then
871
        #   the A=>C and A=>D look like both sides independently introduce the
872
        #   text ('foo'). If F does not modify the text, it would still appear
873
        #   to have deleted on of the versions from C or D. If G then modifies
874
        #   'foo', it should appear as superseding the value in F (since it
875
        #   came from B), rather than conflict because of the resolution during
876
        #   C & D.
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
877
        self.add_rev(b'root', b'XX', [], b'qrs')
878
        self.add_rev(b'root', b'A', [b'XX'], b'abcdef')
879
        self.add_rev(b'root', b'B', [b'A'], b'axcdef')
880
        self.add_rev(b'root', b'C', [b'B'], b'axcdefg')
881
        self.add_rev(b'root', b'D', [b'B'], b'haxcdef')
882
        self.add_rev(b'root', b'E', [b'A'], b'abcdyf')
3514.2.17 by John Arbash Meinel
On Ian's suggestion, change the 'plan_merge' tests to use the clearer 'add_rev' instead of 'add_version'
883
        # Simple combining of all texts
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
884
        self.add_rev(b'root', b'F', [b'C', b'D', b'E'], b'haxcdyfg')
3514.2.17 by John Arbash Meinel
On Ian's suggestion, change the 'plan_merge' tests to use the clearer 'add_rev' instead of 'add_version'
885
        # combine and supersede 'x'
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
886
        self.add_rev(b'root', b'G', [b'C', b'D', b'E'], b'hazcdyfg')
887
        plan = self.plan_merge_vf.plan_merge(b'F', b'G')
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
888
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
889
            ('unchanged', b'h\n'),
890
            ('unchanged', b'a\n'),
891
            ('killed-base', b'b\n'),
892
            ('killed-b', b'x\n'),
893
            ('new-b', b'z\n'),
894
            ('unchanged', b'c\n'),
895
            ('unchanged', b'd\n'),
896
            ('killed-base', b'e\n'),
897
            ('unchanged', b'y\n'),
898
            ('unchanged', b'f\n'),
899
            ('unchanged', b'g\n')],
900
            list(plan))
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
901
        plan = self.plan_merge_vf.plan_lca_merge(b'F', b'G')
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
902
        # This is one of the main differences between plan_merge and
903
        # plan_lca_merge. plan_lca_merge generates a conflict for 'x => z',
904
        # because 'x' was not present in one of the bases. However, in this
905
        # case it is spurious because 'x' does not exist in the global base A.
906
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
907
            ('unchanged', b'h\n'),
908
            ('unchanged', b'a\n'),
909
            ('conflicted-a', b'x\n'),
910
            ('new-b', b'z\n'),
911
            ('unchanged', b'c\n'),
912
            ('unchanged', b'd\n'),
913
            ('unchanged', b'y\n'),
914
            ('unchanged', b'f\n'),
915
            ('unchanged', b'g\n')],
916
            list(plan))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
917
918
    def test_criss_cross_flip_flop(self):
919
        # This is specificly trying to trigger problems when using limited
920
        # ancestry and weaves. The ancestry graph looks like:
921
        #       XX      unused ancestor, should not show up in the weave
922
        #       |
923
        #       A       Unique LCA
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
924
        #      / \
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
925
        #     B   C     B & C both introduce a new line
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
926
        #     |\ /|
927
        #     | X |
928
        #     |/ \|
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
929
        #     D   E     B & C are both merged, so both are common ancestors
930
        #               In the process of merging, both sides order the new
931
        #               lines differently
932
        #
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
933
        self.add_rev(b'root', b'XX', [], b'qrs')
934
        self.add_rev(b'root', b'A', [b'XX'], b'abcdef')
935
        self.add_rev(b'root', b'B', [b'A'], b'abcdgef')
936
        self.add_rev(b'root', b'C', [b'A'], b'abcdhef')
937
        self.add_rev(b'root', b'D', [b'B', b'C'], b'abcdghef')
938
        self.add_rev(b'root', b'E', [b'C', b'B'], b'abcdhgef')
939
        plan = list(self.plan_merge_vf.plan_merge(b'D', b'E'))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
940
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
941
            ('unchanged', b'a\n'),
942
            ('unchanged', b'b\n'),
943
            ('unchanged', b'c\n'),
944
            ('unchanged', b'd\n'),
945
            ('new-b', b'h\n'),
946
            ('unchanged', b'g\n'),
947
            ('killed-b', b'h\n'),
948
            ('unchanged', b'e\n'),
949
            ('unchanged', b'f\n'),
950
            ], plan)
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
951
        pwm = versionedfile.PlanWeaveMerge(plan)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
952
        self.assertEqualDiff(b'a\nb\nc\nd\ng\nh\ne\nf\n',
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
953
                             b''.join(pwm.base_from_plan()))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
954
        # Reversing the order reverses the merge plan, and final order of 'hg'
955
        # => 'gh'
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
956
        plan = list(self.plan_merge_vf.plan_merge(b'E', b'D'))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
957
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
958
            ('unchanged', b'a\n'),
959
            ('unchanged', b'b\n'),
960
            ('unchanged', b'c\n'),
961
            ('unchanged', b'd\n'),
962
            ('new-b', b'g\n'),
963
            ('unchanged', b'h\n'),
964
            ('killed-b', b'g\n'),
965
            ('unchanged', b'e\n'),
966
            ('unchanged', b'f\n'),
967
            ], plan)
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
968
        pwm = versionedfile.PlanWeaveMerge(plan)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
969
        self.assertEqualDiff(b'a\nb\nc\nd\nh\ng\ne\nf\n',
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
970
                             b''.join(pwm.base_from_plan()))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
971
        # This is where lca differs, in that it (fairly correctly) determines
972
        # that there is a conflict because both sides resolved the merge
973
        # differently
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
974
        plan = list(self.plan_merge_vf.plan_lca_merge(b'D', b'E'))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
975
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
976
            ('unchanged', b'a\n'),
977
            ('unchanged', b'b\n'),
978
            ('unchanged', b'c\n'),
979
            ('unchanged', b'd\n'),
980
            ('conflicted-b', b'h\n'),
981
            ('unchanged', b'g\n'),
982
            ('conflicted-a', b'h\n'),
983
            ('unchanged', b'e\n'),
984
            ('unchanged', b'f\n'),
985
            ], plan)
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
986
        pwm = versionedfile.PlanWeaveMerge(plan)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
987
        self.assertEqualDiff(b'a\nb\nc\nd\ng\ne\nf\n',
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
988
                             b''.join(pwm.base_from_plan()))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
989
        # Reversing it changes what line is doubled, but still gives a
990
        # double-conflict
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
991
        plan = list(self.plan_merge_vf.plan_lca_merge(b'E', b'D'))
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
992
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
993
            ('unchanged', b'a\n'),
994
            ('unchanged', b'b\n'),
995
            ('unchanged', b'c\n'),
996
            ('unchanged', b'd\n'),
997
            ('conflicted-b', b'g\n'),
998
            ('unchanged', b'h\n'),
999
            ('conflicted-a', b'g\n'),
1000
            ('unchanged', b'e\n'),
1001
            ('unchanged', b'f\n'),
1002
            ], plan)
4634.101.8 by John Arbash Meinel
Add the criss-cross flip-flop 'bug' for weave merge.
1003
        pwm = versionedfile.PlanWeaveMerge(plan)
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
1004
        self.assertEqualDiff(b'a\nb\nc\nd\nh\ne\nf\n',
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1005
                             b''.join(pwm.base_from_plan()))
3514.2.6 by John Arbash Meinel
Write a (failing) test for complex ancestry.
1006
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1007
    def assertRemoveExternalReferences(self, filtered_parent_map,
1008
                                       child_map, tails, parent_map):
1009
        """Assert results for _PlanMerge._remove_external_references."""
1010
        (act_filtered_parent_map, act_child_map,
1011
         act_tails) = _PlanMerge._remove_external_references(parent_map)
1012
1013
        # The parent map *should* preserve ordering, but the ordering of
1014
        # children is not strictly defined
1015
        # child_map = dict((k, sorted(children))
1016
        #                  for k, children in child_map.iteritems())
1017
        # act_child_map = dict(k, sorted(children)
1018
        #                      for k, children in act_child_map.iteritems())
1019
        self.assertEqual(filtered_parent_map, act_filtered_parent_map)
1020
        self.assertEqual(child_map, act_child_map)
1021
        self.assertEqual(sorted(tails), sorted(act_tails))
1022
1023
    def test__remove_external_references(self):
1024
        # First, nothing to remove
1025
        self.assertRemoveExternalReferences({3: [2], 2: [1], 1: []},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1026
                                            {1: [2], 2: [3], 3: []}, [1], {3: [2], 2: [1], 1: []})
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1027
        # The reverse direction
1028
        self.assertRemoveExternalReferences({1: [2], 2: [3], 3: []},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1029
                                            {3: [2], 2: [1], 1: []}, [3], {1: [2], 2: [3], 3: []})
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1030
        # Extra references
1031
        self.assertRemoveExternalReferences({3: [2], 2: [1], 1: []},
7143.15.2 by Jelmer Vernooij
Run autopep8.
1032
                                            {1: [2], 2: [3], 3: []}, [1], {3: [2, 4], 2: [1, 5], 1: [6]})
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1033
        # Multiple tails
1034
        self.assertRemoveExternalReferences(
1035
            {4: [2, 3], 3: [], 2: [1], 1: []},
1036
            {1: [2], 2: [4], 3: [4], 4: []},
1037
            [1, 3],
1038
            {4: [2, 3], 3: [5], 2: [1], 1: [6]})
1039
        # Multiple children
1040
        self.assertRemoveExternalReferences(
1041
            {1: [3], 2: [3, 4], 3: [], 4: []},
1042
            {1: [], 2: [], 3: [1, 2], 4: [2]},
1043
            [3, 4],
1044
            {1: [3], 2: [3, 4], 3: [5], 4: []})
1045
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1046
    def assertPruneTails(self, pruned_map, tails, parent_map):
1047
        child_map = {}
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
1048
        for key, parent_keys in parent_map.items():
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1049
            child_map.setdefault(key, [])
1050
            for pkey in parent_keys:
1051
                child_map.setdefault(pkey, []).append(key)
1052
        _PlanMerge._prune_tails(parent_map, child_map, tails)
1053
        self.assertEqual(pruned_map, parent_map)
1054
1055
    def test__prune_tails(self):
1056
        # Nothing requested to prune
1057
        self.assertPruneTails({1: [], 2: [], 3: []}, [],
1058
                              {1: [], 2: [], 3: []})
1059
        # Prune a single entry
1060
        self.assertPruneTails({1: [], 3: []}, [2],
1061
                              {1: [], 2: [], 3: []})
1062
        # Prune a chain
1063
        self.assertPruneTails({1: []}, [3],
1064
                              {1: [], 2: [3], 3: []})
1065
        # Prune a chain with a diamond
1066
        self.assertPruneTails({1: []}, [5],
1067
                              {1: [], 2: [3, 4], 3: [5], 4: [5], 5: []})
1068
        # Prune a partial chain
7143.15.2 by Jelmer Vernooij
Run autopep8.
1069
        self.assertPruneTails({1: [6], 6: []}, [5],
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1070
                              {1: [2, 6], 2: [3, 4], 3: [5], 4: [5], 5: [],
1071
                               6: []})
1072
        # Prune a chain with multiple tips, that pulls out intermediates
7143.15.2 by Jelmer Vernooij
Run autopep8.
1073
        self.assertPruneTails({1: [3], 3: []}, [4, 5],
1074
                              {1: [2, 3], 2: [4, 5], 3: [], 4: [], 5: []})
1075
        self.assertPruneTails({1: [3], 3: []}, [5, 4],
1076
                              {1: [2, 3], 2: [4, 5], 3: [], 4: [], 5: []})
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1077
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
1078
    def test_subtract_plans(self):
1079
        old_plan = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
1080
            ('unchanged', b'a\n'),
1081
            ('new-a', b'b\n'),
1082
            ('killed-a', b'c\n'),
1083
            ('new-b', b'd\n'),
1084
            ('new-b', b'e\n'),
1085
            ('killed-b', b'f\n'),
1086
            ('killed-b', b'g\n'),
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
1087
        ]
1088
        new_plan = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
1089
            ('unchanged', b'a\n'),
1090
            ('new-a', b'b\n'),
1091
            ('killed-a', b'c\n'),
1092
            ('new-b', b'd\n'),
1093
            ('new-b', b'h\n'),
1094
            ('killed-b', b'f\n'),
1095
            ('killed-b', b'i\n'),
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
1096
        ]
1097
        subtracted_plan = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
1098
            ('unchanged', b'a\n'),
1099
            ('new-a', b'b\n'),
1100
            ('killed-a', b'c\n'),
1101
            ('new-b', b'h\n'),
1102
            ('unchanged', b'f\n'),
1103
            ('killed-b', b'i\n'),
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
1104
        ]
1105
        self.assertEqual(subtracted_plan,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1106
                         list(_PlanMerge._subtract_plans(old_plan, new_plan)))
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
1107
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1108
    def setup_merge_with_base(self):
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1109
        self.add_rev(b'root', b'COMMON', [], b'abc')
1110
        self.add_rev(b'root', b'THIS', [b'COMMON'], b'abcd')
1111
        self.add_rev(b'root', b'BASE', [b'COMMON'], b'eabc')
1112
        self.add_rev(b'root', b'OTHER', [b'BASE'], b'eafb')
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1113
1114
    def test_plan_merge_with_base(self):
1115
        self.setup_merge_with_base()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1116
        plan = self.plan_merge_vf.plan_merge(b'THIS', b'OTHER', b'BASE')
1117
        self.assertEqual([('unchanged', b'a\n'),
1118
                          ('new-b', b'f\n'),
1119
                          ('unchanged', b'b\n'),
1120
                          ('killed-b', b'c\n'),
1121
                          ('new-a', b'd\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
1122
                          ], list(plan))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1123
1124
    def test_plan_lca_merge(self):
1125
        self.setup_plan_merge()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1126
        plan = self.plan_merge_vf.plan_lca_merge(b'B', b'C')
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1127
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
1128
            ('new-b', b'f\n'),
1129
            ('unchanged', b'a\n'),
1130
            ('killed-b', b'c\n'),
1131
            ('new-a', b'e\n'),
1132
            ('new-a', b'h\n'),
1133
            ('killed-a', b'b\n'),
1134
            ('unchanged', b'g\n')],
1135
            list(plan))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1136
1137
    def test_plan_lca_merge_uncommitted_files(self):
1138
        self.setup_plan_merge_uncommitted()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1139
        plan = self.plan_merge_vf.plan_lca_merge(b'B:', b'C:')
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1140
        self.assertEqual([
7143.15.2 by Jelmer Vernooij
Run autopep8.
1141
            ('new-b', b'f\n'),
1142
            ('unchanged', b'a\n'),
1143
            ('killed-b', b'c\n'),
1144
            ('new-a', b'e\n'),
1145
            ('new-a', b'h\n'),
1146
            ('killed-a', b'b\n'),
1147
            ('unchanged', b'g\n')],
1148
            list(plan))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1149
1150
    def test_plan_lca_merge_with_base(self):
1151
        self.setup_merge_with_base()
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1152
        plan = self.plan_merge_vf.plan_lca_merge(b'THIS', b'OTHER', b'BASE')
1153
        self.assertEqual([('unchanged', b'a\n'),
1154
                          ('new-b', b'f\n'),
1155
                          ('unchanged', b'b\n'),
1156
                          ('killed-b', b'c\n'),
1157
                          ('new-a', b'd\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
1158
                          ], list(plan))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1159
1160
    def test_plan_lca_merge_with_criss_cross(self):
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1161
        self.add_version((b'root', b'ROOT'), [], b'abc')
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1162
        # each side makes a change
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1163
        self.add_version((b'root', b'REV1'), [(b'root', b'ROOT')], b'abcd')
1164
        self.add_version((b'root', b'REV2'), [(b'root', b'ROOT')], b'abce')
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1165
        # both sides merge, discarding others' changes
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1166
        self.add_version((b'root', b'LCA1'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1167
                         [(b'root', b'REV1'), (b'root', b'REV2')], b'abcd')
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1168
        self.add_version((b'root', b'LCA2'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1169
                         [(b'root', b'REV1'), (b'root', b'REV2')], b'fabce')
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1170
        plan = self.plan_merge_vf.plan_lca_merge(b'LCA1', b'LCA2')
1171
        self.assertEqual([('new-b', b'f\n'),
1172
                          ('unchanged', b'a\n'),
1173
                          ('unchanged', b'b\n'),
1174
                          ('unchanged', b'c\n'),
1175
                          ('conflicted-a', b'd\n'),
1176
                          ('conflicted-b', b'e\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1177
                          ], list(plan))
3144.5.3 by Aaron Bentley
Test interesting_files for LCA merge
1178
3287.17.1 by John Arbash Meinel
Fix bug #235715 by using the empty list as the text for a base of NULL_REVISION.
1179
    def test_plan_lca_merge_with_null(self):
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1180
        self.add_version((b'root', b'A'), [], b'ab')
1181
        self.add_version((b'root', b'B'), [], b'bc')
1182
        plan = self.plan_merge_vf.plan_lca_merge(b'A', b'B')
1183
        self.assertEqual([('new-a', b'a\n'),
1184
                          ('unchanged', b'b\n'),
1185
                          ('new-b', b'c\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1186
                          ], list(plan))
3287.17.1 by John Arbash Meinel
Fix bug #235715 by using the empty list as the text for a base of NULL_REVISION.
1187
3514.2.1 by Aaron Bentley
Test for correct conflicts on delete + change
1188
    def test_plan_merge_with_delete_and_change(self):
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1189
        self.add_rev(b'root', b'C', [], b'a')
1190
        self.add_rev(b'root', b'A', [b'C'], b'b')
1191
        self.add_rev(b'root', b'B', [b'C'], b'')
1192
        plan = self.plan_merge_vf.plan_merge(b'A', b'B')
1193
        self.assertEqual([('killed-both', b'a\n'),
1194
                          ('new-a', b'b\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1195
                          ], list(plan))
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1196
1197
    def test_plan_merge_with_move_and_change(self):
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1198
        self.add_rev(b'root', b'C', [], b'abcd')
1199
        self.add_rev(b'root', b'A', [b'C'], b'acbd')
1200
        self.add_rev(b'root', b'B', [b'C'], b'aBcd')
1201
        plan = self.plan_merge_vf.plan_merge(b'A', b'B')
1202
        self.assertEqual([('unchanged', b'a\n'),
1203
                          ('new-a', b'c\n'),
1204
                          ('killed-b', b'b\n'),
1205
                          ('new-b', b'B\n'),
1206
                          ('killed-a', b'c\n'),
1207
                          ('unchanged', b'd\n'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1208
                          ], list(plan))
3514.2.1 by Aaron Bentley
Test for correct conflicts on delete + change
1209
3144.5.3 by Aaron Bentley
Test interesting_files for LCA merge
1210
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1211
class LoggingMerger(object):
1212
    # These seem to be the required attributes
1213
    requires_base = False
1214
    supports_reprocess = False
1215
    supports_show_base = False
1216
    supports_cherrypick = False
1217
    # We intentionally do not define supports_lca_trees
1218
1219
    def __init__(self, *args, **kwargs):
1220
        self.args = args
1221
        self.kwargs = kwargs
1222
1223
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1224
class TestMergerBase(TestCaseWithMemoryTransport):
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1225
    """Common functionality for Merger tests that don't write to disk."""
3514.4.1 by John Arbash Meinel
Update Merger to set a flag when we encounter a criss-cross merge.
1226
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1227
    def get_builder(self):
1228
        builder = self.make_branch_builder('path')
1229
        builder.start_series()
1230
        self.addCleanup(builder.finish_series)
1231
        return builder
1232
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1233
    def setup_simple_graph(self):
1234
        """Create a simple 3-node graph.
1235
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1236
        :return: A BranchBuilder
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1237
        """
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1238
        #
1239
        #  A
1240
        #  |\
1241
        #  B C
1242
        #
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1243
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1244
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1245
                               [('add', ('', None, 'directory', None))],
1246
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1247
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1248
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1249
        return builder
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1250
1251
    def setup_criss_cross_graph(self):
1252
        """Create a 5-node graph with a criss-cross.
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1253
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1254
        :return: A BranchBuilder
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1255
        """
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1256
        # A
1257
        # |\
1258
        # B C
1259
        # |X|
1260
        # D E
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1261
        builder = self.setup_simple_graph()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1262
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1263
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1264
        return builder
1265
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
1266
    def make_Merger(self, builder, other_revision_id, interesting_files=None):
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1267
        """Make a Merger object from a branch builder"""
1268
        mem_tree = memorytree.MemoryTree.create_on_branch(builder.get_branch())
1269
        mem_tree.lock_write()
1270
        self.addCleanup(mem_tree.unlock)
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
1271
        merger = _mod_merge.Merger.from_revision_ids(
3514.4.7 by John Arbash Meinel
switch over test_merge to using the new BranchBuilder api.
1272
            mem_tree, other_revision_id)
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1273
        merger.set_interesting_files(interesting_files)
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1274
        merger.merge_type = _mod_merge.Merge3Merger
1275
        return merger
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1276
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1277
1278
class TestMergerInMemory(TestMergerBase):
1279
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1280
    def test_cache_trees_with_revision_ids_None(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1281
        merger = self.make_Merger(self.setup_simple_graph(), b'C-id')
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1282
        original_cache = dict(merger._cached_trees)
1283
        merger.cache_trees_with_revision_ids([None])
1284
        self.assertEqual(original_cache, merger._cached_trees)
1285
1286
    def test_cache_trees_with_revision_ids_no_revision_id(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1287
        merger = self.make_Merger(self.setup_simple_graph(), b'C-id')
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1288
        original_cache = dict(merger._cached_trees)
1289
        tree = self.make_branch_and_memory_tree('tree')
1290
        merger.cache_trees_with_revision_ids([tree])
1291
        self.assertEqual(original_cache, merger._cached_trees)
1292
1293
    def test_cache_trees_with_revision_ids_having_revision_id(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1294
        merger = self.make_Merger(self.setup_simple_graph(), b'C-id')
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1295
        original_cache = dict(merger._cached_trees)
6973.5.2 by Jelmer Vernooij
Add more bees.
1296
        tree = merger.this_branch.repository.revision_tree(b'B-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1297
        original_cache[b'B-id'] = tree
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1298
        merger.cache_trees_with_revision_ids([tree])
1299
        self.assertEqual(original_cache, merger._cached_trees)
1300
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1301
    def test_find_base(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1302
        merger = self.make_Merger(self.setup_simple_graph(), b'C-id')
1303
        self.assertEqual(b'A-id', merger.base_rev_id)
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1304
        self.assertFalse(merger._is_criss_cross)
1305
        self.assertIs(None, merger._lca_trees)
1306
1307
    def test_find_base_criss_cross(self):
3514.4.14 by John Arbash Meinel
Add a test which shows that the ordering switches when you pick the other parent.
1308
        builder = self.setup_criss_cross_graph()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1309
        merger = self.make_Merger(builder, b'E-id')
1310
        self.assertEqual(b'A-id', merger.base_rev_id)
3514.4.1 by John Arbash Meinel
Update Merger to set a flag when we encounter a criss-cross merge.
1311
        self.assertTrue(merger._is_criss_cross)
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1312
        self.assertEqual([b'B-id', b'C-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1313
                                              for t in merger._lca_trees])
3514.4.14 by John Arbash Meinel
Add a test which shows that the ordering switches when you pick the other parent.
1314
        # If we swap the order, we should get a different lca order
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1315
        builder.build_snapshot([b'E-id'], [], revision_id=b'F-id')
1316
        merger = self.make_Merger(builder, b'D-id')
1317
        self.assertEqual([b'C-id', b'B-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1318
                                              for t in merger._lca_trees])
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1319
3514.4.23 by John Arbash Meinel
Handle when there are more than 2 LCAs while searching for the unique lca.
1320
    def test_find_base_triple_criss_cross(self):
1321
        #       A-.
1322
        #      / \ \
1323
        #     B   C F # F is merged into both branches
1324
        #     |\ /| |
1325
        #     | X | |\
1326
        #     |/ \| | :
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1327
        #   : D   E |
1328
        #    \|   |/
3514.4.23 by John Arbash Meinel
Handle when there are more than 2 LCAs while searching for the unique lca.
1329
        #     G   H
1330
        builder = self.setup_criss_cross_graph()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1331
        builder.build_snapshot([b'A-id'], [], revision_id=b'F-id')
1332
        builder.build_snapshot([b'E-id', b'F-id'], [], revision_id=b'H-id')
1333
        builder.build_snapshot([b'D-id', b'F-id'], [], revision_id=b'G-id')
1334
        merger = self.make_Merger(builder, b'H-id')
1335
        self.assertEqual([b'B-id', b'C-id', b'F-id'],
3514.4.23 by John Arbash Meinel
Handle when there are more than 2 LCAs while searching for the unique lca.
1336
                         [t.get_revision_id() for t in merger._lca_trees])
1337
5540.1.2 by Gary van der Merwe
Add a test for bug #588698, for merging a new root more than once.
1338
    def test_find_base_new_root_criss_cross(self):
1339
        # A   B
1340
        # |\ /|
1341
        # | X |
1342
        # |/ \|
1343
        # C   D
1344
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1345
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1346
                               [('add', ('', None, 'directory', None))],
1347
                               revision_id=b'A-id')
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1348
        builder.build_snapshot([],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1349
                               [('add', ('', None, 'directory', None))],
1350
                               revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1351
        builder.build_snapshot([b'A-id', b'B-id'], [], revision_id=b'D-id')
1352
        builder.build_snapshot([b'A-id', b'B-id'], [], revision_id=b'C-id')
1353
        merger = self.make_Merger(builder, b'D-id')
1354
        self.assertEqual(b'A-id', merger.base_rev_id)
5540.1.2 by Gary van der Merwe
Add a test for bug #588698, for merging a new root more than once.
1355
        self.assertTrue(merger._is_criss_cross)
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1356
        self.assertEqual([b'A-id', b'B-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1357
                                              for t in merger._lca_trees])
5540.1.2 by Gary van der Merwe
Add a test for bug #588698, for merging a new root more than once.
1358
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1359
    def test_no_criss_cross_passed_to_merge_type(self):
1360
        class LCATreesMerger(LoggingMerger):
1361
            supports_lca_trees = True
1362
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1363
        merger = self.make_Merger(self.setup_simple_graph(), b'C-id')
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1364
        merger.merge_type = LCATreesMerger
1365
        merge_obj = merger.make_merger()
1366
        self.assertIsInstance(merge_obj, LCATreesMerger)
1367
        self.assertFalse('lca_trees' in merge_obj.kwargs)
1368
1369
    def test_criss_cross_passed_to_merge_type(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1370
        merger = self.make_Merger(self.setup_criss_cross_graph(), b'E-id')
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1371
        merger.merge_type = _mod_merge.Merge3Merger
1372
        merge_obj = merger.make_merger()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1373
        self.assertEqual([b'B-id', b'C-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1374
                                              for t in merger._lca_trees])
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1375
1376
    def test_criss_cross_not_supported_merge_type(self):
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1377
        merger = self.make_Merger(self.setup_criss_cross_graph(), b'E-id')
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1378
        # We explicitly do not define supports_lca_trees
1379
        merger.merge_type = LoggingMerger
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1380
        merge_obj = merger.make_merger()
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1381
        self.assertIsInstance(merge_obj, LoggingMerger)
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1382
        self.assertFalse('lca_trees' in merge_obj.kwargs)
1383
1384
    def test_criss_cross_unsupported_merge_type(self):
1385
        class UnsupportedLCATreesMerger(LoggingMerger):
1386
            supports_lca_trees = False
1387
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1388
        merger = self.make_Merger(self.setup_criss_cross_graph(), b'E-id')
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
1389
        merger.merge_type = UnsupportedLCATreesMerger
1390
        merge_obj = merger.make_merger()
1391
        self.assertIsInstance(merge_obj, UnsupportedLCATreesMerger)
1392
        self.assertFalse('lca_trees' in merge_obj.kwargs)
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
1393
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1394
1395
class TestMergerEntriesLCA(TestMergerBase):
1396
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
1397
    def make_merge_obj(self, builder, other_revision_id,
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
1398
                       interesting_files=None):
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
1399
        merger = self.make_Merger(builder, other_revision_id,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1400
                                  interesting_files=interesting_files)
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1401
        return merger.make_merger()
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1402
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1403
    def test_simple(self):
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1404
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1405
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1406
                               [('add', (u'', b'a-root-id', 'directory', None)),
1407
                                ('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1408
                               revision_id=b'A-id')
1409
        builder.build_snapshot([b'A-id'],
1410
                               [('modify', ('a', b'a\nb\nC\nc\n'))],
1411
                               revision_id=b'C-id')
1412
        builder.build_snapshot([b'A-id'],
1413
                               [('modify', ('a', b'a\nB\nb\nc\n'))],
1414
                               revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1415
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1416
                               [('modify', ('a', b'a\nB\nb\nC\nc\nE\n'))],
1417
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1418
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1419
                               [('modify', ('a', b'a\nB\nb\nC\nc\n'))],
1420
                               revision_id=b'D-id', )
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1421
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
1422
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1423
        self.assertEqual([b'B-id', b'C-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1424
                                              for t in merge_obj._lca_trees])
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1425
        self.assertEqual(b'A-id', merge_obj.base_tree.get_revision_id())
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
1426
        entries = list(merge_obj._entries_lca())
1427
1428
        # (file_id, changed, parents, names, executable)
1429
        # BASE, lca1, lca2, OTHER, THIS
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1430
        root_id = b'a-root-id'
1431
        self.assertEqual([(b'a-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1432
                           ((u'a', [u'a', u'a']), u'a', u'a'),
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
1433
                           ((root_id, [root_id, root_id]), root_id, root_id),
1434
                           ((u'a', [u'a', u'a']), u'a', u'a'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1435
                           ((False, [False, False]), False, False),
1436
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1437
                          ], entries)
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1438
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1439
    def test_not_in_base(self):
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1440
        # LCAs all have the same last-modified revision for the file, as do
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1441
        # the tips, but the base has something different
1442
        #       A    base, doesn't have the file
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1443
        #       |\
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1444
        #       B C  B introduces 'foo', C introduces 'bar'
1445
        #       |X|
1446
        #       D E  D and E now both have 'foo' and 'bar'
1447
        #       |X|
1448
        #       F G  the files are now in F, G, D and E, but not in A
1449
        #            G modifies 'bar'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1450
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1451
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1452
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1453
                               [('add', (u'', b'a-root-id', 'directory', None))],
1454
                               revision_id=b'A-id')
1455
        builder.build_snapshot([b'A-id'],
1456
                               [('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
1457
                               revision_id=b'B-id')
1458
        builder.build_snapshot([b'A-id'],
1459
                               [('add', (u'bar', b'bar-id', 'file', b'd\ne\nf\n'))],
1460
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1461
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1462
                               [('add', (u'bar', b'bar-id', 'file', b'd\ne\nf\n'))],
1463
                               revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1464
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1465
                               [('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
1466
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1467
        builder.build_snapshot([b'E-id', b'D-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1468
                               [('modify', (u'bar', b'd\ne\nf\nG\n'))],
1469
                               revision_id=b'G-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1470
        builder.build_snapshot([b'D-id', b'E-id'], [], revision_id=b'F-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1471
        merge_obj = self.make_merge_obj(builder, b'G-id')
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1472
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1473
        self.assertEqual([b'D-id', b'E-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1474
                                              for t in merge_obj._lca_trees])
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1475
        self.assertEqual(b'A-id', merge_obj.base_tree.get_revision_id())
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1476
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1477
        root_id = b'a-root-id'
1478
        self.assertEqual([(b'bar-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1479
                           ((None, [u'bar', u'bar']), u'bar', u'bar'),
3514.4.10 by John Arbash Meinel
Test the case where BASE is missing a file that is present in THIS, OTHER and all LCAs.
1480
                           ((None, [root_id, root_id]), root_id, root_id),
1481
                           ((None, [u'bar', u'bar']), u'bar', u'bar'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1482
                           ((None, [False, False]), False, False),
1483
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1484
                          ], entries)
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1485
1486
    def test_not_in_this(self):
1487
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1488
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1489
                               [('add', (u'', b'a-root-id', 'directory', None)),
1490
                                ('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1491
                               revision_id=b'A-id')
1492
        builder.build_snapshot([b'A-id'],
1493
                               [('modify', ('a', b'a\nB\nb\nc\n'))],
1494
                               revision_id=b'B-id')
1495
        builder.build_snapshot([b'A-id'],
1496
                               [('modify', ('a', b'a\nb\nC\nc\n'))],
1497
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1498
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1499
                               [('modify', ('a', b'a\nB\nb\nC\nc\nE\n'))],
1500
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1501
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1502
                               [('unversion', 'a')],
1503
                               revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1504
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1505
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1506
        self.assertEqual([b'B-id', b'C-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1507
                                              for t in merge_obj._lca_trees])
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1508
        self.assertEqual(b'A-id', merge_obj.base_tree.get_revision_id())
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1509
1510
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1511
        root_id = b'a-root-id'
1512
        self.assertEqual([(b'a-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1513
                           ((u'a', [u'a', u'a']), u'a', None),
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1514
                           ((root_id, [root_id, root_id]), root_id, None),
1515
                           ((u'a', [u'a', u'a']), u'a', None),
7490.134.2 by Jelmer Vernooij
Fix tests.
1516
                           ((False, [False, False]), False, None),
1517
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1518
                          ], entries)
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
1519
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1520
    def test_file_not_in_one_lca(self):
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1521
        #   A   # just root
1522
        #   |\
1523
        #   B C # B no file, C introduces a file
1524
        #   |X|
1525
        #   D E # D and E both have the file, unchanged from C
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
1526
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1527
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1528
                               [('add', (u'', b'a-root-id', 'directory', None))],
1529
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1530
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1531
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1532
                               [('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1533
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1534
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1535
                               [], revision_id=b'E-id')  # Inherited from C
1536
        builder.build_snapshot([b'B-id', b'C-id'],  # Merged from C
1537
                               [('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1538
                               revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1539
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
1540
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1541
        self.assertEqual([b'B-id', b'C-id'], [t.get_revision_id()
7143.15.2 by Jelmer Vernooij
Run autopep8.
1542
                                              for t in merge_obj._lca_trees])
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1543
        self.assertEqual(b'A-id', merge_obj.base_tree.get_revision_id())
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
1544
1545
        entries = list(merge_obj._entries_lca())
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1546
        self.assertEqual([], entries)
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
1547
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
1548
    def test_not_in_other(self):
1549
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1550
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1551
                               [('add', (u'', b'a-root-id', 'directory', None)),
1552
                                ('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1553
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1554
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1555
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1556
        builder.build_snapshot(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1557
            [b'C-id', b'B-id'],
1558
            [('unversion', 'a')], revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1559
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1560
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
1561
1562
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1563
        root_id = b'a-root-id'
1564
        self.assertEqual([(b'a-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1565
                           ((u'a', [u'a', u'a']), None, u'a'),
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
1566
                           ((root_id, [root_id, root_id]), None, root_id),
1567
                           ((u'a', [u'a', u'a']), None, u'a'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1568
                           ((False, [False, False]), None, False),
1569
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1570
                          ], entries)
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
1571
3514.4.30 by John Arbash Meinel
Several updates.
1572
    def test_not_in_other_or_lca(self):
1573
        #       A    base, introduces 'foo'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1574
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
1575
        #       B C  B nothing, C deletes foo
1576
        #       |X|
1577
        #       D E  D restores foo (same as B), E leaves it deleted
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
1578
        # Analysis:
1579
        #   A => B, no changes
1580
        #   A => C, delete foo (C should supersede B)
1581
        #   C => D, restore foo
1582
        #   C => E, no changes
1583
        # D would then win 'cleanly' and no record would be given
3514.4.30 by John Arbash Meinel
Several updates.
1584
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1585
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1586
                               [('add', (u'', b'a-root-id', 'directory', None)),
1587
                                ('add', (u'foo', b'foo-id', 'file', b'content\n'))],
1588
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1589
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1590
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1591
                               [('unversion', 'foo')], revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1592
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1593
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1594
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.30 by John Arbash Meinel
Several updates.
1595
1596
        entries = list(merge_obj._entries_lca())
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
1597
        self.assertEqual([], entries)
1598
1599
    def test_not_in_other_mod_in_lca1_not_in_lca2(self):
1600
        #       A    base, introduces 'foo'
1601
        #       |\
1602
        #       B C  B changes 'foo', C deletes foo
1603
        #       |X|
1604
        #       D E  D restores foo (same as B), E leaves it deleted (as C)
1605
        # Analysis:
1606
        #   A => B, modified foo
1607
        #   A => C, delete foo, C does not supersede B
1608
        #   B => D, no changes
1609
        #   C => D, resolve in favor of B
1610
        #   B => E, resolve in favor of E
1611
        #   C => E, no changes
1612
        # In this case, we have a conflict of how the changes were resolved. E
1613
        # picked C and D picked B, so we should issue a conflict
1614
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1615
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1616
                               [('add', (u'', b'a-root-id', 'directory', None)),
1617
                                ('add', (u'foo', b'foo-id', 'file', b'content\n'))],
1618
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1619
        builder.build_snapshot([b'A-id'], [
1620
            ('modify', ('foo', b'new-content\n'))],
6973.5.2 by Jelmer Vernooij
Add more bees.
1621
            revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1622
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1623
                               [('unversion', 'foo')],
1624
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1625
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1626
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1627
        merge_obj = self.make_merge_obj(builder, b'E-id')
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
1628
1629
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1630
        root_id = b'a-root-id'
1631
        self.assertEqual([(b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1632
                           ((u'foo', [u'foo', None]), None, u'foo'),
3514.4.30 by John Arbash Meinel
Several updates.
1633
                           ((root_id, [root_id, None]), None, root_id),
1634
                           ((u'foo', [u'foo', None]), None, 'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1635
                           ((False, [False, None]), None, False),
1636
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1637
                          ], entries)
3514.4.30 by John Arbash Meinel
Several updates.
1638
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1639
    def test_only_in_one_lca(self):
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
1640
        #   A   add only root
1641
        #   |\
1642
        #   B C B nothing, C add file
1643
        #   |X|
1644
        #   D E D still has nothing, E removes file
1645
        # Analysis:
1646
        #   B => D, no change
1647
        #   C => D, removed the file
1648
        #   B => E, no change
1649
        #   C => E, removed the file
1650
        # Thus D & E have identical changes, and this is a no-op
1651
        # Alternatively:
1652
        #   A => B, no change
1653
        #   A => C, add file, thus C supersedes B
1654
        #   w/ C=BASE, D=THIS, E=OTHER we have 'happy convergence'
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1655
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1656
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1657
                               [('add', (u'', b'a-root-id', 'directory', None))],
1658
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1659
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1660
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1661
                               [('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1662
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1663
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1664
                               [('unversion', 'a')],
1665
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1666
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1667
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1668
1669
        entries = list(merge_obj._entries_lca())
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
1670
        self.assertEqual([], entries)
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1671
3514.4.16 by John Arbash Meinel
another test for only in OTHER
1672
    def test_only_in_other(self):
1673
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1674
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1675
                               [('add', (u'', b'a-root-id', 'directory', None))],
1676
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1677
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1678
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1679
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1680
                               [('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
1681
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1682
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1683
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.16 by John Arbash Meinel
another test for only in OTHER
1684
1685
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1686
        root_id = b'a-root-id'
1687
        self.assertEqual([(b'a-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1688
                           ((None, [None, None]), u'a', None),
3514.4.16 by John Arbash Meinel
another test for only in OTHER
1689
                           ((None, [None, None]), root_id, None),
1690
                           ((None, [None, None]), u'a', None),
7490.134.2 by Jelmer Vernooij
Fix tests.
1691
                           ((None, [None, None]), False, None),
1692
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1693
                          ], entries)
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1694
3514.4.30 by John Arbash Meinel
Several updates.
1695
    def test_one_lca_supersedes(self):
3514.4.41 by John Arbash Meinel
Some grammar and other clarity feedback from Aaron.
1696
        # One LCA supersedes the other LCAs last modified value, but the
3514.4.30 by John Arbash Meinel
Several updates.
1697
        # value is not the same as BASE.
1698
        #       A    base, introduces 'foo', last mod A
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1699
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
1700
        #       B C  B modifies 'foo' (mod B), C does nothing (mod A)
1701
        #       |X|
1702
        #       D E  D does nothing (mod B), E updates 'foo' (mod E)
1703
        #       |X|
1704
        #       F G  F updates 'foo' (mod F). G does nothing (mod E)
1705
        #
1706
        #   At this point, G should not be considered to modify 'foo', even
1707
        #   though its LCAs disagree. This is because the modification in E
1708
        #   completely supersedes the value in D.
1709
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1710
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1711
                               [('add', (u'', b'a-root-id', 'directory', None)),
1712
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1713
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1714
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1715
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1716
                               [('modify', ('foo', b'B content\n'))],
1717
                               revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1718
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1719
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1720
                               [('modify', ('foo', b'E content\n'))],
1721
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1722
        builder.build_snapshot([b'E-id', b'D-id'], [], revision_id=b'G-id')
1723
        builder.build_snapshot([b'D-id', b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1724
                               [('modify', ('foo', b'F content\n'))],
1725
                               revision_id=b'F-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1726
        merge_obj = self.make_merge_obj(builder, b'G-id')
3514.4.30 by John Arbash Meinel
Several updates.
1727
1728
        self.assertEqual([], list(merge_obj._entries_lca()))
1729
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1730
    def test_one_lca_supersedes_path(self):
1731
        # Double-criss-cross merge, the ultimate base value is different from
1732
        # the intermediate.
1733
        #   A    value 'foo'
1734
        #   |\
1735
        #   B C  B value 'bar', C = 'foo'
1736
        #   |X|
1737
        #   D E  D = 'bar', E supersedes to 'bing'
1738
        #   |X|
1739
        #   F G  F = 'bing', G supersedes to 'barry'
1740
        #
1741
        # In this case, we technically should not care about the value 'bar' for
1742
        # D, because it was clearly superseded by E's 'bing'. The
1743
        # per-file/attribute graph would actually look like:
1744
        #   A
1745
        #   |
1746
        #   B
1747
        #   |
1748
        #   E
1749
        #   |
1750
        #   G
1751
        #
1752
        # Because the other side of the merge never modifies the value, it just
1753
        # takes the value from the merge.
1754
        #
1755
        # ATM this fails because we will prune 'foo' from the LCAs, but we
1756
        # won't prune 'bar'. This is getting far off into edge-case land, so we
1757
        # aren't supporting it yet.
1758
        #
1759
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1760
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1761
                               [('add', (u'', b'a-root-id', 'directory', None)),
1762
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1763
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1764
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1765
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1766
                               [('rename', ('foo', 'bar'))],
1767
                               revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1768
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1769
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1770
                               [('rename', ('foo', 'bing'))],
1771
                               revision_id=b'E-id')  # override to bing
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1772
        builder.build_snapshot([b'E-id', b'D-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1773
                               [('rename', ('bing', 'barry'))],
1774
                               revision_id=b'G-id')  # override to barry
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1775
        builder.build_snapshot([b'D-id', b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1776
                               [('rename', ('bar', 'bing'))],
1777
                               revision_id=b'F-id')  # Merge in E's change
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1778
        merge_obj = self.make_merge_obj(builder, b'G-id')
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1779
1780
        self.expectFailure("We don't do an actual heads() check on lca values,"
7143.15.2 by Jelmer Vernooij
Run autopep8.
1781
                           " or use the per-attribute graph",
1782
                           self.assertEqual, [], list(merge_obj._entries_lca()))
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1783
1784
    def test_one_lca_accidentally_pruned(self):
1785
        # Another incorrect resolution from the same basic flaw:
1786
        #   A    value 'foo'
1787
        #   |\
1788
        #   B C  B value 'bar', C = 'foo'
1789
        #   |X|
1790
        #   D E  D = 'bar', E reverts to 'foo'
1791
        #   |X|
1792
        #   F G  F = 'bing', G switches to 'bar'
1793
        #
1794
        # 'bar' will not be seen as an interesting change, because 'foo' will
1795
        # be pruned from the LCAs, even though it was newly introduced by E
1796
        # (superseding B).
1797
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1798
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1799
                               [('add', (u'', b'a-root-id', 'directory', None)),
1800
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1801
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1802
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1803
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1804
                               [('rename', ('foo', 'bar'))],
1805
                               revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1806
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1807
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1808
        builder.build_snapshot([b'E-id', b'D-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1809
                               [('rename', ('foo', 'bar'))],
1810
                               revision_id=b'G-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1811
        builder.build_snapshot([b'D-id', b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1812
                               [('rename', ('bar', 'bing'))],
1813
                               revision_id=b'F-id')  # should end up conflicting
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1814
        merge_obj = self.make_merge_obj(builder, b'G-id')
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1815
1816
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1817
        root_id = b'a-root-id'
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1818
        self.expectFailure("We prune values from BASE even when relevant.",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1819
                           self.assertEqual,
1820
                           [(b'foo-id', False,
1821
                             ((root_id, [root_id, root_id]), root_id, root_id),
1822
                               ((u'foo', [u'bar', u'foo']), u'bar', u'bing'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1823
                               ((False, [False, False]), False, False),
1824
                             False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1825
                            ], entries)
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
1826
3514.4.30 by John Arbash Meinel
Several updates.
1827
    def test_both_sides_revert(self):
1828
        # Both sides of a criss-cross revert the text to the lca
1829
        #       A    base, introduces 'foo'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1830
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
1831
        #       B C  B modifies 'foo', C modifies 'foo'
1832
        #       |X|
1833
        #       D E  D reverts to B, E reverts to C
1834
        # This should conflict
1835
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1836
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1837
                               [('add', (u'', b'a-root-id', 'directory', None)),
1838
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1839
                               revision_id=b'A-id')
1840
        builder.build_snapshot([b'A-id'],
1841
                               [('modify', ('foo', b'B content\n'))],
1842
                               revision_id=b'B-id')
1843
        builder.build_snapshot([b'A-id'],
1844
                               [('modify', ('foo', b'C content\n'))],
1845
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1846
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1847
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1848
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.30 by John Arbash Meinel
Several updates.
1849
1850
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1851
        root_id = b'a-root-id'
1852
        self.assertEqual([(b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1853
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
3514.4.30 by John Arbash Meinel
Several updates.
1854
                           ((root_id, [root_id, root_id]), root_id, root_id),
1855
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1856
                           ((False, [False, False]), False, False),
1857
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1858
                          ], entries)
3514.4.30 by John Arbash Meinel
Several updates.
1859
1860
    def test_different_lca_resolve_one_side_updates_content(self):
1861
        # Both sides converge, but then one side updates the text.
1862
        #       A    base, introduces 'foo'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1863
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
1864
        #       B C  B modifies 'foo', C modifies 'foo'
1865
        #       |X|
1866
        #       D E  D reverts to B, E reverts to C
1867
        #       |
1868
        #       F    F updates to a new value
1869
        # We need to emit an entry for 'foo', because D & E differed on the
1870
        # merge resolution
1871
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1872
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1873
                               [('add', (u'', b'a-root-id', 'directory', None)),
1874
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1875
                               revision_id=b'A-id')
1876
        builder.build_snapshot([b'A-id'],
1877
                               [('modify', ('foo', b'B content\n'))],
1878
                               revision_id=b'B-id')
1879
        builder.build_snapshot([b'A-id'],
1880
                               [('modify', ('foo', b'C content\n'))],
1881
                               revision_id=b'C-id', )
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1882
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1883
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1884
        builder.build_snapshot([b'D-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1885
                               [('modify', ('foo', b'F content\n'))],
1886
                               revision_id=b'F-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1887
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.30 by John Arbash Meinel
Several updates.
1888
1889
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1890
        root_id = b'a-root-id'
1891
        self.assertEqual([(b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1892
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
3514.4.30 by John Arbash Meinel
Several updates.
1893
                           ((root_id, [root_id, root_id]), root_id, root_id),
1894
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1895
                           ((False, [False, False]), False, False),
1896
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1897
                          ], entries)
3514.4.30 by John Arbash Meinel
Several updates.
1898
1899
    def test_same_lca_resolution_one_side_updates_content(self):
1900
        # Both sides converge, but then one side updates the text.
1901
        #       A    base, introduces 'foo'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
1902
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
1903
        #       B C  B modifies 'foo', C modifies 'foo'
1904
        #       |X|
1905
        #       D E  D and E use C's value
1906
        #       |
1907
        #       F    F updates to a new value
1908
        # I think it is a bug that this conflicts, but we don't have a way to
1909
        # detect otherwise. And because of:
1910
        #   test_different_lca_resolve_one_side_updates_content
1911
        # We need to conflict.
1912
1913
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1914
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1915
                               [('add', (u'', b'a-root-id', 'directory', None)),
1916
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
1917
                               revision_id=b'A-id')
1918
        builder.build_snapshot([b'A-id'],
1919
                               [('modify', ('foo', b'B content\n'))],
1920
                               revision_id=b'B-id')
1921
        builder.build_snapshot([b'A-id'],
1922
                               [('modify', ('foo', b'C content\n'))],
1923
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1924
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1925
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1926
                               [('modify', ('foo', b'C content\n'))],
1927
                               revision_id=b'D-id')  # Same as E
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1928
        builder.build_snapshot([b'D-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1929
                               [('modify', ('foo', b'F content\n'))],
1930
                               revision_id=b'F-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1931
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.30 by John Arbash Meinel
Several updates.
1932
1933
        entries = list(merge_obj._entries_lca())
1934
        self.expectFailure("We don't detect that LCA resolution was the"
1935
                           " same on both sides",
7143.15.2 by Jelmer Vernooij
Run autopep8.
1936
                           self.assertEqual, [], entries)
3514.4.30 by John Arbash Meinel
Several updates.
1937
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1938
    def test_only_path_changed(self):
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1939
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1940
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1941
                               [('add', (u'', b'a-root-id', 'directory', None)),
1942
                                ('add', (u'a', b'a-id', 'file', b'content\n'))],
1943
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1944
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1945
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1946
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1947
                               [('rename', (u'a', u'b'))],
1948
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1949
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1950
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1951
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1952
        root_id = b'a-root-id'
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1953
        # The content was not changed, only the path
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1954
        self.assertEqual([(b'a-id', False,
6928.1.2 by Jelmer Vernooij
Fix path specification.
1955
                           ((u'a', [u'a', u'a']), u'b', u'a'),
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1956
                           ((root_id, [root_id, root_id]), root_id, root_id),
1957
                           ((u'a', [u'a', u'a']), u'b', u'a'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1958
                           ((False, [False, False]), False, False),
1959
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1960
                          ], entries)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1961
1962
    def test_kind_changed(self):
1963
        # Identical content, except 'D' changes a-id into a directory
1964
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1965
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1966
                               [('add', (u'', b'a-root-id', 'directory', None)),
1967
                                ('add', (u'a', b'a-id', 'file', b'content\n'))],
1968
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1969
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1970
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1971
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1972
                               [('unversion', 'a'),
1973
                                ('flush', None),
1974
                                ('add', (u'a', b'a-id', 'directory', None))],
1975
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1976
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
1977
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1978
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1979
        root_id = b'a-root-id'
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1980
        # Only the kind was changed (content)
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1981
        self.assertEqual([(b'a-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1982
                           ((u'a', [u'a', u'a']), u'a', u'a'),
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1983
                           ((root_id, [root_id, root_id]), root_id, root_id),
1984
                           ((u'a', [u'a', u'a']), u'a', u'a'),
7490.134.2 by Jelmer Vernooij
Fix tests.
1985
                           ((False, [False, False]), False, False),
1986
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1987
                          ], entries)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1988
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
1989
    def test_this_changed_kind(self):
1990
        # Identical content, but THIS changes a file to a directory
1991
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
1992
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1993
                               [('add', (u'', b'a-root-id', 'directory', None)),
1994
                                ('add', (u'a', b'a-id', 'file', b'content\n'))],
1995
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
1996
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
1997
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
1998
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
1999
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2000
                               [('unversion', 'a'),
2001
                                ('flush', None),
2002
                                ('add', (u'a', b'a-id', 'directory', None))],
2003
                               revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2004
        merge_obj = self.make_merge_obj(builder, b'E-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2005
        entries = list(merge_obj._entries_lca())
2006
        # Only the kind was changed (content)
2007
        self.assertEqual([], entries)
2008
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2009
    def test_interesting_files(self):
2010
        # Two files modified, but we should filter one of them
2011
        builder = self.get_builder()
6816.2.2 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
2012
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2013
                               [('add', (u'', b'a-root-id', 'directory', None)),
2014
                                ('add', (u'a', b'a-id', 'file', b'content\n')),
2015
                                   ('add', (u'b', b'b-id', 'file', b'content\n'))],
2016
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2017
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2018
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2019
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2020
                               [('modify', ('a', b'new-content\n')),
2021
                                ('modify', ('b', b'new-content\n'))],
2022
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2023
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2024
        merge_obj = self.make_merge_obj(builder, b'E-id',
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2025
                                        interesting_files=['b'])
2026
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2027
        root_id = b'a-root-id'
2028
        self.assertEqual([(b'b-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2029
                           ((u'b', [u'b', u'b']), u'b', u'b'),
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2030
                           ((root_id, [root_id, root_id]), root_id, root_id),
2031
                           ((u'b', [u'b', u'b']), u'b', u'b'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2032
                           ((False, [False, False]), False, False),
2033
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2034
                          ], entries)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2035
2036
    def test_interesting_file_in_this(self):
2037
        # This renamed the file, but it should still match the entry in other
2038
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2039
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2040
                               [('add', (u'', b'a-root-id', 'directory', None)),
2041
                                ('add', (u'a', b'a-id', 'file', b'content\n')),
2042
                                   ('add', (u'b', b'b-id', 'file', b'content\n'))],
2043
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2044
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2045
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2046
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2047
                               [('modify', ('a', b'new-content\n')),
2048
                                ('modify', ('b', b'new-content\n'))],
2049
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2050
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2051
                               [('rename', ('b', 'c'))],
2052
                               revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2053
        merge_obj = self.make_merge_obj(builder, b'E-id',
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2054
                                        interesting_files=['c'])
2055
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2056
        root_id = b'a-root-id'
2057
        self.assertEqual([(b'b-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2058
                           ((u'b', [u'b', u'b']), u'b', u'c'),
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2059
                           ((root_id, [root_id, root_id]), root_id, root_id),
2060
                           ((u'b', [u'b', u'b']), u'b', u'c'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2061
                           ((False, [False, False]), False, False),
2062
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2063
                          ], entries)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2064
2065
    def test_interesting_file_in_base(self):
2066
        # This renamed the file, but it should still match the entry in BASE
2067
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2068
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2069
                               [('add', (u'', b'a-root-id', 'directory', None)),
2070
                                ('add', (u'a', b'a-id', 'file', b'content\n')),
2071
                                   ('add', (u'c', b'c-id', 'file', b'content\n'))],
2072
                               revision_id=b'A-id')
2073
        builder.build_snapshot([b'A-id'],
2074
                               [('rename', ('c', 'b'))],
2075
                               revision_id=b'B-id')
2076
        builder.build_snapshot([b'A-id'],
2077
                               [('rename', ('c', 'b'))],
2078
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2079
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2080
                               [('modify', ('a', b'new-content\n')),
2081
                                ('modify', ('b', b'new-content\n'))],
2082
                               revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2083
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2084
        merge_obj = self.make_merge_obj(builder, b'E-id',
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2085
                                        interesting_files=['c'])
2086
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2087
        root_id = b'a-root-id'
2088
        self.assertEqual([(b'c-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2089
                           ((u'c', [u'b', u'b']), u'b', u'b'),
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2090
                           ((root_id, [root_id, root_id]), root_id, root_id),
2091
                           ((u'c', [u'b', u'b']), u'b', u'b'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2092
                           ((False, [False, False]), False, False),
2093
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2094
                          ], entries)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2095
2096
    def test_interesting_file_in_lca(self):
2097
        # This renamed the file, but it should still match the entry in LCA
2098
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2099
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2100
                               [('add', (u'', b'a-root-id', 'directory', None)),
2101
                                ('add', (u'a', b'a-id', 'file', b'content\n')),
2102
                                   ('add', (u'b', b'b-id', 'file', b'content\n'))],
2103
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2104
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2105
                               [('rename', ('b', 'c'))], revision_id=b'B-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2106
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2107
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2108
                               [('modify', ('a', b'new-content\n')),
2109
                                ('modify', ('b', b'new-content\n'))],
2110
                               revision_id=b'E-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
2111
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2112
                               [('rename', ('c', 'b'))], revision_id=b'D-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2113
        merge_obj = self.make_merge_obj(builder, b'E-id',
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2114
                                        interesting_files=['c'])
2115
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2116
        root_id = b'a-root-id'
2117
        self.assertEqual([(b'b-id', True,
6928.1.2 by Jelmer Vernooij
Fix path specification.
2118
                           ((u'b', [u'c', u'b']), u'b', u'b'),
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2119
                           ((root_id, [root_id, root_id]), root_id, root_id),
2120
                           ((u'b', [u'c', u'b']), u'b', u'b'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2121
                           ((False, [False, False]), False, False),
2122
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2123
                          ], entries)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2124
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
2125
    def test_interesting_files(self):
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2126
        # Two files modified, but we should filter one of them
2127
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2128
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2129
                               [('add', (u'', b'a-root-id', 'directory', None)),
2130
                                ('add', (u'a', b'a-id', 'file', b'content\n')),
2131
                                   ('add', (u'b', b'b-id', 'file', b'content\n'))],
2132
                               revision_id=b'A-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2133
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2134
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2135
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2136
                               [('modify', ('a', b'new-content\n')),
2137
                                ('modify', ('b', b'new-content\n'))], revision_id=b'E-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2138
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2139
        merge_obj = self.make_merge_obj(builder, b'E-id',
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
2140
                                        interesting_files=['b'])
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2141
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2142
        root_id = b'a-root-id'
2143
        self.assertEqual([(b'b-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2144
                           ((u'b', [u'b', u'b']), u'b', u'b'),
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2145
                           ((root_id, [root_id, root_id]), root_id, root_id),
2146
                           ((u'b', [u'b', u'b']), u'b', u'b'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2147
                           ((False, [False, False]), False, False),
2148
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2149
                          ], entries)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
2150
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2151
2152
class TestMergerEntriesLCAOnDisk(tests.TestCaseWithTransport):
2153
2154
    def get_builder(self):
2155
        builder = self.make_branch_builder('path')
2156
        builder.start_series()
2157
        self.addCleanup(builder.finish_series)
2158
        return builder
2159
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2160
    def get_wt_from_builder(self, builder):
2161
        """Get a real WorkingTree from the builder."""
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2162
        the_branch = builder.get_branch()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
2163
        wt = the_branch.controldir.create_workingtree()
3514.4.31 by John Arbash Meinel
Add expected failures for cases where we should be looking at more than
2164
        # Note: This is a little bit ugly, but we are holding the branch
2165
        #       write-locked as part of the build process, and we would like to
2166
        #       maintain that. So we just force the WT to re-use the same
2167
        #       branch object.
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2168
        wt._branch = the_branch
2169
        wt.lock_write()
2170
        self.addCleanup(wt.unlock)
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2171
        return wt
2172
2173
    def do_merge(self, builder, other_revision_id):
2174
        wt = self.get_wt_from_builder(builder)
6719.1.4 by Jelmer Vernooij
Fix remaining tests.
2175
        merger = _mod_merge.Merger.from_revision_ids(
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2176
            wt, other_revision_id)
2177
        merger.merge_type = _mod_merge.Merge3Merger
2178
        return wt, merger.do_merge()
2179
2180
    def test_simple_lca(self):
2181
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2182
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2183
                               [('add', (u'', b'a-root-id', 'directory', None)),
2184
                                ('add', (u'a', b'a-id', 'file', b'a\nb\nc\n'))],
2185
                               revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2186
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2187
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2188
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
2189
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2190
                               [('modify', ('a', b'a\nb\nc\nd\ne\nf\n'))],
2191
                               revision_id=b'D-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2192
        wt, conflicts = self.do_merge(builder, b'E-id')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2193
        self.assertEqual(0, conflicts)
2194
        # The merge should have simply update the contents of 'a'
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2195
        self.assertEqual(b'a\nb\nc\nd\ne\nf\n', wt.get_file_text('a'))
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2196
2197
    def test_conflict_without_lca(self):
2198
        # This test would cause a merge conflict, unless we use the lca trees
2199
        # to determine the real ancestry
2200
        #   A       Path at 'foo'
2201
        #  / \
2202
        # B   C     Path renamed to 'bar' in B
2203
        # |\ /|
2204
        # | X |
2205
        # |/ \|
2206
        # D   E     Path at 'bar' in D and E
2207
        #     |
2208
        #     F     Path at 'baz' in F, which supersedes 'bar' and 'foo'
2209
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2210
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2211
                               [('add', (u'', b'a-root-id', 'directory', None)),
2212
                                ('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
2213
                               revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2214
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2215
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2216
                               [('rename', ('foo', 'bar'))], revision_id=b'B-id', )
2217
        builder.build_snapshot([b'C-id', b'B-id'],  # merge the rename
2218
                               [('rename', ('foo', 'bar'))], revision_id=b'E-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2219
        builder.build_snapshot([b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2220
                               [('rename', ('bar', 'baz'))], revision_id=b'F-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2221
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2222
        wt, conflicts = self.do_merge(builder, b'F-id')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2223
        self.assertEqual(0, conflicts)
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2224
        # The merge should simply recognize that the final rename takes
2225
        # precedence
6855.4.1 by Jelmer Vernooij
Yet more bees.
2226
        self.assertEqual('baz', wt.id2path(b'foo-id'))
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2227
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2228
    def test_other_deletes_lca_renames(self):
2229
        # This test would cause a merge conflict, unless we use the lca trees
2230
        # to determine the real ancestry
2231
        #   A       Path at 'foo'
2232
        #  / \
2233
        # B   C     Path renamed to 'bar' in B
2234
        # |\ /|
2235
        # | X |
2236
        # |/ \|
2237
        # D   E     Path at 'bar' in D and E
2238
        #     |
2239
        #     F     F deletes 'bar'
2240
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2241
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2242
                               [('add', (u'', b'a-root-id', 'directory', None)),
2243
                                ('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
2244
                               revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2245
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2246
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2247
                               [('rename', ('foo', 'bar'))], revision_id=b'B-id')
2248
        builder.build_snapshot([b'C-id', b'B-id'],  # merge the rename
2249
                               [('rename', ('foo', 'bar'))], revision_id=b'E-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2250
        builder.build_snapshot([b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2251
                               [('unversion', 'bar')], revision_id=b'F-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2252
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2253
        wt, conflicts = self.do_merge(builder, b'F-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2254
        self.assertEqual(0, conflicts)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2255
        self.assertRaises(errors.NoSuchId, wt.id2path, b'foo-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2256
2257
    def test_executable_changes(self):
2258
        #   A       Path at 'foo'
2259
        #  / \
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2260
        # B   C
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2261
        # |\ /|
2262
        # | X |
2263
        # |/ \|
2264
        # D   E
2265
        #     |
2266
        #     F     Executable bit changed
2267
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2268
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2269
                               [('add', (u'', b'a-root-id', 'directory', None)),
2270
                                ('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
2271
                               revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2272
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2273
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2274
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2275
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2276
        # Have to use a real WT, because BranchBuilder doesn't support exec bit
2277
        wt = self.get_wt_from_builder(builder)
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
2278
        with wt.transform() as tt:
6885.1.1 by Jelmer Vernooij
Get rid of TreeTransform.trans_id_tree_file_id.
2279
            tt.set_executability(True, tt.trans_id_tree_path('foo'))
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2280
            tt.apply()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
2281
        self.assertTrue(wt.is_executable('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2282
        wt.commit('F-id', rev_id=b'F-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2283
        # Reset to D, so that we can merge F
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2284
        wt.set_parent_ids([b'D-id'])
2285
        wt.branch.set_last_revision_info(3, b'D-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2286
        wt.revert()
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
2287
        self.assertFalse(wt.is_executable('foo'))
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2288
        conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2289
        self.assertEqual(0, conflicts)
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
2290
        self.assertTrue(wt.is_executable('foo'))
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
2291
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2292
    def test_create_symlink(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2293
        self.requireFeature(features.SymlinkFeature)
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2294
        #   A
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2295
        #  / \
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2296
        # B   C
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2297
        # |\ /|
2298
        # | X |
2299
        # |/ \|
2300
        # D   E
2301
        #     |
2302
        #     F     Add a symlink 'foo' => 'bar'
2303
        # Have to use a real WT, because BranchBuilder and MemoryTree don't
2304
        # have symlink support
2305
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2306
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2307
                               [('add', (u'', b'a-root-id', 'directory', None))],
2308
                               revision_id=b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2309
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2310
        builder.build_snapshot([b'A-id'], [], revision_id=b'B-id')
2311
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2312
        builder.build_snapshot([b'C-id', b'B-id'], [], revision_id=b'E-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2313
        # Have to use a real WT, because BranchBuilder doesn't support exec bit
2314
        wt = self.get_wt_from_builder(builder)
2315
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2316
        wt.add(['foo'], [b'foo-id'])
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2317
        self.assertEqual('bar', wt.get_symlink_target('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2318
        wt.commit('add symlink', rev_id=b'F-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2319
        # Reset to D, so that we can merge F
6855.4.1 by Jelmer Vernooij
Yet more bees.
2320
        wt.set_parent_ids([b'D-id'])
2321
        wt.branch.set_last_revision_info(3, b'D-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2322
        wt.revert()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
2323
        self.assertFalse(wt.is_versioned('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2324
        conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2325
        self.assertEqual(0, conflicts)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2326
        self.assertEqual(b'foo-id', wt.path2id('foo'))
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2327
        self.assertEqual('bar', wt.get_symlink_target('foo'))
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2328
3514.4.30 by John Arbash Meinel
Several updates.
2329
    def test_both_sides_revert(self):
2330
        # Both sides of a criss-cross revert the text to the lca
2331
        #       A    base, introduces 'foo'
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2332
        #       |\
3514.4.30 by John Arbash Meinel
Several updates.
2333
        #       B C  B modifies 'foo', C modifies 'foo'
2334
        #       |X|
2335
        #       D E  D reverts to B, E reverts to C
2336
        # This should conflict
2337
        # This must be done with a real WorkingTree, because normally their
2338
        # inventory contains "None" rather than a real sha1
2339
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2340
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2341
                               [('add', (u'', b'a-root-id', 'directory', None)),
2342
                                ('add', (u'foo', b'foo-id', 'file', b'A content\n'))],
2343
                               revision_id=b'A-id')
2344
        builder.build_snapshot([b'A-id'],
2345
                               [('modify', ('foo', b'B content\n'))],
2346
                               revision_id=b'B-id')
2347
        builder.build_snapshot([b'A-id'],
2348
                               [('modify', ('foo', b'C content\n'))],
2349
                               revision_id=b'C-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2350
        builder.build_snapshot([b'C-id', b'B-id'], [],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2351
                               revision_id=b'E-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2352
        builder.build_snapshot([b'B-id', b'C-id'], [],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2353
                               revision_id=b'D-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2354
        wt, conflicts = self.do_merge(builder, b'E-id')
3514.4.30 by John Arbash Meinel
Several updates.
2355
        self.assertEqual(1, conflicts)
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2356
        self.assertEqualDiff(b'<<<<<<< TREE\n'
2357
                             b'B content\n'
2358
                             b'=======\n'
2359
                             b'C content\n'
2360
                             b'>>>>>>> MERGE-SOURCE\n',
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
2361
                             wt.get_file_text('foo'))
3514.4.30 by John Arbash Meinel
Several updates.
2362
3514.4.28 by John Arbash Meinel
More symlink tests.
2363
    def test_modified_symlink(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2364
        self.requireFeature(features.SymlinkFeature)
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2365
        #   A       Create symlink foo => bar
2366
        #  / \
2367
        # B   C     B relinks foo => baz
2368
        # |\ /|
2369
        # | X |
2370
        # |/ \|
2371
        # D   E     D & E have foo => baz
2372
        #     |
2373
        #     F     F changes it to bing
2374
        #
2375
        # Merging D & F should result in F cleanly overriding D, because D's
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2376
        # value actually comes from B
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2377
2378
        # Have to use a real WT, because BranchBuilder and MemoryTree don't
2379
        # have symlink support
2380
        wt = self.make_branch_and_tree('path')
2381
        wt.lock_write()
2382
        self.addCleanup(wt.unlock)
2383
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2384
        wt.add(['foo'], [b'foo-id'])
2385
        wt.commit('add symlink', rev_id=b'A-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2386
        os.remove('path/foo')
2387
        os.symlink('baz', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2388
        wt.commit('foo => baz', rev_id=b'B-id')
2389
        wt.set_last_revision(b'A-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2390
        wt.branch.set_last_revision_info(1, b'A-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2391
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2392
        wt.commit('C', rev_id=b'C-id')
2393
        wt.merge_from_branch(wt.branch, b'B-id')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2394
        self.assertEqual('baz', wt.get_symlink_target('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2395
        wt.commit('E merges C & B', rev_id=b'E-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2396
        os.remove('path/foo')
2397
        os.symlink('bing', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2398
        wt.commit('F foo => bing', rev_id=b'F-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2399
        wt.set_last_revision(b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2400
        wt.branch.set_last_revision_info(2, b'B-id')
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2401
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2402
        wt.merge_from_branch(wt.branch, b'C-id')
2403
        wt.commit('D merges B & C', rev_id=b'D-id')
2404
        conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
3948.1.7 by Vincent Ladeuil
Slight refactoring and test fixing.
2405
        self.assertEqual(0, conflicts)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2406
        self.assertEqual('bing', wt.get_symlink_target('foo'))
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
2407
3514.4.28 by John Arbash Meinel
More symlink tests.
2408
    def test_renamed_symlink(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2409
        self.requireFeature(features.SymlinkFeature)
3514.4.28 by John Arbash Meinel
More symlink tests.
2410
        #   A       Create symlink foo => bar
2411
        #  / \
2412
        # B   C     B renames foo => barry
2413
        # |\ /|
2414
        # | X |
2415
        # |/ \|
2416
        # D   E     D & E have barry
2417
        #     |
2418
        #     F     F renames barry to blah
2419
        #
2420
        # Merging D & F should result in F cleanly overriding D, because D's
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2421
        # value actually comes from B
3514.4.28 by John Arbash Meinel
More symlink tests.
2422
2423
        wt = self.make_branch_and_tree('path')
2424
        wt.lock_write()
2425
        self.addCleanup(wt.unlock)
2426
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2427
        wt.add(['foo'], [b'foo-id'])
2428
        wt.commit('A add symlink', rev_id=b'A-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2429
        wt.rename_one('foo', 'barry')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2430
        wt.commit('B foo => barry', rev_id=b'B-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2431
        wt.set_last_revision(b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2432
        wt.branch.set_last_revision_info(1, b'A-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2433
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2434
        wt.commit('C', rev_id=b'C-id')
2435
        wt.merge_from_branch(wt.branch, b'B-id')
2436
        self.assertEqual('barry', wt.id2path(b'foo-id'))
6809.4.9 by Jelmer Vernooij
Fix some more tests.
2437
        self.assertEqual('bar', wt.get_symlink_target('barry'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2438
        wt.commit('E merges C & B', rev_id=b'E-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2439
        wt.rename_one('barry', 'blah')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2440
        wt.commit('F barry => blah', rev_id=b'F-id')
2441
        wt.set_last_revision(b'B-id')
2442
        wt.branch.set_last_revision_info(2, b'B-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2443
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2444
        wt.merge_from_branch(wt.branch, b'C-id')
2445
        wt.commit('D merges B & C', rev_id=b'D-id')
2446
        self.assertEqual('barry', wt.id2path(b'foo-id'))
3514.4.28 by John Arbash Meinel
More symlink tests.
2447
        # Check the output of the Merger object directly
6855.4.1 by Jelmer Vernooij
Yet more bees.
2448
        merger = _mod_merge.Merger.from_revision_ids(wt, b'F-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2449
        merger.merge_type = _mod_merge.Merge3Merger
2450
        merge_obj = merger.make_merger()
2451
        root_id = wt.path2id('')
2452
        entries = list(merge_obj._entries_lca())
2453
        # No content change, just a path change
6855.4.1 by Jelmer Vernooij
Yet more bees.
2454
        self.assertEqual([(b'foo-id', False,
6928.1.2 by Jelmer Vernooij
Fix path specification.
2455
                           ((u'foo', [u'barry', u'foo']), u'blah', u'barry'),
3514.4.28 by John Arbash Meinel
More symlink tests.
2456
                           ((root_id, [root_id, root_id]), root_id, root_id),
2457
                           ((u'foo', [u'barry', u'foo']), u'blah', u'barry'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2458
                           ((False, [False, False]), False, False),
2459
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2460
                          ], entries)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2461
        conflicts = wt.merge_from_branch(wt.branch, to_revision=b'F-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2462
        self.assertEqual(0, conflicts)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2463
        self.assertEqual('blah', wt.id2path(b'foo-id'))
3514.4.28 by John Arbash Meinel
More symlink tests.
2464
2465
    def test_symlink_no_content_change(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2466
        self.requireFeature(features.SymlinkFeature)
3514.4.28 by John Arbash Meinel
More symlink tests.
2467
        #   A       Create symlink foo => bar
2468
        #  / \
2469
        # B   C     B relinks foo => baz
2470
        # |\ /|
2471
        # | X |
2472
        # |/ \|
2473
        # D   E     D & E have foo => baz
2474
        # |
2475
        # F         F has foo => bing
2476
        #
2477
        # Merging E into F should not cause a conflict, because E doesn't have
2478
        # a content change relative to the LCAs (it does relative to A)
2479
        wt = self.make_branch_and_tree('path')
2480
        wt.lock_write()
2481
        self.addCleanup(wt.unlock)
2482
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2483
        wt.add(['foo'], [b'foo-id'])
2484
        wt.commit('add symlink', rev_id=b'A-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2485
        os.remove('path/foo')
2486
        os.symlink('baz', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2487
        wt.commit('foo => baz', rev_id=b'B-id')
2488
        wt.set_last_revision(b'A-id')
2489
        wt.branch.set_last_revision_info(1, b'A-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2490
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2491
        wt.commit('C', rev_id=b'C-id')
2492
        wt.merge_from_branch(wt.branch, b'B-id')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2493
        self.assertEqual('baz', wt.get_symlink_target('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2494
        wt.commit('E merges C & B', rev_id=b'E-id')
2495
        wt.set_last_revision(b'B-id')
2496
        wt.branch.set_last_revision_info(2, b'B-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2497
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2498
        wt.merge_from_branch(wt.branch, b'C-id')
2499
        wt.commit('D merges B & C', rev_id=b'D-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2500
        os.remove('path/foo')
2501
        os.symlink('bing', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2502
        wt.commit('F foo => bing', rev_id=b'F-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2503
2504
        # Check the output of the Merger object directly
6855.4.1 by Jelmer Vernooij
Yet more bees.
2505
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2506
        merger.merge_type = _mod_merge.Merge3Merger
2507
        merge_obj = merger.make_merger()
2508
        # Nothing interesting happened in OTHER relative to BASE
2509
        self.assertEqual([], list(merge_obj._entries_lca()))
2510
        # Now do a real merge, just to test the rest of the stack
6855.4.1 by Jelmer Vernooij
Yet more bees.
2511
        conflicts = wt.merge_from_branch(wt.branch, to_revision=b'E-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2512
        self.assertEqual(0, conflicts)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2513
        self.assertEqual('bing', wt.get_symlink_target('foo'))
3514.4.28 by John Arbash Meinel
More symlink tests.
2514
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2515
    def test_symlink_this_changed_kind(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2516
        self.requireFeature(features.SymlinkFeature)
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2517
        #   A       Nothing
2518
        #  / \
2519
        # B   C     B creates symlink foo => bar
2520
        # |\ /|
2521
        # | X |
2522
        # |/ \|
2523
        # D   E     D changes foo into a file, E has foo => bing
2524
        #
2525
        # Mostly, this is trying to test that we don't try to os.readlink() on
2526
        # a file, or when there is nothing there
2527
        wt = self.make_branch_and_tree('path')
2528
        wt.lock_write()
2529
        self.addCleanup(wt.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2530
        wt.commit('base', rev_id=b'A-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2531
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2532
        wt.add(['foo'], [b'foo-id'])
2533
        wt.commit('add symlink foo => bar', rev_id=b'B-id')
2534
        wt.set_last_revision(b'A-id')
2535
        wt.branch.set_last_revision_info(1, b'A-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2536
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2537
        wt.commit('C', rev_id=b'C-id')
2538
        wt.merge_from_branch(wt.branch, b'B-id')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2539
        self.assertEqual('bar', wt.get_symlink_target('foo'))
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2540
        os.remove('path/foo')
2541
        # We have to change the link in E, or it won't try to do a comparison
2542
        os.symlink('bing', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2543
        wt.commit('E merges C & B, overrides to bing', rev_id=b'E-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2544
        wt.set_last_revision(b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2545
        wt.branch.set_last_revision_info(2, b'B-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2546
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2547
        wt.merge_from_branch(wt.branch, b'C-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2548
        os.remove('path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2549
        self.build_tree_contents([('path/foo', b'file content\n')])
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2550
        # XXX: workaround, WT doesn't detect kind changes unless you do
2551
        # iter_changes()
2552
        list(wt.iter_changes(wt.basis_tree()))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2553
        wt.commit('D merges B & C, makes it a file', rev_id=b'D-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2554
6855.4.1 by Jelmer Vernooij
Yet more bees.
2555
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2556
        merger.merge_type = _mod_merge.Merge3Merger
2557
        merge_obj = merger.make_merger()
2558
        entries = list(merge_obj._entries_lca())
2559
        root_id = wt.path2id('')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2560
        self.assertEqual([(b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2561
                           ((None, [u'foo', None]), u'foo', u'foo'),
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2562
                           ((None, [root_id, None]), root_id, root_id),
2563
                           ((None, [u'foo', None]), u'foo', u'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2564
                           ((None, [False, None]), False, False),
2565
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2566
                          ], entries)
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
2567
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2568
    def test_symlink_all_wt(self):
2569
        """Check behavior if all trees are Working Trees."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
2570
        self.requireFeature(features.SymlinkFeature)
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2571
        # The big issue is that entry.symlink_target is None for WorkingTrees.
2572
        # So we need to make sure we handle that case correctly.
2573
        #   A   foo => bar
2574
        #   |\
2575
        #   B C B relinks foo => baz
2576
        #   |X|
2577
        #   D E D & E have foo => baz
2578
        #     |
2579
        #     F F changes it to bing
2580
        # Merging D & F should result in F cleanly overriding D, because D's
2581
        # value actually comes from B
2582
2583
        wt = self.make_branch_and_tree('path')
2584
        wt.lock_write()
2585
        self.addCleanup(wt.unlock)
2586
        os.symlink('bar', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2587
        wt.add(['foo'], [b'foo-id'])
2588
        wt.commit('add symlink', rev_id=b'A-id')
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2589
        os.remove('path/foo')
2590
        os.symlink('baz', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2591
        wt.commit('foo => baz', rev_id=b'B-id')
2592
        wt.set_last_revision(b'A-id')
2593
        wt.branch.set_last_revision_info(1, b'A-id')
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2594
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2595
        wt.commit('C', rev_id=b'C-id')
2596
        wt.merge_from_branch(wt.branch, b'B-id')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
2597
        self.assertEqual('baz', wt.get_symlink_target('foo'))
6855.4.1 by Jelmer Vernooij
Yet more bees.
2598
        wt.commit('E merges C & B', rev_id=b'E-id')
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2599
        os.remove('path/foo')
2600
        os.symlink('bing', 'path/foo')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2601
        wt.commit('F foo => bing', rev_id=b'F-id')
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2602
        wt.set_last_revision(b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2603
        wt.branch.set_last_revision_info(2, b'B-id')
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2604
        wt.revert()
6855.4.1 by Jelmer Vernooij
Yet more bees.
2605
        wt.merge_from_branch(wt.branch, b'C-id')
2606
        wt.commit('D merges B & C', rev_id=b'D-id')
2607
        wt_base = wt.controldir.sprout('base', b'A-id').open_workingtree()
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2608
        wt_base.lock_read()
2609
        self.addCleanup(wt_base.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2610
        wt_lca1 = wt.controldir.sprout('b-tree', b'B-id').open_workingtree()
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2611
        wt_lca1.lock_read()
2612
        self.addCleanup(wt_lca1.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2613
        wt_lca2 = wt.controldir.sprout('c-tree', b'C-id').open_workingtree()
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2614
        wt_lca2.lock_read()
2615
        self.addCleanup(wt_lca2.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2616
        wt_other = wt.controldir.sprout('other', b'F-id').open_workingtree()
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2617
        wt_other.lock_read()
2618
        self.addCleanup(wt_other.unlock)
2619
        merge_obj = _mod_merge.Merge3Merger(wt, wt, wt_base,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2620
                                            wt_other, lca_trees=[wt_lca1, wt_lca2], do_merge=False)
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2621
        entries = list(merge_obj._entries_lca())
2622
        root_id = wt.path2id('')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2623
        self.assertEqual([(b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2624
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2625
                           ((root_id, [root_id, root_id]), root_id, root_id),
2626
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2627
                           ((False, [False, False]), False, False),
2628
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2629
                          ], entries)
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
2630
3514.4.25 by John Arbash Meinel
A few more merge-level behavior tests.
2631
    def test_other_reverted_path_to_base(self):
2632
        #   A       Path at 'foo'
2633
        #  / \
2634
        # B   C     Path at 'bar' in B
2635
        # |\ /|
2636
        # | X |
2637
        # |/ \|
2638
        # D   E     Path at 'bar'
2639
        #     |
2640
        #     F     Path at 'foo'
2641
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2642
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2643
                               [('add', (u'', b'a-root-id', 'directory', None)),
2644
                                ('add', (u'foo', b'foo-id', 'file', b'a\nb\nc\n'))],
2645
                               revision_id=b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2646
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2647
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2648
                               [('rename', ('foo', 'bar'))], revision_id=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2649
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2650
                               [('rename', ('foo', 'bar'))], revision_id=b'E-id')  # merge the rename
6855.4.1 by Jelmer Vernooij
Yet more bees.
2651
        builder.build_snapshot([b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2652
                               [('rename', ('bar', 'foo'))], revision_id=b'F-id')  # Rename back to BASE
6855.4.1 by Jelmer Vernooij
Yet more bees.
2653
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2654
        wt, conflicts = self.do_merge(builder, b'F-id')
3514.4.25 by John Arbash Meinel
A few more merge-level behavior tests.
2655
        self.assertEqual(0, conflicts)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2656
        self.assertEqual('foo', wt.id2path(b'foo-id'))
3514.4.25 by John Arbash Meinel
A few more merge-level behavior tests.
2657
2658
    def test_other_reverted_content_to_base(self):
2659
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2660
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2661
                               [('add', (u'', b'a-root-id', 'directory', None)),
2662
                                ('add', (u'foo', b'foo-id', 'file', b'base content\n'))],
2663
                               revision_id=b'A-id')
6883.22.11 by Jelmer Vernooij
merge trunk
2664
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2665
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2666
                               [('modify', ('foo', b'B content\n'))],
2667
                               revision_id=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2668
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2669
                               [('modify', ('foo', b'B content\n'))],
2670
                               revision_id=b'E-id')  # merge the content
6855.4.1 by Jelmer Vernooij
Yet more bees.
2671
        builder.build_snapshot([b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2672
                               [('modify', ('foo', b'base content\n'))],
2673
                               revision_id=b'F-id')  # Revert back to BASE
6855.4.1 by Jelmer Vernooij
Yet more bees.
2674
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2675
        wt, conflicts = self.do_merge(builder, b'F-id')
3514.4.25 by John Arbash Meinel
A few more merge-level behavior tests.
2676
        self.assertEqual(0, conflicts)
2677
        # TODO: We need to use the per-file graph to properly select a BASE
3514.4.26 by John Arbash Meinel
Clean up comments, only symlink support left.
2678
        #       before this will work. Or at least use the LCA trees to find
2679
        #       the appropriate content base. (which is B, not A).
6973.7.3 by Jelmer Vernooij
Fix some more tests.
2680
        self.assertEqual(b'base content\n', wt.get_file_text('foo'))
3514.4.25 by John Arbash Meinel
A few more merge-level behavior tests.
2681
3514.4.28 by John Arbash Meinel
More symlink tests.
2682
    def test_other_modified_content(self):
2683
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2684
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2685
                               [('add', (u'', b'a-root-id', 'directory', None)),
2686
                                ('add', (u'foo', b'foo-id', 'file', b'base content\n'))],
2687
                               revision_id=b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2688
        builder.build_snapshot([b'A-id'], [], revision_id=b'C-id')
2689
        builder.build_snapshot([b'A-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2690
                               [('modify', ('foo', b'B content\n'))],
2691
                               revision_id=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2692
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2693
                               [('modify', ('foo', b'B content\n'))],
2694
                               revision_id=b'E-id')  # merge the content
6855.4.1 by Jelmer Vernooij
Yet more bees.
2695
        builder.build_snapshot([b'E-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2696
                               [('modify', ('foo', b'F content\n'))],
2697
                               revision_id=b'F-id')  # Override B content
6855.4.1 by Jelmer Vernooij
Yet more bees.
2698
        builder.build_snapshot([b'B-id', b'C-id'], [], revision_id=b'D-id')
2699
        wt, conflicts = self.do_merge(builder, b'F-id')
3514.4.28 by John Arbash Meinel
More symlink tests.
2700
        self.assertEqual(0, conflicts)
6883.22.11 by Jelmer Vernooij
merge trunk
2701
        self.assertEqual(b'F content\n', wt.get_file_text('foo'))
3514.4.28 by John Arbash Meinel
More symlink tests.
2702
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2703
    def test_all_wt(self):
2704
        """Check behavior if all trees are Working Trees."""
2705
        # The big issue is that entry.revision is None for WorkingTrees. (as is
2706
        # entry.text_sha1, etc. So we need to make sure we handle that case
2707
        # correctly.
2708
        #   A   Content of 'foo', path of 'a'
2709
        #   |\
2710
        #   B C B modifies content, C renames 'a' => 'b'
2711
        #   |X|
2712
        #   D E E updates content, renames 'b' => 'c'
2713
        builder = self.get_builder()
6816.2.3 by Jelmer Vernooij
Port over last uses of build_snapshot.
2714
        builder.build_snapshot(None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2715
                               [('add', (u'', b'a-root-id', 'directory', None)),
2716
                                ('add', (u'a', b'a-id', 'file', b'base content\n')),
2717
                                   ('add', (u'foo', b'foo-id', 'file', b'base content\n'))],
2718
                               revision_id=b'A-id')
2719
        builder.build_snapshot([b'A-id'],
2720
                               [('modify', ('foo', b'B content\n'))],
2721
                               revision_id=b'B-id')
2722
        builder.build_snapshot([b'A-id'],
2723
                               [('rename', ('a', 'b'))],
2724
                               revision_id=b'C-id')
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2725
        builder.build_snapshot([b'C-id', b'B-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2726
                               [('rename', ('b', 'c')),
2727
                                ('modify', ('foo', b'E content\n'))],
2728
                               revision_id=b'E-id')
6973.11.9 by Jelmer Vernooij
Fix tests.
2729
        builder.build_snapshot([b'B-id', b'C-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
2730
                               [('rename', ('a', 'b'))], revision_id=b'D-id')  # merged change
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2731
        wt_this = self.get_wt_from_builder(builder)
6973.11.9 by Jelmer Vernooij
Fix tests.
2732
        wt_base = wt_this.controldir.sprout('base', b'A-id').open_workingtree()
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2733
        wt_base.lock_read()
2734
        self.addCleanup(wt_base.unlock)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2735
        wt_lca1 = wt_this.controldir.sprout(
2736
            'b-tree', b'B-id').open_workingtree()
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2737
        wt_lca1.lock_read()
2738
        self.addCleanup(wt_lca1.unlock)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2739
        wt_lca2 = wt_this.controldir.sprout(
2740
            'c-tree', b'C-id').open_workingtree()
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2741
        wt_lca2.lock_read()
2742
        self.addCleanup(wt_lca2.unlock)
7143.15.2 by Jelmer Vernooij
Run autopep8.
2743
        wt_other = wt_this.controldir.sprout(
2744
            'other', b'E-id').open_workingtree()
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2745
        wt_other.lock_read()
2746
        self.addCleanup(wt_other.unlock)
2747
        merge_obj = _mod_merge.Merge3Merger(wt_this, wt_this, wt_base,
7143.15.2 by Jelmer Vernooij
Run autopep8.
2748
                                            wt_other, lca_trees=[wt_lca1, wt_lca2], do_merge=False)
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2749
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2750
        root_id = b'a-root-id'
2751
        self.assertEqual([(b'a-id', False,
6928.1.4 by Jelmer Vernooij
Fix remaining tests.
2752
                           ((u'a', [u'a', u'b']), u'c', u'b'),
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2753
                           ((root_id, [root_id, root_id]), root_id, root_id),
2754
                           ((u'a', [u'a', u'b']), u'c', u'b'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2755
                           ((False, [False, False]), False, False),
2756
                           False),
6973.11.9 by Jelmer Vernooij
Fix tests.
2757
                          (b'foo-id', True,
6883.10.1 by Jelmer Vernooij
Fix more tets.
2758
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2759
                           ((root_id, [root_id, root_id]), root_id, root_id),
2760
                           ((u'foo', [u'foo', u'foo']), u'foo', u'foo'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2761
                           ((False, [False, False]), False, False),
2762
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2763
                          ], entries)
3514.4.32 by John Arbash Meinel
Add a test for proper behavior when *everything* is a WT.
2764
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2765
    def test_nested_tree_unmodified(self):
2766
        # Tested with a real WT, because BranchBuilder/MemoryTree don't handle
2767
        # 'tree-reference'
2768
        wt = self.make_branch_and_tree('tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2769
                                       format='development-subtree')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2770
        wt.lock_write()
2771
        self.addCleanup(wt.unlock)
2772
        sub_tree = self.make_branch_and_tree('tree/sub-tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2773
                                             format='development-subtree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2774
        wt.set_root_id(b'a-root-id')
2775
        sub_tree.set_root_id(b'sub-tree-root')
2776
        self.build_tree_contents([('tree/sub-tree/file', b'text1')])
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2777
        sub_tree.add('file')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2778
        sub_tree.commit('foo', rev_id=b'sub-A-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2779
        wt.add_reference(sub_tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2780
        wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2781
        # Now create a criss-cross merge in the parent, without modifying the
2782
        # subtree
6855.4.1 by Jelmer Vernooij
Yet more bees.
2783
        wt.commit('B', rev_id=b'B-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2784
        wt.set_last_revision(b'A-id')
2785
        wt.branch.set_last_revision_info(1, b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2786
        wt.commit('C', rev_id=b'C-id', recursive=None)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
2787
        wt.merge_from_branch(wt.branch, to_revision=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2788
        wt.commit('E', rev_id=b'E-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2789
        wt.set_parent_ids([b'B-id', b'C-id'])
2790
        wt.branch.set_last_revision_info(2, b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2791
        wt.commit('D', rev_id=b'D-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2792
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2793
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2794
        merger.merge_type = _mod_merge.Merge3Merger
2795
        merge_obj = merger.make_merger()
2796
        entries = list(merge_obj._entries_lca())
2797
        self.assertEqual([], entries)
2798
2799
    def test_nested_tree_subtree_modified(self):
2800
        # Tested with a real WT, because BranchBuilder/MemoryTree don't handle
2801
        # 'tree-reference'
2802
        wt = self.make_branch_and_tree('tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2803
                                       format='development-subtree')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2804
        wt.lock_write()
2805
        self.addCleanup(wt.unlock)
2806
        sub_tree = self.make_branch_and_tree('tree/sub',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2807
                                             format='development-subtree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2808
        wt.set_root_id(b'a-root-id')
2809
        sub_tree.set_root_id(b'sub-tree-root')
2810
        self.build_tree_contents([('tree/sub/file', b'text1')])
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2811
        sub_tree.add('file')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2812
        sub_tree.commit('foo', rev_id=b'sub-A-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2813
        wt.add_reference(sub_tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2814
        wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2815
        # Now create a criss-cross merge in the parent, without modifying the
2816
        # subtree
6855.4.1 by Jelmer Vernooij
Yet more bees.
2817
        wt.commit('B', rev_id=b'B-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2818
        wt.set_last_revision(b'A-id')
2819
        wt.branch.set_last_revision_info(1, b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2820
        wt.commit('C', rev_id=b'C-id', recursive=None)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
2821
        wt.merge_from_branch(wt.branch, to_revision=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2822
        self.build_tree_contents([('tree/sub/file', b'text2')])
2823
        sub_tree.commit('modify contents', rev_id=b'sub-B-id')
2824
        wt.commit('E', rev_id=b'E-id', recursive=None)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
2825
        wt.set_parent_ids([b'B-id', b'C-id'])
6973.10.6 by Jelmer Vernooij
Fix tests.
2826
        wt.branch.set_last_revision_info(2, b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2827
        wt.commit('D', rev_id=b'D-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2828
6973.10.6 by Jelmer Vernooij
Fix tests.
2829
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2830
        merger.merge_type = _mod_merge.Merge3Merger
2831
        merge_obj = merger.make_merger()
2832
        entries = list(merge_obj._entries_lca())
2833
        # Nothing interesting about this sub-tree, because content changes are
2834
        # computed at a higher level
2835
        self.assertEqual([], entries)
2836
2837
    def test_nested_tree_subtree_renamed(self):
2838
        # Tested with a real WT, because BranchBuilder/MemoryTree don't handle
2839
        # 'tree-reference'
2840
        wt = self.make_branch_and_tree('tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2841
                                       format='development-subtree')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2842
        wt.lock_write()
2843
        self.addCleanup(wt.unlock)
2844
        sub_tree = self.make_branch_and_tree('tree/sub',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2845
                                             format='development-subtree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2846
        wt.set_root_id(b'a-root-id')
2847
        sub_tree.set_root_id(b'sub-tree-root')
2848
        self.build_tree_contents([('tree/sub/file', b'text1')])
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2849
        sub_tree.add('file')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2850
        sub_tree.commit('foo', rev_id=b'sub-A-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2851
        wt.add_reference(sub_tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2852
        wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2853
        # Now create a criss-cross merge in the parent, without modifying the
2854
        # subtree
6855.4.1 by Jelmer Vernooij
Yet more bees.
2855
        wt.commit('B', rev_id=b'B-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2856
        wt.set_last_revision(b'A-id')
2857
        wt.branch.set_last_revision_info(1, b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2858
        wt.commit('C', rev_id=b'C-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2859
        wt.merge_from_branch(wt.branch, to_revision=b'B-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2860
        wt.rename_one('sub', 'alt_sub')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2861
        wt.commit('E', rev_id=b'E-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2862
        wt.set_last_revision(b'B-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2863
        wt.revert()
6973.10.6 by Jelmer Vernooij
Fix tests.
2864
        wt.set_parent_ids([b'B-id', b'C-id'])
2865
        wt.branch.set_last_revision_info(2, b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2866
        wt.commit('D', rev_id=b'D-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2867
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2868
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2869
        merger.merge_type = _mod_merge.Merge3Merger
2870
        merge_obj = merger.make_merger()
2871
        entries = list(merge_obj._entries_lca())
6973.11.5 by Jelmer Vernooij
Update python3.passing.
2872
        root_id = b'a-root-id'
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
2873
        self.assertEqual([(b'sub-tree-root', False,
6928.1.4 by Jelmer Vernooij
Fix remaining tests.
2874
                           ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'),
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2875
                           ((root_id, [root_id, root_id]), root_id, root_id),
2876
                           ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2877
                           ((False, [False, False]), False, False),
2878
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2879
                          ], entries)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2880
2881
    def test_nested_tree_subtree_renamed_and_modified(self):
2882
        # Tested with a real WT, because BranchBuilder/MemoryTree don't handle
2883
        # 'tree-reference'
2884
        wt = self.make_branch_and_tree('tree',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2885
                                       format='development-subtree')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2886
        wt.lock_write()
2887
        self.addCleanup(wt.unlock)
2888
        sub_tree = self.make_branch_and_tree('tree/sub',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2889
                                             format='development-subtree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2890
        wt.set_root_id(b'a-root-id')
2891
        sub_tree.set_root_id(b'sub-tree-root')
2892
        self.build_tree_contents([('tree/sub/file', b'text1')])
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2893
        sub_tree.add('file')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2894
        sub_tree.commit('foo', rev_id=b'sub-A-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2895
        wt.add_reference(sub_tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
2896
        wt.commit('set text to 1', rev_id=b'A-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2897
        # Now create a criss-cross merge in the parent, without modifying the
2898
        # subtree
6855.4.1 by Jelmer Vernooij
Yet more bees.
2899
        wt.commit('B', rev_id=b'B-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2900
        wt.set_last_revision(b'A-id')
2901
        wt.branch.set_last_revision_info(1, b'A-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2902
        wt.commit('C', rev_id=b'C-id', recursive=None)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
2903
        wt.merge_from_branch(wt.branch, to_revision=b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2904
        self.build_tree_contents([('tree/sub/file', b'text2')])
2905
        sub_tree.commit('modify contents', rev_id=b'sub-B-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2906
        wt.rename_one('sub', 'alt_sub')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2907
        wt.commit('E', rev_id=b'E-id', recursive=None)
6973.10.6 by Jelmer Vernooij
Fix tests.
2908
        wt.set_last_revision(b'B-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2909
        wt.revert()
6973.10.6 by Jelmer Vernooij
Fix tests.
2910
        wt.set_parent_ids([b'B-id', b'C-id'])
2911
        wt.branch.set_last_revision_info(2, b'B-id')
6855.4.1 by Jelmer Vernooij
Yet more bees.
2912
        wt.commit('D', rev_id=b'D-id', recursive=None)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2913
6973.10.6 by Jelmer Vernooij
Fix tests.
2914
        merger = _mod_merge.Merger.from_revision_ids(wt, b'E-id')
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2915
        merger.merge_type = _mod_merge.Merge3Merger
2916
        merge_obj = merger.make_merger()
2917
        entries = list(merge_obj._entries_lca())
6973.10.6 by Jelmer Vernooij
Fix tests.
2918
        root_id = b'a-root-id'
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
2919
        self.assertEqual([(b'sub-tree-root', False,
6928.1.4 by Jelmer Vernooij
Fix remaining tests.
2920
                           ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'),
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2921
                           ((root_id, [root_id, root_id]), root_id, root_id),
2922
                           ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'),
7490.134.2 by Jelmer Vernooij
Fix tests.
2923
                           ((False, [False, False]), False, False),
2924
                           False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
2925
                          ], entries)
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
2926
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2927
2928
class TestLCAMultiWay(tests.TestCase):
2929
3514.4.30 by John Arbash Meinel
Several updates.
2930
    def assertLCAMultiWay(self, expected, base, lcas, other, this,
2931
                          allow_overriding_lca=True):
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2932
        self.assertEqual(expected, _mod_merge.Merge3Merger._lca_multi_way(
7143.15.2 by Jelmer Vernooij
Run autopep8.
2933
            (base, lcas), other, this,
2934
            allow_overriding_lca=allow_overriding_lca))
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2935
2936
    def test_other_equal_equal_lcas(self):
2937
        """Test when OTHER=LCA and all LCAs are identical."""
2938
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2939
                               'bval', ['bval', 'bval'], 'bval', 'bval')
2940
        self.assertLCAMultiWay('this',
2941
                               'bval', ['lcaval', 'lcaval'], 'lcaval', 'bval')
2942
        self.assertLCAMultiWay('this',
2943
                               'bval', ['lcaval', 'lcaval', 'lcaval'], 'lcaval', 'bval')
2944
        self.assertLCAMultiWay('this',
2945
                               'bval', ['lcaval', 'lcaval', 'lcaval'], 'lcaval', 'tval')
2946
        self.assertLCAMultiWay('this',
2947
                               'bval', ['lcaval', 'lcaval', 'lcaval'], 'lcaval', None)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2948
2949
    def test_other_equal_this(self):
2950
        """Test when other and this are identical."""
2951
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2952
                               'bval', ['bval', 'bval'], 'oval', 'oval')
2953
        self.assertLCAMultiWay('this',
2954
                               'bval', ['lcaval', 'lcaval'], 'oval', 'oval')
2955
        self.assertLCAMultiWay('this',
2956
                               'bval', ['cval', 'dval'], 'oval', 'oval')
2957
        self.assertLCAMultiWay('this',
2958
                               'bval', [None, 'lcaval'], 'oval', 'oval')
2959
        self.assertLCAMultiWay('this',
2960
                               None, [None, 'lcaval'], 'oval', 'oval')
2961
        self.assertLCAMultiWay('this',
2962
                               None, ['lcaval', 'lcaval'], 'oval', 'oval')
2963
        self.assertLCAMultiWay('this',
2964
                               None, ['cval', 'dval'], 'oval', 'oval')
2965
        self.assertLCAMultiWay('this',
2966
                               None, ['cval', 'dval'], None, None)
2967
        self.assertLCAMultiWay('this',
2968
                               None, ['cval', 'dval', 'eval', 'fval'], 'oval', 'oval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2969
2970
    def test_no_lcas(self):
2971
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2972
                               'bval', [], 'bval', 'tval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2973
        self.assertLCAMultiWay('other',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2974
                               'bval', [], 'oval', 'bval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2975
        self.assertLCAMultiWay('conflict',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2976
                               'bval', [], 'oval', 'tval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2977
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2978
                               'bval', [], 'oval', 'oval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2979
2980
    def test_lca_supersedes_other_lca(self):
2981
        """If one lca == base, the other lca takes precedence"""
2982
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2983
                               'bval', ['bval', 'lcaval'], 'lcaval', 'tval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2984
        self.assertLCAMultiWay('this',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2985
                               'bval', ['bval', 'lcaval'], 'lcaval', 'bval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2986
        # This is actually considered a 'revert' because the 'lcaval' in LCAS
2987
        # supersedes the BASE val (in the other LCA) but then OTHER reverts it
2988
        # back to bval.
2989
        self.assertLCAMultiWay('other',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2990
                               'bval', ['bval', 'lcaval'], 'bval', 'lcaval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2991
        self.assertLCAMultiWay('conflict',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2992
                               'bval', ['bval', 'lcaval'], 'bval', 'tval')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
2993
2994
    def test_other_and_this_pick_different_lca(self):
2995
        # OTHER and THIS resolve the lca conflict in different ways
2996
        self.assertLCAMultiWay('conflict',
7143.15.2 by Jelmer Vernooij
Run autopep8.
2997
                               'bval', ['lca1val', 'lca2val'], 'lca1val', 'lca2val')
2998
        self.assertLCAMultiWay('conflict',
2999
                               'bval', ['lca1val', 'lca2val', 'lca3val'], 'lca1val', 'lca2val')
3000
        self.assertLCAMultiWay('conflict',
3001
                               'bval', ['lca1val', 'lca2val', 'bval'], 'lca1val', 'lca2val')
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
3002
3003
    def test_other_in_lca(self):
3004
        # OTHER takes a value of one of the LCAs, THIS takes a new value, which
3005
        # theoretically supersedes both LCA values and 'wins'
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3006
        self.assertLCAMultiWay(
3007
            'this', 'bval', ['lca1val', 'lca2val'], 'lca1val', 'newval')
3008
        self.assertLCAMultiWay(
3009
            'this', 'bval', ['lca1val', 'lca2val', 'lca3val'], 'lca1val',
3010
            'newval')
7143.15.2 by Jelmer Vernooij
Run autopep8.
3011
        self.assertLCAMultiWay('conflict',
3012
                               'bval', ['lca1val',
3013
                                        'lca2val'], 'lca1val', 'newval',
3014
                               allow_overriding_lca=False)
3015
        self.assertLCAMultiWay('conflict',
3016
                               'bval', ['lca1val', 'lca2val',
3017
                                        'lca3val'], 'lca1val', 'newval',
3018
                               allow_overriding_lca=False)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
3019
        # THIS reverted back to BASE, but that is an explicit supersede of all
3020
        # LCAs
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3021
        self.assertLCAMultiWay(
3022
            'this', 'bval', ['lca1val', 'lca2val', 'lca3val'], 'lca1val',
3023
            'bval')
3024
        self.assertLCAMultiWay(
3025
            'this', 'bval', ['lca1val', 'lca2val', 'bval'], 'lca1val', 'bval')
7143.15.2 by Jelmer Vernooij
Run autopep8.
3026
        self.assertLCAMultiWay('conflict',
3027
                               'bval', ['lca1val', 'lca2val',
3028
                                        'lca3val'], 'lca1val', 'bval',
3029
                               allow_overriding_lca=False)
3030
        self.assertLCAMultiWay('conflict',
3031
                               'bval', ['lca1val', 'lca2val',
3032
                                        'bval'], 'lca1val', 'bval',
3033
                               allow_overriding_lca=False)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
3034
3035
    def test_this_in_lca(self):
3036
        # THIS takes a value of one of the LCAs, OTHER takes a new value, which
3037
        # theoretically supersedes both LCA values and 'wins'
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3038
        self.assertLCAMultiWay(
3039
            'other', 'bval', ['lca1val', 'lca2val'], 'oval', 'lca1val')
3040
        self.assertLCAMultiWay(
3041
            'other', 'bval', ['lca1val', 'lca2val'], 'oval', 'lca2val')
7143.15.2 by Jelmer Vernooij
Run autopep8.
3042
        self.assertLCAMultiWay('conflict',
3043
                               'bval', ['lca1val',
3044
                                        'lca2val'], 'oval', 'lca1val',
3045
                               allow_overriding_lca=False)
3046
        self.assertLCAMultiWay('conflict',
3047
                               'bval', ['lca1val',
3048
                                        'lca2val'], 'oval', 'lca2val',
3049
                               allow_overriding_lca=False)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
3050
        # OTHER reverted back to BASE, but that is an explicit supersede of all
3051
        # LCAs
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3052
        self.assertLCAMultiWay(
3053
            'other', 'bval', ['lca1val', 'lca2val', 'lca3val'], 'bval',
3054
            'lca3val')
3055
        self.assertLCAMultiWay(
3056
            'conflict', 'bval', ['lca1val', 'lca2val', 'lca3val'],
3057
            'bval', 'lca3val', allow_overriding_lca=False)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
3058
3059
    def test_all_differ(self):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3060
        self.assertLCAMultiWay(
3061
            'conflict', 'bval', ['lca1val', 'lca2val'], 'oval', 'tval')
3062
        self.assertLCAMultiWay(
3063
            'conflict', 'bval', ['lca1val', 'lca2val', 'lca2val'], 'oval',
3064
            'tval')
3065
        self.assertLCAMultiWay(
3066
            'conflict', 'bval', ['lca1val', 'lca2val', 'lca3val'], 'oval',
3067
            'tval')
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3068
3069
3070
class TestConfigurableFileMerger(tests.TestCaseWithTransport):
3071
4797.9.2 by Vincent Ladeuil
More tests.
3072
    def setUp(self):
3073
        super(TestConfigurableFileMerger, self).setUp()
3074
        self.calls = []
3075
3076
    def get_merger_factory(self):
3077
        # Allows  the inner methods to access the test attributes
5340.15.1 by John Arbash Meinel
supersede exc-info branch
3078
        calls = self.calls
4797.9.2 by Vincent Ladeuil
More tests.
3079
3080
        class FooMerger(_mod_merge.ConfigurableFileMerger):
4797.5.3 by Robert Collins
Tweak ConfigurableFileMerger to use class variables rather than requiring __init__ wrapping as future proofing for helper functions.
3081
            name_prefix = "foo"
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
3082
            default_files = ['bar']
4797.9.2 by Vincent Ladeuil
More tests.
3083
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3084
            def merge_text(self, params):
5340.15.1 by John Arbash Meinel
supersede exc-info branch
3085
                calls.append('merge_text')
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
3086
                return ('not_applicable', None)
4797.9.2 by Vincent Ladeuil
More tests.
3087
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3088
        def factory(merger):
4797.9.2 by Vincent Ladeuil
More tests.
3089
            result = FooMerger(merger)
3090
            # Make sure we start with a clean slate
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3091
            self.assertEqual(None, result.affected_files)
4797.9.2 by Vincent Ladeuil
More tests.
3092
            # Track the original merger
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3093
            self.merger = result
3094
            return result
4797.9.2 by Vincent Ladeuil
More tests.
3095
3096
        return factory
3097
3098
    def _install_hook(self, factory):
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3099
        _mod_merge.Merger.hooks.install_named_hook('merge_file_content',
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
3100
                                                   factory, 'test factory')
4797.9.2 by Vincent Ladeuil
More tests.
3101
3102
    def make_builder(self):
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3103
        builder = test_merge_core.MergeBuilder(self.test_base_dir)
3104
        self.addCleanup(builder.cleanup)
4797.9.2 by Vincent Ladeuil
More tests.
3105
        return builder
3106
3107
    def make_text_conflict(self, file_name='bar'):
3108
        factory = self.get_merger_factory()
3109
        self._install_hook(factory)
3110
        builder = self.make_builder()
7143.15.2 by Jelmer Vernooij
Run autopep8.
3111
        builder.add_file(b'bar-id', builder.tree_root,
3112
                         file_name, b'text1', True)
6973.11.5 by Jelmer Vernooij
Update python3.passing.
3113
        builder.change_contents(b'bar-id', other=b'text4', this=b'text3')
4797.9.2 by Vincent Ladeuil
More tests.
3114
        return builder
3115
3116
    def make_kind_change(self):
3117
        factory = self.get_merger_factory()
3118
        self._install_hook(factory)
3119
        builder = self.make_builder()
6973.11.5 by Jelmer Vernooij
Update python3.passing.
3120
        builder.add_file(b'bar-id', builder.tree_root, 'bar', b'text1', True,
4797.9.2 by Vincent Ladeuil
More tests.
3121
                         this=False)
7058.4.1 by Jelmer Vernooij
Fix another 40 tests.
3122
        builder.add_dir(b'bar-dir', builder.tree_root, 'bar-id',
4797.9.2 by Vincent Ladeuil
More tests.
3123
                        base=False, other=False)
3124
        return builder
3125
4797.21.1 by Aaron Bentley
Fix merge when this_tree is not a WorkingTree.
3126
    def test_uses_this_branch(self):
3127
        builder = self.make_text_conflict()
7350.3.4 by Jelmer Vernooij
Use context managers.
3128
        with builder.make_preview_transform() as tt:
3129
            pass
4797.21.1 by Aaron Bentley
Fix merge when this_tree is not a WorkingTree.
3130
4797.9.2 by Vincent Ladeuil
More tests.
3131
    def test_affected_files_cached(self):
3132
        """Ensures that the config variable is cached"""
3133
        builder = self.make_text_conflict()
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
3134
        conflicts = builder.merge()
3135
        # The hook should set the variable
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
3136
        self.assertEqual(['bar'], self.merger.affected_files)
4797.9.2 by Vincent Ladeuil
More tests.
3137
        self.assertEqual(1, len(conflicts))
3138
3139
    def test_hook_called_for_text_conflicts(self):
3140
        builder = self.make_text_conflict()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3141
        builder.merge()
4797.9.2 by Vincent Ladeuil
More tests.
3142
        # The hook should call the merge_text() method
3143
        self.assertEqual(['merge_text'], self.calls)
3144
3145
    def test_hook_not_called_for_kind_change(self):
3146
        builder = self.make_kind_change()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3147
        builder.merge()
4797.9.2 by Vincent Ladeuil
More tests.
3148
        # The hook should not call the merge_text() method
3149
        self.assertEqual([], self.calls)
3150
3151
    def test_hook_not_called_for_other_files(self):
3152
        builder = self.make_text_conflict('foobar')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3153
        builder.merge()
4797.9.2 by Vincent Ladeuil
More tests.
3154
        # The hook should not call the merge_text() method
3155
        self.assertEqual([], self.calls)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3156
3157
3158
class TestMergeIntoBase(tests.TestCaseWithTransport):
3159
3160
    def setup_simple_branch(self, relpath, shape=None, root_id=None):
3161
        """One commit, containing tree specified by optional shape.
7143.15.2 by Jelmer Vernooij
Run autopep8.
3162
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3163
        Default is empty tree (just root entry).
3164
        """
3165
        if root_id is None:
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3166
            root_id = b'%s-root-id' % (relpath.encode('ascii'),)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3167
        wt = self.make_branch_and_tree(relpath)
3168
        wt.set_root_id(root_id)
3169
        if shape is not None:
3170
            adjusted_shape = [relpath + '/' + elem for elem in shape]
3171
            self.build_tree(adjusted_shape)
6973.11.5 by Jelmer Vernooij
Update python3.passing.
3172
            ids = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
3173
                (b'%s-%s-id' % (relpath.encode('utf-8'),
3174
                                basename(elem.rstrip('/')).encode('ascii')))
6973.11.5 by Jelmer Vernooij
Update python3.passing.
3175
                for elem in shape]
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3176
            wt.add(shape, ids=ids)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3177
        rev_id = b'r1-%s' % (relpath.encode('utf-8'),)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3178
        wt.commit("Initial commit of %s" % (relpath,), rev_id=rev_id)
3179
        self.assertEqual(root_id, wt.path2id(''))
3180
        return wt
3181
3182
    def setup_two_branches(self, custom_root_ids=True):
3183
        """Setup 2 branches, one will be a library, the other a project."""
3184
        if custom_root_ids:
3185
            root_id = None
3186
        else:
3187
            root_id = inventory.ROOT_ID
3188
        project_wt = self.setup_simple_branch(
3189
            'project', ['README', 'dir/', 'dir/file.c'],
3190
            root_id)
3191
        lib_wt = self.setup_simple_branch(
3192
            'lib1', ['README', 'Makefile', 'foo.c'], root_id)
3193
3194
        return project_wt, lib_wt
3195
3196
    def do_merge_into(self, location, merge_as):
3197
        """Helper for using MergeIntoMerger.
7143.15.2 by Jelmer Vernooij
Run autopep8.
3198
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3199
        :param location: location of directory to merge from, either the
3200
            location of a branch or of a path inside a branch.
3201
        :param merge_as: the path in a tree to add the new directory as.
3202
        :returns: the conflicts from 'do_merge'.
3203
        """
7479.2.1 by Jelmer Vernooij
Drop python2 support.
3204
        with contextlib.ExitStack() as stack:
7356.1.1 by Jelmer Vernooij
Use ExitStack context rather than brz-specific OperationWithCleanup.
3205
            # Open and lock the various tree and branch objects
3206
            wt, subdir_relpath = WorkingTree.open_containing(merge_as)
3207
            stack.enter_context(wt.lock_write())
3208
            branch_to_merge, subdir_to_merge = _mod_branch.Branch.open_containing(
3209
                location)
3210
            stack.enter_context(branch_to_merge.lock_read())
3211
            other_tree = branch_to_merge.basis_tree()
3212
            stack.enter_context(other_tree.lock_read())
3213
            # Perform the merge
3214
            merger = _mod_merge.MergeIntoMerger(
3215
                this_tree=wt, other_tree=other_tree, other_branch=branch_to_merge,
3216
                target_subdir=subdir_relpath, source_subpath=subdir_to_merge)
3217
            merger.set_base_revision(_mod_revision.NULL_REVISION, branch_to_merge)
3218
            conflicts = merger.do_merge()
3219
            merger.set_pending()
3220
            return conflicts
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3221
3222
    def assertTreeEntriesEqual(self, expected_entries, tree):
3223
        """Assert that 'tree' contains the expected inventory entries.
3224
3225
        :param expected_entries: sequence of (path, file-id) pairs.
3226
        """
3227
        files = [(path, ie.file_id) for path, ie in tree.iter_entries_by_dir()]
3228
        self.assertEqual(expected_entries, files)
3229
3230
3231
class TestMergeInto(TestMergeIntoBase):
3232
3233
    def test_newdir_with_unique_roots(self):
3234
        """Merge a branch with a unique root into a new directory."""
3235
        project_wt, lib_wt = self.setup_two_branches()
3236
        self.do_merge_into('lib1', 'project/lib1')
3237
        project_wt.lock_read()
3238
        self.addCleanup(project_wt.unlock)
3239
        # The r1-lib1 revision should be merged into this one
7143.15.2 by Jelmer Vernooij
Run autopep8.
3240
        self.assertEqual([b'r1-project', b'r1-lib1'],
3241
                         project_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3242
        self.assertTreeEntriesEqual(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3243
            [('', b'project-root-id'),
3244
             ('README', b'project-README-id'),
3245
             ('dir', b'project-dir-id'),
3246
             ('lib1', b'lib1-root-id'),
3247
             ('dir/file.c', b'project-file.c-id'),
3248
             ('lib1/Makefile', b'lib1-Makefile-id'),
3249
             ('lib1/README', b'lib1-README-id'),
3250
             ('lib1/foo.c', b'lib1-foo.c-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3251
             ], project_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3252
3253
    def test_subdir(self):
3254
        """Merge a branch into a subdirectory of an existing directory."""
3255
        project_wt, lib_wt = self.setup_two_branches()
3256
        self.do_merge_into('lib1', 'project/dir/lib1')
3257
        project_wt.lock_read()
3258
        self.addCleanup(project_wt.unlock)
3259
        # The r1-lib1 revision should be merged into this one
7143.15.2 by Jelmer Vernooij
Run autopep8.
3260
        self.assertEqual([b'r1-project', b'r1-lib1'],
3261
                         project_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3262
        self.assertTreeEntriesEqual(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3263
            [('', b'project-root-id'),
3264
             ('README', b'project-README-id'),
3265
             ('dir', b'project-dir-id'),
3266
             ('dir/file.c', b'project-file.c-id'),
3267
             ('dir/lib1', b'lib1-root-id'),
3268
             ('dir/lib1/Makefile', b'lib1-Makefile-id'),
3269
             ('dir/lib1/README', b'lib1-README-id'),
3270
             ('dir/lib1/foo.c', b'lib1-foo.c-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3271
             ], project_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3272
3273
    def test_newdir_with_repeat_roots(self):
3274
        """If the file-id of the dir to be merged already exists a new ID will
3275
        be allocated to let the merge happen.
3276
        """
3277
        project_wt, lib_wt = self.setup_two_branches(custom_root_ids=False)
3278
        root_id = project_wt.path2id('')
3279
        self.do_merge_into('lib1', 'project/lib1')
3280
        project_wt.lock_read()
3281
        self.addCleanup(project_wt.unlock)
3282
        # The r1-lib1 revision should be merged into this one
7143.15.2 by Jelmer Vernooij
Run autopep8.
3283
        self.assertEqual([b'r1-project', b'r1-lib1'],
3284
                         project_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3285
        new_lib1_id = project_wt.path2id('lib1')
3286
        self.assertNotEqual(None, new_lib1_id)
3287
        self.assertTreeEntriesEqual(
3288
            [('', root_id),
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3289
             ('README', b'project-README-id'),
3290
             ('dir', b'project-dir-id'),
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3291
             ('lib1', new_lib1_id),
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3292
             ('dir/file.c', b'project-file.c-id'),
3293
             ('lib1/Makefile', b'lib1-Makefile-id'),
3294
             ('lib1/README', b'lib1-README-id'),
3295
             ('lib1/foo.c', b'lib1-foo.c-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3296
             ], project_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3297
3298
    def test_name_conflict(self):
3299
        """When the target directory name already exists a conflict is
3300
        generated and the original directory is renamed to foo.moved.
3301
        """
3302
        dest_wt = self.setup_simple_branch('dest', ['dir/', 'dir/file.txt'])
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3303
        self.setup_simple_branch('src', ['README'])
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3304
        conflicts = self.do_merge_into('src', 'dest/dir')
3305
        self.assertEqual(1, conflicts)
3306
        dest_wt.lock_read()
3307
        self.addCleanup(dest_wt.unlock)
3308
        # The r1-lib1 revision should be merged into this one
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3309
        self.assertEqual([b'r1-dest', b'r1-src'], dest_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3310
        self.assertTreeEntriesEqual(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3311
            [('', b'dest-root-id'),
3312
             ('dir', b'src-root-id'),
3313
             ('dir.moved', b'dest-dir-id'),
3314
             ('dir/README', b'src-README-id'),
3315
             ('dir.moved/file.txt', b'dest-file.txt-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3316
             ], dest_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3317
3318
    def test_file_id_conflict(self):
3319
        """A conflict is generated if the merge-into adds a file (or other
3320
        inventory entry) with a file-id that already exists in the target tree.
3321
        """
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3322
        self.setup_simple_branch('dest', ['file.txt'])
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3323
        # Make a second tree with a file-id that will clash with file.txt in
3324
        # dest.
3325
        src_wt = self.make_branch_and_tree('src')
3326
        self.build_tree(['src/README'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
3327
        src_wt.add(['README'], ids=[b'dest-file.txt-id'])
3328
        src_wt.commit("Rev 1 of src.", rev_id=b'r1-src')
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3329
        conflicts = self.do_merge_into('src', 'dest/dir')
3330
        # This is an edge case that shouldn't happen to users very often.  So
3331
        # we don't care really about the exact presentation of the conflict,
3332
        # just that there is one.
3333
        self.assertEqual(1, conflicts)
3334
3335
    def test_only_subdir(self):
3336
        """When the location points to just part of a tree, merge just that
3337
        subtree.
3338
        """
3339
        dest_wt = self.setup_simple_branch('dest')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3340
        self.setup_simple_branch('src', ['hello.txt', 'dir/', 'dir/foo.c'])
3341
        self.do_merge_into('src/dir', 'dest/dir')
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3342
        dest_wt.lock_read()
3343
        self.addCleanup(dest_wt.unlock)
3344
        # The r1-lib1 revision should NOT be merged into this one (this is a
3345
        # partial merge).
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3346
        self.assertEqual([b'r1-dest'], dest_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3347
        self.assertTreeEntriesEqual(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3348
            [('', b'dest-root-id'),
3349
             ('dir', b'src-dir-id'),
3350
             ('dir/foo.c', b'src-foo.c-id'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
3351
             ], dest_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3352
3353
    def test_only_file(self):
3354
        """An edge case: merge just one file, not a whole dir."""
3355
        dest_wt = self.setup_simple_branch('dest')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3356
        self.setup_simple_branch('two-file', ['file1.txt', 'file2.txt'])
3357
        self.do_merge_into('two-file/file1.txt', 'dest/file1.txt')
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3358
        dest_wt.lock_read()
3359
        self.addCleanup(dest_wt.unlock)
3360
        # The r1-lib1 revision should NOT be merged into this one
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3361
        self.assertEqual([b'r1-dest'], dest_wt.get_parent_ids())
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3362
        self.assertTreeEntriesEqual(
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3363
            [('', b'dest-root-id'), ('file1.txt', b'two-file-file1.txt-id')],
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3364
            dest_wt)
3365
3366
    def test_no_such_source_path(self):
3367
        """PathNotInTree is raised if the specified path in the source tree
3368
        does not exist.
3369
        """
3370
        dest_wt = self.setup_simple_branch('dest')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3371
        self.setup_simple_branch('src', ['dir/'])
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3372
        self.assertRaises(_mod_merge.PathNotInTree, self.do_merge_into,
7143.15.2 by Jelmer Vernooij
Run autopep8.
3373
                          'src/no-such-dir', 'dest/foo')
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3374
        dest_wt.lock_read()
3375
        self.addCleanup(dest_wt.unlock)
3376
        # The dest tree is unmodified.
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3377
        self.assertEqual([b'r1-dest'], dest_wt.get_parent_ids())
3378
        self.assertTreeEntriesEqual([('', b'dest-root-id')], dest_wt)
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3379
3380
    def test_no_such_target_path(self):
3381
        """PathNotInTree is also raised if the specified path in the target
3382
        tree does not exist.
3383
        """
3384
        dest_wt = self.setup_simple_branch('dest')
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
3385
        self.setup_simple_branch('src', ['file.txt'])
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3386
        self.assertRaises(_mod_merge.PathNotInTree, self.do_merge_into,
7143.15.2 by Jelmer Vernooij
Run autopep8.
3387
                          'src', 'dest/no-such-dir/foo')
5246.2.34 by Andrew Bennetts
Delete test_merge_into, and put those tests directly in test_merge.
3388
        dest_wt.lock_read()
3389
        self.addCleanup(dest_wt.unlock)
3390
        # The dest tree is unmodified.
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3391
        self.assertEqual([b'r1-dest'], dest_wt.get_parent_ids())
3392
        self.assertTreeEntriesEqual([('', b'dest-root-id')], dest_wt)
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3393
3394
3395
class TestMergeHooks(TestCaseWithTransport):
3396
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3397
    def setUp(self):
3398
        super(TestMergeHooks, self).setUp()
3399
        self.tree_a = self.make_branch_and_tree('tree_a')
6855.4.1 by Jelmer Vernooij
Yet more bees.
3400
        self.build_tree_contents([('tree_a/file', b'content_1')])
3401
        self.tree_a.add('file', b'file-id')
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3402
        self.tree_a.commit('added file')
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3403
7143.15.2 by Jelmer Vernooij
Run autopep8.
3404
        self.tree_b = self.tree_a.controldir.sprout(
3405
            'tree_b').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3406
        self.build_tree_contents([('tree_b/file', b'content_2')])
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3407
        self.tree_b.commit('modify file')
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3408
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3409
    def test_pre_merge_hook_inject_different_tree(self):
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
3410
        tree_c = self.tree_b.controldir.sprout('tree_c').open_workingtree()
6855.4.1 by Jelmer Vernooij
Yet more bees.
3411
        self.build_tree_contents([('tree_c/file', b'content_3')])
6388.1.4 by Jelmer Vernooij
Fix tests.
3412
        tree_c.commit("more content")
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3413
        calls = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3414
6388.1.4 by Jelmer Vernooij
Fix tests.
3415
        def factory(merger):
3416
            self.assertIsInstance(merger, _mod_merge.Merge3Merger)
3417
            merger.other_tree = tree_c
3418
            calls.append(merger)
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3419
        _mod_merge.Merger.hooks.install_named_hook('pre_merge',
3420
                                                   factory, 'test factory')
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3421
        self.tree_a.merge_from_branch(self.tree_b.branch)
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3422
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3423
        self.assertFileEqual(b"content_3", 'tree_a/file')
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3424
        self.assertLength(1, calls)
3425
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3426
    def test_post_merge_hook_called(self):
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3427
        calls = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
3428
6388.1.4 by Jelmer Vernooij
Fix tests.
3429
        def factory(merger):
3430
            self.assertIsInstance(merger, _mod_merge.Merge3Merger)
3431
            calls.append(merger)
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3432
        _mod_merge.Merger.hooks.install_named_hook('post_merge',
3433
                                                   factory, 'test factory')
3434
6388.1.7 by Jelmer Vernooij
Review feedback from Vila.
3435
        self.tree_a.merge_from_branch(self.tree_b.branch)
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3436
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
3437
        self.assertFileEqual(b"content_2", 'tree_a/file')
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
3438
        self.assertLength(1, calls)