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