/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 breezy/tests/test_workingtree.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2019-06-15 15:50:25 UTC
  • mfrom: (7296.11.1 custom-github)
  • Revision ID: breezy.the.bot@gmail.com-20190615155025-edm8b2lkn1mzqwtq
Use local REST implementation to access GitHub API.

Merged from https://code.launchpad.net/~jelmer/brz/custom-github/+merge/367669

Show diffs side-by-side

added added

removed removed

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