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