/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_workingtree.py

  • Committer: Alexander Belchenko
  • Date: 2006-06-29 08:41:31 UTC
  • mto: (1860.1.1 win32.installer)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060629084131-3ea4d44e3204e36f
win32 installer for bzr.dev.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
from io import BytesIO
 
18
from cStringIO import StringIO
19
19
import os
20
20
 
21
 
from .. import (
22
 
    conflicts,
23
 
    errors,
24
 
    symbol_versioning,
25
 
    trace,
26
 
    transport,
27
 
    workingtree,
28
 
    )
29
 
from ..bzr import (
30
 
    bzrdir,
31
 
    workingtree as bzrworkingtree,
32
 
    workingtree_3,
33
 
    workingtree_4,
34
 
    )
35
 
from ..lock import write_locked
36
 
from ..lockdir import LockDir
37
 
from . import TestCase, TestCaseWithTransport, TestSkipped
38
 
from ..tree import (
39
 
    TreeEntry,
40
 
    TreeDirectory,
41
 
    TreeFile,
42
 
    TreeLink,
43
 
    )
44
 
 
45
 
from .features import SymlinkFeature
 
21
import bzrlib
 
22
from bzrlib.branch import Branch
 
23
from bzrlib import bzrdir, conflicts, errors, workingtree
 
24
from bzrlib.bzrdir import BzrDir
 
25
from bzrlib.errors import NotBranchError, NotVersionedError
 
26
from bzrlib.lockdir import LockDir
 
27
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
 
28
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
29
from bzrlib.trace import mutter
 
30
from bzrlib.transport import get_transport
 
31
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
 
32
                                WorkingTree)
46
33
 
47
34
class TestTreeDirectory(TestCaseWithTransport):
48
35
 
71
58
class TestDefaultFormat(TestCaseWithTransport):
72
59
 
73
60
    def test_get_set_default_format(self):
74
 
        old_format = workingtree.format_registry.get_default()
75
 
        # default is 6
76
 
        self.assertTrue(isinstance(
77
 
            old_format, workingtree_4.WorkingTreeFormat6))
78
 
        workingtree.format_registry.set_default(SampleTreeFormat())
79
 
        try:
80
 
            # the default branch format is used by the meta dir format
81
 
            # which is not the default bzrdir format at this point
82
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
83
 
            dir.create_repository()
84
 
            dir.create_branch()
85
 
            result = dir.create_workingtree()
86
 
            self.assertEqual(result, 'A tree')
87
 
        finally:
88
 
            workingtree.format_registry.set_default(old_format)
89
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
90
 
 
91
 
    def test_from_string(self):
92
 
        self.assertIsInstance(
93
 
            SampleTreeFormat.from_string(b"Sample tree format."),
94
 
            SampleTreeFormat)
95
 
        self.assertRaises(
96
 
            AssertionError, SampleTreeFormat.from_string,
97
 
            b"Different format string.")
98
 
 
99
 
    def test_get_set_default_format_by_key(self):
100
 
        old_format = workingtree.format_registry.get_default()
101
 
        # default is 6
102
 
        format = SampleTreeFormat()
103
 
        workingtree.format_registry.register(format)
104
 
        self.addCleanup(workingtree.format_registry.remove, format)
105
 
        self.assertTrue(isinstance(
106
 
            old_format, workingtree_4.WorkingTreeFormat6))
107
 
        workingtree.format_registry.set_default_key(format.get_format_string())
108
 
        try:
109
 
            # the default branch format is used by the meta dir format
110
 
            # which is not the default bzrdir format at this point
111
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
112
 
            dir.create_repository()
113
 
            dir.create_branch()
114
 
            result = dir.create_workingtree()
115
 
            self.assertEqual(result, 'A tree')
116
 
        finally:
117
 
            workingtree.format_registry.set_default_key(
118
 
                old_format.get_format_string())
119
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
120
 
 
121
 
    def test_open(self):
122
 
        tree = self.make_branch_and_tree('.')
123
 
        open_direct = workingtree.WorkingTree.open('.')
124
 
        self.assertEqual(tree.basedir, open_direct.basedir)
125
 
        open_no_args = workingtree.WorkingTree.open()
126
 
        self.assertEqual(tree.basedir, open_no_args.basedir)
127
 
 
128
 
    def test_open_containing(self):
129
 
        tree = self.make_branch_and_tree('.')
130
 
        open_direct, relpath = workingtree.WorkingTree.open_containing('.')
131
 
        self.assertEqual(tree.basedir, open_direct.basedir)
132
 
        self.assertEqual('', relpath)
133
 
        open_no_args, relpath = workingtree.WorkingTree.open_containing()
134
 
        self.assertEqual(tree.basedir, open_no_args.basedir)
135
 
        self.assertEqual('', relpath)
136
 
        open_subdir, relpath = workingtree.WorkingTree.open_containing(
137
 
            'subdir')
138
 
        self.assertEqual(tree.basedir, open_subdir.basedir)
139
 
        self.assertEqual('subdir', relpath)
140
 
 
141
 
 
142
 
class SampleTreeFormat(bzrworkingtree.WorkingTreeFormatMetaDir):
 
61
        old_format = workingtree.WorkingTreeFormat.get_default_format()
 
62
        # default is 3
 
63
        self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
 
64
        workingtree.WorkingTreeFormat.set_default_format(SampleTreeFormat())
 
65
        try:
 
66
            # the default branch format is used by the meta dir format
 
67
            # which is not the default bzrdir format at this point
 
68
            dir = bzrdir.BzrDirMetaFormat1().initialize('.')
 
69
            dir.create_repository()
 
70
            dir.create_branch()
 
71
            result = dir.create_workingtree()
 
72
            self.assertEqual(result, 'A tree')
 
73
        finally:
 
74
            workingtree.WorkingTreeFormat.set_default_format(old_format)
 
75
        self.assertEqual(old_format, workingtree.WorkingTreeFormat.get_default_format())
 
76
 
 
77
 
 
78
class SampleTreeFormat(workingtree.WorkingTreeFormat):
143
79
    """A sample format
144
80
 
145
 
    this format is initializable, unsupported to aid in testing the
 
81
    this format is initializable, unsupported to aid in testing the 
146
82
    open and open_downlevel routines.
147
83
    """
148
84
 
149
 
    @classmethod
150
 
    def get_format_string(cls):
 
85
    def get_format_string(self):
151
86
        """See WorkingTreeFormat.get_format_string()."""
152
 
        return b"Sample tree format."
 
87
        return "Sample tree format."
153
88
 
154
 
    def initialize(self, a_controldir, revision_id=None, from_branch=None,
155
 
                   accelerator_tree=None, hardlink=False):
 
89
    def initialize(self, a_bzrdir, revision_id=None):
156
90
        """Sample branches cannot be created."""
157
 
        t = a_controldir.get_workingtree_transport(self)
158
 
        t.put_bytes('format', self.get_format_string())
 
91
        t = a_bzrdir.get_workingtree_transport(self)
 
92
        t.put('format', StringIO(self.get_format_string()))
159
93
        return 'A tree'
160
94
 
161
95
    def is_supported(self):
165
99
        return "opened tree."
166
100
 
167
101
 
168
 
class SampleExtraTreeFormat(workingtree.WorkingTreeFormat):
169
 
    """A sample format that does not support use in a metadir.
170
 
 
171
 
    """
172
 
 
173
 
    def get_format_string(self):
174
 
        # Not usable in a metadir, so no format string
175
 
        return None
176
 
 
177
 
    def initialize(self, a_controldir, revision_id=None, from_branch=None,
178
 
                   accelerator_tree=None, hardlink=False):
179
 
        raise NotImplementedError(self.initialize)
180
 
 
181
 
    def is_supported(self):
182
 
        return False
183
 
 
184
 
    def open(self, transport, _found=False):
185
 
        raise NotImplementedError(self.open)
186
 
 
187
 
 
188
102
class TestWorkingTreeFormat(TestCaseWithTransport):
189
103
    """Tests for the WorkingTreeFormat facility."""
190
104
 
191
 
    def test_find_format_string(self):
192
 
        # is the right format object found for a working tree?
193
 
        branch = self.make_branch('branch')
194
 
        self.assertRaises(
195
 
            errors.NoWorkingTree,
196
 
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string,
197
 
            branch.controldir)
198
 
        transport = branch.controldir.get_workingtree_transport(None)
199
 
        transport.mkdir('.')
200
 
        transport.put_bytes("format", b"some format name")
201
 
        # The format does not have to be known by Bazaar,
202
 
        # find_format_string just retrieves the name
203
 
        self.assertEqual(
204
 
            b"some format name",
205
 
            bzrworkingtree.WorkingTreeFormatMetaDir.find_format_string(
206
 
                branch.controldir))
207
 
 
208
105
    def test_find_format(self):
209
106
        # is the right format object found for a working tree?
210
107
        # create a branch with a few known format objects.
211
108
        self.build_tree(["foo/", "bar/"])
212
 
 
213
109
        def check_format(format, url):
214
 
            dir = format._matchingcontroldir.initialize(url)
 
110
            dir = format._matchingbzrdir.initialize(url)
215
111
            dir.create_repository()
216
112
            dir.create_branch()
217
113
            format.initialize(dir)
218
 
            found_format = bzrworkingtree.WorkingTreeFormatMetaDir.find_format(
219
 
                dir)
220
 
            self.assertIsInstance(found_format, format.__class__)
221
 
        check_format(workingtree_3.WorkingTreeFormat3(), "bar")
222
 
 
 
114
            t = get_transport(url)
 
115
            found_format = workingtree.WorkingTreeFormat.find_format(dir)
 
116
            self.failUnless(isinstance(found_format, format.__class__))
 
117
        check_format(workingtree.WorkingTreeFormat3(), "bar")
 
118
        
223
119
    def test_find_format_no_tree(self):
224
120
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
225
121
        self.assertRaises(errors.NoWorkingTree,
226
 
                          bzrworkingtree.WorkingTreeFormatMetaDir.find_format,
 
122
                          workingtree.WorkingTreeFormat.find_format,
227
123
                          dir)
228
124
 
229
125
    def test_find_format_unknown_format(self):
232
128
        dir.create_branch()
233
129
        SampleTreeFormat().initialize(dir)
234
130
        self.assertRaises(errors.UnknownFormatError,
235
 
                          bzrworkingtree.WorkingTreeFormatMetaDir.find_format,
 
131
                          workingtree.WorkingTreeFormat.find_format,
236
132
                          dir)
237
133
 
238
 
    def test_find_format_with_features(self):
239
 
        tree = self.make_branch_and_tree('.', format='2a')
240
 
        tree.update_feature_flags({b"name": b"necessity"})
241
 
        found_format = bzrworkingtree.WorkingTreeFormatMetaDir.find_format(
242
 
            tree.controldir)
243
 
        self.assertIsInstance(found_format, workingtree.WorkingTreeFormat)
244
 
        self.assertEqual(found_format.features.get(b"name"), b"necessity")
245
 
        self.assertRaises(
246
 
            bzrdir.MissingFeature, found_format.check_support_status, True)
247
 
        self.addCleanup(
248
 
            bzrworkingtree.WorkingTreeFormatMetaDir.unregister_feature,
249
 
            b"name")
250
 
        bzrworkingtree.WorkingTreeFormatMetaDir.register_feature(b"name")
251
 
        found_format.check_support_status(True)
252
 
 
253
 
 
254
 
class TestWorkingTreeIterEntriesByDir_wSubtrees(TestCaseWithTransport):
255
 
 
256
 
    def make_simple_tree(self):
257
 
        tree = self.make_branch_and_tree('tree', format='development-subtree')
258
 
        self.build_tree(['tree/a/', 'tree/a/b/', 'tree/a/b/c'])
259
 
        tree.set_root_id(b'root-id')
260
 
        tree.add(['a', 'a/b', 'a/b/c'], [b'a-id', b'b-id', b'c-id'])
261
 
        tree.commit('initial')
262
 
        return tree
263
 
 
264
 
    def test_just_directory(self):
265
 
        tree = self.make_simple_tree()
266
 
        self.assertEqual([('directory', b'root-id'),
267
 
                          ('directory', b'a-id'),
268
 
                          ('directory', b'b-id'),
269
 
                          ('file', b'c-id')],
270
 
                         [(ie.kind, ie.file_id)
271
 
                          for path, ie in tree.iter_entries_by_dir()])
272
 
        self.make_branch_and_tree('tree/a/b')
273
 
        self.assertEqual([('tree-reference', b'b-id')],
274
 
                         [(ie.kind, ie.file_id)
275
 
                          for path, ie in tree.iter_entries_by_dir(
276
 
                              specific_files=['a/b'])])
277
 
 
278
 
    def test_direct_subtree(self):
279
 
        tree = self.make_simple_tree()
280
 
        self.make_branch_and_tree('tree/a/b')
281
 
        self.assertEqual([('directory', b'root-id'),
282
 
                          ('directory', b'a-id'),
283
 
                          ('tree-reference', b'b-id')],
284
 
                         [(ie.kind, ie.file_id)
285
 
                          for path, ie in tree.iter_entries_by_dir()])
286
 
 
287
 
    def test_indirect_subtree(self):
288
 
        tree = self.make_simple_tree()
289
 
        self.make_branch_and_tree('tree/a')
290
 
        self.assertEqual([('directory', b'root-id'),
291
 
                          ('tree-reference', b'a-id')],
292
 
                         [(ie.kind, ie.file_id)
293
 
                          for path, ie in tree.iter_entries_by_dir()])
294
 
 
295
 
 
296
 
class TestWorkingTreeFormatRegistry(TestCase):
297
 
 
298
 
    def setUp(self):
299
 
        super(TestWorkingTreeFormatRegistry, self).setUp()
300
 
        self.registry = workingtree.WorkingTreeFormatRegistry()
301
 
 
302
134
    def test_register_unregister_format(self):
303
135
        format = SampleTreeFormat()
304
 
        self.registry.register(format)
305
 
        self.assertEqual(format, self.registry.get(b"Sample tree format."))
306
 
        self.registry.remove(format)
307
 
        self.assertRaises(KeyError, self.registry.get, b"Sample tree format.")
308
 
 
309
 
    def test_get_all(self):
310
 
        format = SampleTreeFormat()
311
 
        self.assertEqual([], self.registry._get_all())
312
 
        self.registry.register(format)
313
 
        self.assertEqual([format], self.registry._get_all())
314
 
 
315
 
    def test_register_extra(self):
316
 
        format = SampleExtraTreeFormat()
317
 
        self.assertEqual([], self.registry._get_all())
318
 
        self.registry.register_extra(format)
319
 
        self.assertEqual([format], self.registry._get_all())
320
 
 
321
 
    def test_register_extra_lazy(self):
322
 
        self.assertEqual([], self.registry._get_all())
323
 
        self.registry.register_extra_lazy("breezy.tests.test_workingtree",
324
 
                                          "SampleExtraTreeFormat")
325
 
        formats = self.registry._get_all()
326
 
        self.assertEqual(1, len(formats))
327
 
        self.assertIsInstance(formats[0], SampleExtraTreeFormat)
 
136
        # make a control dir
 
137
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
 
138
        dir.create_repository()
 
139
        dir.create_branch()
 
140
        # make a branch
 
141
        format.initialize(dir)
 
142
        # register a format for it.
 
143
        workingtree.WorkingTreeFormat.register_format(format)
 
144
        # which branch.Open will refuse (not supported)
 
145
        self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
 
146
        # but open_downlevel will work
 
147
        self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
 
148
        # unregister the format
 
149
        workingtree.WorkingTreeFormat.unregister_format(format)
328
150
 
329
151
 
330
152
class TestWorkingTreeFormat3(TestCaseWithTransport):
334
156
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
335
157
        control.create_repository()
336
158
        control.create_branch()
337
 
        workingtree_3.WorkingTreeFormat3().initialize(control)
 
159
        tree = workingtree.WorkingTreeFormat3().initialize(control)
338
160
        # we want:
339
161
        # format 'Bazaar-NG Working Tree format 3'
340
162
        # inventory = blank inventory
342
164
        # stat-cache = ??
343
165
        # no inventory.basis yet
344
166
        t = control.get_workingtree_transport(None)
345
 
        self.assertEqualDiff(b'Bazaar-NG Working Tree format 3',
 
167
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
346
168
                             t.get('format').read())
347
 
        self.assertEqualDiff(t.get('inventory').read(),
348
 
                             b'<inventory format="5">\n'
349
 
                             b'</inventory>\n',
350
 
                             )
351
 
        self.assertEqualDiff(b'### bzr hashcache v5\n',
 
169
        self.assertEqualDiff('<inventory format="5">\n'
 
170
                             '</inventory>\n',
 
171
                             t.get('inventory').read())
 
172
        self.assertEqualDiff('### bzr hashcache v5\n',
352
173
                             t.get('stat-cache').read())
353
174
        self.assertFalse(t.has('inventory.basis'))
354
175
        # no last-revision file means 'None' or 'NULLREVISION'
355
176
        self.assertFalse(t.has('last-revision'))
356
 
        # TODO RBC 20060210 do a commit, check the inventory.basis is created
 
177
        # TODO RBC 20060210 do a commit, check the inventory.basis is created 
357
178
        # correctly and last-revision file becomes present.
358
179
 
359
180
    def test_uses_lockdir(self):
360
181
        """WorkingTreeFormat3 uses its own LockDir:
361
 
 
 
182
            
362
183
            - lock is a directory
363
184
            - when the WorkingTree is locked, LockDir can see that
364
185
        """
365
186
        t = self.get_transport()
366
187
        url = self.get_url()
367
188
        dir = bzrdir.BzrDirMetaFormat1().initialize(url)
368
 
        dir.create_repository()
369
 
        dir.create_branch()
 
189
        repo = dir.create_repository()
 
190
        branch = dir.create_branch()
370
191
        try:
371
 
            tree = workingtree_3.WorkingTreeFormat3().initialize(dir)
 
192
            tree = workingtree.WorkingTreeFormat3().initialize(dir)
372
193
        except errors.NotLocalUrl:
373
194
            raise TestSkipped('Not a local URL')
374
195
        self.assertIsDirectory('.bzr', t)
375
196
        self.assertIsDirectory('.bzr/checkout', t)
376
197
        self.assertIsDirectory('.bzr/checkout/lock', t)
377
198
        our_lock = LockDir(t, '.bzr/checkout/lock')
378
 
        self.assertEqual(our_lock.peek(), None)
379
 
        with tree.lock_write():
380
 
            self.assertTrue(our_lock.peek())
381
 
        self.assertEqual(our_lock.peek(), None)
 
199
        self.assertEquals(our_lock.peek(), None)
 
200
        tree.lock_write()
 
201
        self.assertTrue(our_lock.peek())
 
202
        tree.unlock()
 
203
        self.assertEquals(our_lock.peek(), None)
382
204
 
383
205
    def test_missing_pending_merges(self):
384
206
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
385
207
        control.create_repository()
386
208
        control.create_branch()
387
 
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
388
 
        tree._transport.delete("pending-merges")
389
 
        self.assertEqual([], tree.get_parent_ids())
390
 
 
391
 
 
392
 
class TestRevert(TestCaseWithTransport):
393
 
 
394
 
    def test_revert_conflicts_recursive(self):
395
 
        this_tree = self.make_branch_and_tree('this-tree')
396
 
        self.build_tree_contents([('this-tree/foo/',),
397
 
                                  ('this-tree/foo/bar', b'bar')])
398
 
        this_tree.add(['foo', 'foo/bar'])
399
 
        this_tree.commit('created foo/bar')
400
 
        other_tree = this_tree.controldir.sprout(
401
 
            'other-tree').open_workingtree()
402
 
        self.build_tree_contents([('other-tree/foo/bar', b'baz')])
403
 
        other_tree.commit('changed bar')
404
 
        self.build_tree_contents([('this-tree/foo/bar', b'qux')])
405
 
        this_tree.commit('changed qux')
406
 
        this_tree.merge_from_branch(other_tree.branch)
407
 
        self.assertEqual(1, len(this_tree.conflicts()))
408
 
        this_tree.revert(['foo'])
409
 
        self.assertEqual(0, len(this_tree.conflicts()))
410
 
 
411
 
 
412
 
class TestAutoResolve(TestCaseWithTransport):
413
 
 
414
 
    def _auto_resolve(self, tree):
415
 
        """Call auto_resolve on tree expecting deprecation"""
416
 
        return self.applyDeprecated(
417
 
            symbol_versioning.deprecated_in((3, 0, 1)),
418
 
            tree.auto_resolve,)
419
 
 
420
 
    def test_auto_resolve(self):
421
 
        base = self.make_branch_and_tree('base')
422
 
        self.build_tree_contents([('base/hello', b'Hello')])
423
 
        base.add('hello', b'hello_id')
424
 
        base.commit('Hello')
425
 
        other = base.controldir.sprout('other').open_workingtree()
426
 
        self.build_tree_contents([('other/hello', b'hELLO')])
427
 
        other.commit('Case switch')
428
 
        this = base.controldir.sprout('this').open_workingtree()
429
 
        self.assertPathExists('this/hello')
430
 
        self.build_tree_contents([('this/hello', b'Hello World')])
431
 
        this.commit('Add World')
432
 
        this.merge_from_branch(other.branch)
433
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
434
 
                         this.conflicts())
435
 
        self._auto_resolve(this)
436
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
437
 
                         this.conflicts())
438
 
        self.build_tree_contents([('this/hello', '<<<<<<<')])
439
 
        self._auto_resolve(this)
440
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
441
 
                         this.conflicts())
442
 
        self.build_tree_contents([('this/hello', '=======')])
443
 
        self._auto_resolve(this)
444
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
445
 
                         this.conflicts())
446
 
        self.build_tree_contents([('this/hello', '\n>>>>>>>')])
447
 
        remaining, resolved = self._auto_resolve(this)
448
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
449
 
                         this.conflicts())
450
 
        self.assertEqual([], resolved)
451
 
        self.build_tree_contents([('this/hello', b'hELLO wORLD')])
452
 
        remaining, resolved = self._auto_resolve(this)
453
 
        self.assertEqual([], this.conflicts())
454
 
        self.assertEqual([conflicts.TextConflict('hello', b'hello_id')],
455
 
                         resolved)
456
 
        self.assertPathDoesNotExist('this/hello.BASE')
457
 
 
458
 
    def test_unsupported_symlink_auto_resolve(self):
459
 
        self.requireFeature(SymlinkFeature)
460
 
        base = self.make_branch_and_tree('base')
461
 
        self.build_tree_contents([('base/hello', 'Hello')])
462
 
        base.add('hello', b'hello_id')
463
 
        base.commit('commit 0')
464
 
        other = base.controldir.sprout('other').open_workingtree()
465
 
        self.build_tree_contents([('other/hello', 'Hello')])
466
 
        os.symlink('other/hello', 'other/foo')
467
 
        other.add('foo', b'foo_id')
468
 
        other.commit('commit symlink')
469
 
        this = base.controldir.sprout('this').open_workingtree()
470
 
        self.assertPathExists('this/hello')
471
 
        self.build_tree_contents([('this/hello', 'Hello')])
472
 
        this.commit('commit 2')
473
 
        log = BytesIO()
474
 
        trace.push_log_file(log)
475
 
        os_symlink = getattr(os, 'symlink', None)
476
 
        os.symlink = None
477
 
        try:
478
 
            this.merge_from_branch(other.branch)
479
 
        finally:
480
 
            if os_symlink:
481
 
                os.symlink = os_symlink
482
 
        self.assertContainsRe(
483
 
            log.getvalue(),
484
 
            b'Unable to create symlink "foo" on this filesystem')
485
 
 
486
 
    def test_auto_resolve_dir(self):
487
 
        tree = self.make_branch_and_tree('tree')
488
 
        self.build_tree(['tree/hello/'])
489
 
        tree.add('hello', b'hello-id')
490
 
        file_conflict = conflicts.TextConflict('hello', b'hello-id')
491
 
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
492
 
        remaining, resolved = self._auto_resolve(tree)
493
 
        self.assertEqual(
494
 
            remaining,
495
 
            conflicts.ConflictList([conflicts.TextConflict(u'hello', 'hello-id')]))
496
 
        self.assertEqual(resolved, [])
497
 
 
498
 
    def test_auto_resolve_missing(self):
499
 
        tree = self.make_branch_and_tree('tree')
500
 
        file_conflict = conflicts.TextConflict('hello', b'hello-id')
501
 
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
502
 
        remaining, resolved = self._auto_resolve(tree)
503
 
        self.assertEqual(remaining, [])
504
 
        self.assertEqual(
505
 
            resolved,
506
 
            conflicts.ConflictList([conflicts.TextConflict(u'hello', 'hello-id')]))
507
 
 
508
 
 
509
 
class TestStoredUncommitted(TestCaseWithTransport):
510
 
 
511
 
    def store_uncommitted(self):
512
 
        tree = self.make_branch_and_tree('tree')
513
 
        tree.commit('get root in there')
514
 
        self.build_tree_contents([('tree/file', b'content')])
515
 
        tree.add('file', b'file-id')
516
 
        tree.store_uncommitted()
517
 
        return tree
518
 
 
519
 
    def test_store_uncommitted(self):
520
 
        self.store_uncommitted()
521
 
        self.assertPathDoesNotExist('tree/file')
522
 
 
523
 
    def test_store_uncommitted_no_change(self):
524
 
        tree = self.make_branch_and_tree('tree')
525
 
        tree.commit('get root in there')
526
 
        tree.store_uncommitted()
527
 
        self.assertIs(None, tree.branch.get_unshelver(tree))
528
 
 
529
 
    def test_restore_uncommitted(self):
530
 
        with write_locked(self.store_uncommitted()) as tree:
531
 
            tree.restore_uncommitted()
532
 
            self.assertPathExists('tree/file')
533
 
            self.assertIs(None, tree.branch.get_unshelver(tree))
534
 
 
535
 
    def test_restore_uncommitted_none(self):
536
 
        tree = self.make_branch_and_tree('tree')
537
 
        tree.restore_uncommitted()
 
209
        tree = workingtree.WorkingTreeFormat3().initialize(control)
 
210
        tree._control_files._transport.delete("pending-merges")
 
211
        self.assertEqual([], tree.pending_merges())
 
212
 
 
213
 
 
214
class TestFormat2WorkingTree(TestCaseWithTransport):
 
215
    """Tests that are specific to format 2 trees."""
 
216
 
 
217
    def create_format2_tree(self, url):
 
218
        return self.make_branch_and_tree(
 
219
            url, format=bzrlib.bzrdir.BzrDirFormat6())
 
220
 
 
221
    def test_conflicts(self):
 
222
        # test backwards compatability
 
223
        tree = self.create_format2_tree('.')
 
224
        self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
 
225
                          None)
 
226
        file('lala.BASE', 'wb').write('labase')
 
227
        expected = conflicts.ContentsConflict('lala')
 
228
        self.assertEqual(list(tree.conflicts()), [expected])
 
229
        file('lala', 'wb').write('la')
 
230
        tree.add('lala', 'lala-id')
 
231
        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
 
232
        self.assertEqual(list(tree.conflicts()), [expected])
 
233
        file('lala.THIS', 'wb').write('lathis')
 
234
        file('lala.OTHER', 'wb').write('laother')
 
235
        # When "text conflict"s happen, stem, THIS and OTHER are text
 
236
        expected = conflicts.TextConflict('lala', file_id='lala-id')
 
237
        self.assertEqual(list(tree.conflicts()), [expected])
 
238
        os.unlink('lala.OTHER')
 
239
        os.mkdir('lala.OTHER')
 
240
        expected = conflicts.ContentsConflict('lala', file_id='lala-id')
 
241
        self.assertEqual(list(tree.conflicts()), [expected])
 
242
 
 
243
 
 
244
class TestNonFormatSpecificCode(TestCaseWithTransport):
 
245
    """This class contains tests of workingtree that are not format specific."""
 
246
 
 
247
    
 
248
    def test_gen_file_id(self):
 
249
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('bar'), 'bar-')
 
250
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('Mwoo oof\t m'), 'Mwoooofm-')
 
251
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('..gam.py'), 'gam.py-')
 
252
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('..Mwoo oof\t m'), 'Mwoooofm-')
 
253
 
 
254
    def test_next_id_suffix(self):
 
255
        bzrlib.workingtree._gen_id_suffix = None
 
256
        bzrlib.workingtree._next_id_suffix()
 
257
        self.assertNotEqual(None, bzrlib.workingtree._gen_id_suffix)
 
258
        bzrlib.workingtree._gen_id_suffix = "foo-"
 
259
        bzrlib.workingtree._gen_id_serial = 1
 
260
        self.assertEqual("foo-2", bzrlib.workingtree._next_id_suffix())
 
261
        self.assertEqual("foo-3", bzrlib.workingtree._next_id_suffix())
 
262
        self.assertEqual("foo-4", bzrlib.workingtree._next_id_suffix())
 
263
        self.assertEqual("foo-5", bzrlib.workingtree._next_id_suffix())
 
264
        self.assertEqual("foo-6", bzrlib.workingtree._next_id_suffix())
 
265
        self.assertEqual("foo-7", bzrlib.workingtree._next_id_suffix())
 
266
        self.assertEqual("foo-8", bzrlib.workingtree._next_id_suffix())
 
267
        self.assertEqual("foo-9", bzrlib.workingtree._next_id_suffix())
 
268
        self.assertEqual("foo-10", bzrlib.workingtree._next_id_suffix())
 
269
 
 
270
    def test__translate_ignore_rule(self):
 
271
        tree = self.make_branch_and_tree('.')
 
272
        # translation should return the regex, the number of groups in it,
 
273
        # and the original rule in a tuple.
 
274
        # there are three sorts of ignore rules:
 
275
        # root only - regex is the rule itself without the leading ./
 
276
        self.assertEqual(
 
277
            "(rootdirrule$)", 
 
278
            tree._translate_ignore_rule("./rootdirrule"))
 
279
        # full path - regex is the rule itself
 
280
        self.assertEqual(
 
281
            "(path\\/to\\/file$)",
 
282
            tree._translate_ignore_rule("path/to/file"))
 
283
        # basename only rule - regex is a rule that ignores everything up
 
284
        # to the last / in the filename
 
285
        self.assertEqual(
 
286
            "((?:.*/)?(?!.*/)basenamerule$)",
 
287
            tree._translate_ignore_rule("basenamerule"))
 
288
 
 
289
    def test__combine_ignore_rules(self):
 
290
        tree = self.make_branch_and_tree('.')
 
291
        # the combined ignore regexs need the outer group indices
 
292
        # placed in a dictionary with the rules that were combined.
 
293
        # an empty set of rules
 
294
        # this is returned as a list of combined regex,rule sets, because
 
295
        # python has a limit of 100 combined regexes.
 
296
        compiled_rules = tree._combine_ignore_rules([])
 
297
        self.assertEqual([], compiled_rules)
 
298
        # one of each type of rule.
 
299
        compiled_rules = tree._combine_ignore_rules(
 
300
            ["rule1", "rule/two", "./three"])[0]
 
301
        # what type *is* the compiled regex to do an isinstance of ?
 
302
        self.assertEqual(3, compiled_rules[0].groups)
 
303
        self.assertEqual(
 
304
            {0:"rule1",1:"rule/two",2:"./three"},
 
305
            compiled_rules[1])
 
306
 
 
307
    def test__combine_ignore_rules_grouping(self):
 
308
        tree = self.make_branch_and_tree('.')
 
309
        # when there are too many rules, the output is split into groups of 100
 
310
        rules = []
 
311
        for index in range(198):
 
312
            rules.append('foo')
 
313
        self.assertEqual(2, len(tree._combine_ignore_rules(rules)))
 
314
 
 
315
    def test__get_ignore_rules_as_regex(self):
 
316
        tree = self.make_branch_and_tree('.')
 
317
        # test against the default rules.
 
318
        reference_output = tree._combine_ignore_rules(bzrlib.DEFAULT_IGNORE)[0]
 
319
        regex_rules = tree._get_ignore_rules_as_regex()[0]
 
320
        self.assertEqual(len(reference_output[1]), regex_rules[0].groups)
 
321
        self.assertEqual(reference_output[1], regex_rules[1])