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