/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1
# (C) 2005,2006 Canonical Ltd
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
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
17
18
from cStringIO import StringIO
19
import os
20
21
import bzrlib
1508.1.25 by Robert Collins
Update per review comments.
22
import bzrlib.branch
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
23
from bzrlib.branch import Branch
24
import bzrlib.bzrdir as bzrdir
25
from bzrlib.bzrdir import BzrDir
26
import bzrlib.errors as errors
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
27
from bzrlib.errors import (NotBranchError, NotVersionedError, 
28
                           UnsupportedOperation)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
29
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
30
from bzrlib.tests import TestSkipped
31
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
32
from bzrlib.trace import mutter
33
import bzrlib.workingtree as workingtree
34
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
35
                                WorkingTree)
36
37
38
class TestWorkingTree(TestCaseWithWorkingTree):
39
40
    def test_listfiles(self):
41
        tree = self.make_branch_and_tree('.')
42
        os.mkdir('dir')
43
        print >> open('file', 'w'), "content"
44
        if has_symlinks():
45
            os.symlink('target', 'symlink')
46
        files = list(tree.list_files())
47
        self.assertEqual(files[0], ('dir', '?', 'directory', None, TreeDirectory()))
48
        self.assertEqual(files[1], ('file', '?', 'file', None, TreeFile()))
49
        if has_symlinks():
50
            self.assertEqual(files[2], ('symlink', '?', 'symlink', None, TreeLink()))
51
52
    def test_open_containing(self):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
53
        branch = self.make_branch_and_tree('.').branch
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
54
        wt, relpath = WorkingTree.open_containing()
55
        self.assertEqual('', relpath)
56
        self.assertEqual(wt.basedir + '/', branch.base)
57
        wt, relpath = WorkingTree.open_containing(u'.')
58
        self.assertEqual('', relpath)
59
        self.assertEqual(wt.basedir + '/', branch.base)
60
        wt, relpath = WorkingTree.open_containing('./foo')
61
        self.assertEqual('foo', relpath)
62
        self.assertEqual(wt.basedir + '/', branch.base)
63
        wt, relpath = WorkingTree.open_containing('file://' + getcwd() + '/foo')
64
        self.assertEqual('foo', relpath)
65
        self.assertEqual(wt.basedir + '/', branch.base)
66
67
    def test_basic_relpath(self):
68
        # for comprehensive relpath tests, see whitebox.py.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
69
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
70
        self.assertEqual('child',
71
                         tree.relpath(pathjoin(getcwd(), 'child')))
72
73
    def test_lock_locks_branch(self):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
74
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
75
        tree.lock_read()
76
        self.assertEqual('r', tree.branch.peek_lock_mode())
77
        tree.unlock()
78
        self.assertEqual(None, tree.branch.peek_lock_mode())
79
        tree.lock_write()
80
        self.assertEqual('w', tree.branch.peek_lock_mode())
81
        tree.unlock()
82
        self.assertEqual(None, tree.branch.peek_lock_mode())
83
 
84
    def test_revert(self):
85
        """Test selected-file revert"""
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
86
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
87
88
        self.build_tree(['hello.txt'])
89
        file('hello.txt', 'w').write('initial hello')
90
91
        self.assertRaises(NotVersionedError,
92
                          tree.revert, ['hello.txt'])
93
        tree.add(['hello.txt'])
94
        tree.commit('create initial hello.txt')
95
96
        self.check_file_contents('hello.txt', 'initial hello')
97
        file('hello.txt', 'w').write('new hello')
98
        self.check_file_contents('hello.txt', 'new hello')
99
100
        # revert file modified since last revision
101
        tree.revert(['hello.txt'])
102
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
103
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
104
105
        # reverting again does not clobber the backup
106
        tree.revert(['hello.txt'])
107
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
108
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.10.28 by Aaron Bentley
Use numbered backup files
109
        
110
        # backup files are numbered
111
        file('hello.txt', 'w').write('new hello2')
112
        tree.revert(['hello.txt'])
113
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
114
        self.check_file_contents('hello.txt.~1~', 'new hello')
115
        self.check_file_contents('hello.txt.~2~', 'new hello2')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
116
117
    def test_unknowns(self):
118
        tree = self.make_branch_and_tree('.')
119
        self.build_tree(['hello.txt',
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
120
                         'hello.txt.~1~'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
121
        self.assertEquals(list(tree.unknowns()),
122
                          ['hello.txt'])
123
124
    def test_hashcache(self):
125
        from bzrlib.tests.test_hashcache import pause
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
126
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
127
        self.build_tree(['hello.txt',
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
128
                         'hello.txt.~1~'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
129
        tree.add('hello.txt')
130
        pause()
131
        sha = tree.get_file_sha1(tree.path2id('hello.txt'))
132
        self.assertEqual(1, tree._hashcache.miss_count)
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
133
        tree2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
134
        sha2 = tree2.get_file_sha1(tree2.path2id('hello.txt'))
135
        self.assertEqual(0, tree2._hashcache.miss_count)
136
        self.assertEqual(1, tree2._hashcache.hit_count)
137
138
    def test_initialize(self):
139
        # initialize should create a working tree and branch in an existing dir
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
140
        t = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
141
        b = Branch.open('.')
142
        self.assertEqual(t.branch.base, b.base)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
143
        t2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
144
        self.assertEqual(t.basedir, t2.basedir)
145
        self.assertEqual(b.base, t2.branch.base)
146
        # TODO maybe we should check the branch format? not sure if its
147
        # appropriate here.
148
149
    def test_rename_dirs(self):
150
        """Test renaming directories and the files within them."""
151
        wt = self.make_branch_and_tree('.')
152
        b = wt.branch
153
        self.build_tree(['dir/', 'dir/sub/', 'dir/sub/file'])
154
        wt.add(['dir', 'dir/sub', 'dir/sub/file'])
155
156
        wt.commit('create initial state')
157
158
        revid = b.revision_history()[0]
159
        self.log('first revision_id is {%s}' % revid)
160
        
161
        inv = b.repository.get_revision_inventory(revid)
162
        self.log('contents of inventory: %r' % inv.entries())
163
164
        self.check_inventory_shape(inv,
165
                                   ['dir', 'dir/sub', 'dir/sub/file'])
166
167
        wt.rename_one('dir', 'newdir')
168
169
        self.check_inventory_shape(wt.read_working_inventory(),
170
                                   ['newdir', 'newdir/sub', 'newdir/sub/file'])
171
172
        wt.rename_one('newdir/sub', 'newdir/newsub')
173
        self.check_inventory_shape(wt.read_working_inventory(),
174
                                   ['newdir', 'newdir/newsub',
175
                                    'newdir/newsub/file'])
176
177
    def test_add_in_unversioned(self):
178
        """Try to add a file in an unversioned directory.
179
180
        "bzr add" adds the parent as necessary, but simple working tree add
181
        doesn't do that.
182
        """
183
        from bzrlib.errors import NotVersionedError
184
        wt = self.make_branch_and_tree('.')
185
        self.build_tree(['foo/',
186
                         'foo/hello'])
187
        self.assertRaises(NotVersionedError,
188
                          wt.add,
189
                          'foo/hello')
190
191
    def test_add_missing(self):
192
        # adding a msising file -> NoSuchFile
193
        wt = self.make_branch_and_tree('.')
194
        self.assertRaises(errors.NoSuchFile, wt.add, 'fpp')
195
196
    def test_remove_verbose(self):
197
        #FIXME the remove api should not print or otherwise depend on the
198
        # text UI - RBC 20060124
199
        wt = self.make_branch_and_tree('.')
200
        self.build_tree(['hello'])
201
        wt.add(['hello'])
202
        wt.commit(message='add hello')
203
        stdout = StringIO()
204
        stderr = StringIO()
205
        self.assertEqual(None, self.apply_redirected(None, stdout, stderr,
206
                                                     wt.remove,
207
                                                     ['hello'],
208
                                                     verbose=True))
209
        self.assertEqual('?       hello\n', stdout.getvalue())
210
        self.assertEqual('', stderr.getvalue())
211
212
    def test_clone_trivial(self):
213
        wt = self.make_branch_and_tree('source')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
214
        cloned_dir = wt.bzrdir.clone('target')
215
        cloned = cloned_dir.open_workingtree()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
216
        self.assertEqual(cloned.last_revision(), wt.last_revision())
217
218
    def test_last_revision(self):
219
        wt = self.make_branch_and_tree('source')
220
        self.assertEqual(None, wt.last_revision())
221
        wt.commit('A', allow_pointless=True, rev_id='A')
222
        self.assertEqual('A', wt.last_revision())
223
224
    def test_set_last_revision(self):
225
        wt = self.make_branch_and_tree('source')
226
        self.assertEqual(None, wt.last_revision())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
227
        # cannot set the last revision to one not in the branch history.
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
228
        self.assertRaises(errors.NoSuchRevision, wt.set_last_revision, 'A')
229
        wt.commit('A', allow_pointless=True, rev_id='A')
230
        self.assertEqual('A', wt.last_revision())
231
        # None is aways in the branch
232
        wt.set_last_revision(None)
233
        self.assertEqual(None, wt.last_revision())
234
        # and now we can set it to 'A'
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
235
        # because some formats mutate the branch to set it on the tree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
236
        # we need to alter the branch to let this pass.
237
        wt.branch.set_revision_history(['A', 'B'])
238
        wt.set_last_revision('A')
239
        self.assertEqual('A', wt.last_revision())
240
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
241
    def test_set_last_revision_different_to_branch(self):
242
        # working tree formats from the meta-dir format and newer support
243
        # setting the last revision on a tree independently of that on the 
244
        # branch. Its concievable that some future formats may want to 
245
        # couple them again (i.e. because its really a smart server and
246
        # the working tree will always match the branch). So we test
247
        # that formats where initialising a branch does not initialise a 
248
        # tree - and thus have separable entities - support skewing the 
249
        # two things.
250
        branch = self.make_branch('tree')
251
        try:
252
            # if there is a working tree now, this is not supported.
253
            branch.bzrdir.open_workingtree()
254
            return
255
        except errors.NoWorkingTree:
256
            pass
257
        wt = branch.bzrdir.create_workingtree()
258
        wt.commit('A', allow_pointless=True, rev_id='A')
259
        wt.set_last_revision(None)
260
        self.assertEqual(None, wt.last_revision())
261
        self.assertEqual('A', wt.branch.last_revision())
262
        # and now we can set it back to 'A'
263
        wt.set_last_revision('A')
264
        self.assertEqual('A', wt.last_revision())
265
        self.assertEqual('A', wt.branch.last_revision())
266
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
267
    def test_clone_and_commit_preserves_last_revision(self):
268
        wt = self.make_branch_and_tree('source')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
269
        cloned_dir = wt.bzrdir.clone('target')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
270
        wt.commit('A', allow_pointless=True, rev_id='A')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
271
        self.assertNotEqual(cloned_dir.open_workingtree().last_revision(),
272
                            wt.last_revision())
273
274
    def test_clone_preserves_content(self):
275
        wt = self.make_branch_and_tree('source')
276
        self.build_tree(['added', 'deleted', 'notadded'], transport=wt.bzrdir.transport.clone('..'))
277
        wt.add('deleted', 'deleted')
278
        wt.commit('add deleted')
279
        wt.remove('deleted')
280
        wt.add('added', 'added')
281
        cloned_dir = wt.bzrdir.clone('target')
282
        cloned = cloned_dir.open_workingtree()
283
        cloned_transport = cloned.bzrdir.transport.clone('..')
284
        self.assertFalse(cloned_transport.has('deleted'))
285
        self.assertTrue(cloned_transport.has('added'))
286
        self.assertFalse(cloned_transport.has('notadded'))
287
        self.assertEqual('added', cloned.path2id('added'))
288
        self.assertEqual(None, cloned.path2id('deleted'))
289
        self.assertEqual(None, cloned.path2id('notadded'))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
290
        
291
    def test_basis_tree_returns_last_revision(self):
292
        wt = self.make_branch_and_tree('.')
293
        self.build_tree(['foo'])
294
        wt.add('foo', 'foo-id')
295
        wt.commit('A', rev_id='A')
296
        wt.rename_one('foo', 'bar')
297
        wt.commit('B', rev_id='B')
298
        wt.set_last_revision('B')
299
        tree = wt.basis_tree()
300
        self.failUnless(tree.has_filename('bar'))
301
        wt.set_last_revision('A')
302
        tree = wt.basis_tree()
303
        self.failUnless(tree.has_filename('foo'))
304
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
305
    def test_clone_tree_revision(self):
306
        # make a tree with a last-revision,
307
        # and clone it with a different last-revision, this should switch
308
        # do it.
309
        #
310
        # also test that the content is merged
311
        # and conflicts recorded.
312
        # This should merge between the trees - local edits should be preserved
313
        # but other changes occured.
314
        # we test this by having one file that does
315
        # not change between two revisions, and another that does -
316
        # if the changed one is not changed, fail,
317
        # if the one that did not change has lost a local change, fail.
318
        # 
319
        raise TestSkipped('revision limiting is not implemented yet.')
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
320
321
    def test_initialize_with_revision_id(self):
322
        # a bzrdir can construct a working tree for itself @ a specific revision.
323
        source = self.make_branch_and_tree('source')
324
        source.commit('a', rev_id='a', allow_pointless=True)
325
        source.commit('b', rev_id='b', allow_pointless=True)
326
        self.build_tree(['new/'])
327
        made_control = self.bzrdir_format.initialize('new')
328
        source.branch.repository.clone(made_control)
329
        source.branch.clone(made_control)
330
        made_tree = self.workingtree_format.initialize(made_control, revision_id='a')
331
        self.assertEqual('a', made_tree.last_revision())
1508.1.23 by Robert Collins
Test that the working tree last revision is indeed set during commit.
332
333
    def test_commit_sets_last_revision(self):
334
        tree = self.make_branch_and_tree('tree')
335
        tree.commit('foo', rev_id='foo', allow_pointless=True)
336
        self.assertEqual('foo', tree.last_revision())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
337
1587.1.8 by Robert Collins
Local commits on unbound branches fail.
338
    def test_commit_local_unbound(self):
339
        # using the library api to do a local commit on unbound branches is 
340
        # also an error
341
        tree = self.make_branch_and_tree('tree')
342
        self.assertRaises(errors.LocalRequiresBoundBranch,
343
                          tree.commit,
344
                          'foo',
345
                          local=True)
1587.1.9 by Robert Collins
Local commits do no alter or access the master branch.
346
 
347
    def test_local_commit_ignores_master(self):
348
        # a --local commit does not require access to the master branch
349
        # at all, or even for it to exist.
350
        # we test this by setting up a bound branch and then corrupting
351
        # the master.
352
        master = self.make_branch('master')
353
        tree = self.make_branch_and_tree('tree')
354
        try:
355
            tree.branch.bind(master)
356
        except errors.UpgradeRequired:
357
            # older format.
358
            return
359
        master.bzrdir.transport.put('branch-format', StringIO('garbage'))
360
        del master
361
        # check its corrupted.
362
        self.assertRaises(errors.UnknownFormatError,
363
                          bzrdir.BzrDir.open,
364
                          'master')
365
        tree.commit('foo', rev_id='foo', local=True)
366
 
367
    def test_local_commit_does_not_push_to_master(self):
368
        # a --local commit does not require access to the master branch
369
        # at all, or even for it to exist.
370
        # we test that even when its available it does not push to it.
371
        master = self.make_branch('master')
372
        tree = self.make_branch_and_tree('tree')
373
        try:
374
            tree.branch.bind(master)
375
        except errors.UpgradeRequired:
376
            # older format.
377
            return
378
        tree.commit('foo', rev_id='foo', local=True)
379
        self.failIf(master.repository.has_revision('foo'))
380
        self.assertEqual(None, master.last_revision())
381
        
1508.1.24 by Robert Collins
Add update command for use with checkouts.
382
    def test_update_sets_last_revision(self):
383
        # working tree formats from the meta-dir format and newer support
384
        # setting the last revision on a tree independently of that on the 
385
        # branch. Its concievable that some future formats may want to 
386
        # couple them again (i.e. because its really a smart server and
387
        # the working tree will always match the branch). So we test
388
        # that formats where initialising a branch does not initialise a 
389
        # tree - and thus have separable entities - support skewing the 
390
        # two things.
391
        main_branch = self.make_branch('tree')
392
        try:
393
            # if there is a working tree now, this is not supported.
394
            main_branch.bzrdir.open_workingtree()
395
            return
396
        except errors.NoWorkingTree:
397
            pass
398
        wt = main_branch.bzrdir.create_workingtree()
399
        # create an out of date working tree by making a checkout in this
400
        # current format
401
        self.build_tree(['checkout/', 'tree/file'])
402
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1508.1.25 by Robert Collins
Update per review comments.
403
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
404
        old_tree = self.workingtree_format.initialize(checkout)
405
        # now commit to 'tree'
406
        wt.add('file')
407
        wt.commit('A', rev_id='A')
408
        # and update old_tree
409
        self.assertEqual(0, old_tree.update())
410
        self.failUnlessExists('checkout/file')
411
        self.assertEqual('A', old_tree.last_revision())
412
413
    def test_update_returns_conflict_count(self):
414
        # working tree formats from the meta-dir format and newer support
415
        # setting the last revision on a tree independently of that on the 
416
        # branch. Its concievable that some future formats may want to 
417
        # couple them again (i.e. because its really a smart server and
418
        # the working tree will always match the branch). So we test
419
        # that formats where initialising a branch does not initialise a 
420
        # tree - and thus have separable entities - support skewing the 
421
        # two things.
422
        main_branch = self.make_branch('tree')
423
        try:
424
            # if there is a working tree now, this is not supported.
425
            main_branch.bzrdir.open_workingtree()
426
            return
427
        except errors.NoWorkingTree:
428
            pass
429
        wt = main_branch.bzrdir.create_workingtree()
430
        # create an out of date working tree by making a checkout in this
431
        # current format
432
        self.build_tree(['checkout/', 'tree/file'])
433
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1508.1.25 by Robert Collins
Update per review comments.
434
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
435
        old_tree = self.workingtree_format.initialize(checkout)
436
        # now commit to 'tree'
437
        wt.add('file')
438
        wt.commit('A', rev_id='A')
439
        # and add a file file to the checkout
440
        self.build_tree(['checkout/file'])
441
        old_tree.add('file')
442
        # and update old_tree
443
        self.assertEqual(1, old_tree.update())
444
        self.assertEqual('A', old_tree.last_revision())
445
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
446
    def test_merge_revert(self):
447
        from bzrlib.merge import merge_inner
448
        this = self.make_branch_and_tree('b1')
449
        open('b1/a', 'wb').write('a test\n')
450
        this.add('a')
451
        open('b1/b', 'wb').write('b test\n')
452
        this.add('b')
453
        this.commit(message='')
454
        base = this.bzrdir.clone('b2').open_workingtree()
455
        open('b2/a', 'wb').write('b test\n')
456
        other = this.bzrdir.clone('b3').open_workingtree()
457
        open('b3/a', 'wb').write('c test\n')
458
        open('b3/c', 'wb').write('c test\n')
459
        other.add('c')
460
461
        open('b1/b', 'wb').write('q test\n')
462
        open('b1/d', 'wb').write('d test\n')
463
        merge_inner(this.branch, other, base, this_tree=this)
464
        self.assertNotEqual(open('b1/a', 'rb').read(), 'a test\n')
465
        this.revert([])
466
        self.assertEqual(open('b1/a', 'rb').read(), 'a test\n')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
467
        self.assertIs(os.path.exists('b1/b.~1~'), True)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
468
        self.assertIs(os.path.exists('b1/c'), False)
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
469
        self.assertIs(os.path.exists('b1/a.~1~'), False)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
470
        self.assertIs(os.path.exists('b1/d'), True)
1534.7.200 by Aaron Bentley
Merge from mainline
471
1587.1.10 by Robert Collins
update updates working tree and branch together.
472
    def test_update_updates_bound_branch_no_local_commits(self):
473
        # doing an update in a tree updates the branch its bound to too.
474
        master_tree = self.make_branch_and_tree('master')
475
        tree = self.make_branch_and_tree('tree')
476
        try:
477
            tree.branch.bind(master_tree.branch)
478
        except errors.UpgradeRequired:
479
            # legacy branches cannot bind
480
            return
481
        master_tree.commit('foo', rev_id='foo', allow_pointless=True)
482
        tree.update()
483
        self.assertEqual('foo', tree.last_revision())
484
        self.assertEqual('foo', tree.branch.last_revision())
1587.1.11 by Robert Collins
Local commits appear to be working properly.
485
486
    def test_update_turns_local_commit_into_merge(self):
487
        # doing an update with a few local commits and no master commits
1587.1.13 by Robert Collins
Explain why update pivots more clearly in the relevant test.
488
        # makes pending-merges. 
489
        # this is done so that 'bzr update; bzr revert' will always produce
490
        # an exact copy of the 'logical branch' - the referenced branch for
491
        # a checkout, and the master for a bound branch.
492
        # its possible that we should instead have 'bzr update' when there
493
        # is nothing new on the master leave the current commits intact and
494
        # alter 'revert' to revert to the master always. But for now, its
495
        # good.
1587.1.11 by Robert Collins
Local commits appear to be working properly.
496
        master_tree = self.make_branch_and_tree('master')
497
        tree = self.make_branch_and_tree('tree')
498
        try:
499
            tree.branch.bind(master_tree.branch)
500
        except errors.UpgradeRequired:
501
            # legacy branches cannot bind
502
            return
503
        tree.commit('foo', rev_id='foo', allow_pointless=True, local=True)
504
        tree.commit('bar', rev_id='bar', allow_pointless=True, local=True)
505
        tree.update()
506
        self.assertEqual(None, tree.last_revision())
507
        self.assertEqual([], tree.branch.revision_history())
508
        self.assertEqual(['bar'], tree.pending_merges())
509
1558.3.3 by Aaron Bentley
Fix error handling for merge_modified
510
    def test_merge_modified(self):
511
        tree = self.make_branch_and_tree('master')
512
        tree._control_files.put('merge-hashes', StringIO('asdfasdf'))
513
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
514
1534.10.22 by Aaron Bentley
Got ConflictList implemented
515
    def test_conflicts(self):
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
516
        from bzrlib.tests.test_conflicts import example_conflicts
517
        tree = self.make_branch_and_tree('master')
518
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
519
            tree.set_conflicts(example_conflicts)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
520
        except UnsupportedOperation:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
521
            raise TestSkipped('set_conflicts not supported')
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
522
            
523
        tree2 = WorkingTree.open('master')
1534.10.22 by Aaron Bentley
Got ConflictList implemented
524
        self.assertEqual(tree2.conflicts(), example_conflicts)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
525
        tree2._control_files.put('conflicts', StringIO(''))
526
        self.assertRaises(errors.ConflictFormatError, 
1534.10.22 by Aaron Bentley
Got ConflictList implemented
527
                          tree2.conflicts)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
528
        tree2._control_files.put('conflicts', StringIO('a'))
529
        self.assertRaises(errors.ConflictFormatError, 
1534.10.22 by Aaron Bentley
Got ConflictList implemented
530
                          tree2.conflicts)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
531
532
    def make_merge_conflicts(self):
533
        from bzrlib.merge import merge_inner 
534
        tree = self.make_branch_and_tree('mine')
535
        file('mine/bloo', 'wb').write('one')
536
        tree.add('bloo')
1534.10.14 by Aaron Bentley
Made revert clear conflicts
537
        file('mine/blo', 'wb').write('on')
538
        tree.add('blo')
1534.10.12 by Aaron Bentley
Merge produces new conflicts
539
        tree.commit("blah", allow_pointless=False)
540
        base = tree.basis_tree()
541
        BzrDir.open("mine").sprout("other")
542
        file('other/bloo', 'wb').write('two')
543
        othertree = WorkingTree.open('other')
544
        othertree.commit('blah', allow_pointless=False)
545
        file('mine/bloo', 'wb').write('three')
546
        tree.commit("blah", allow_pointless=False)
547
        merge_inner(tree.branch, othertree, base, this_tree=tree)
548
        return tree
549
550
    def test_merge_conflicts(self):
551
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
552
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
553
554
    def test_clear_merge_conflicts(self):
1534.10.22 by Aaron Bentley
Got ConflictList implemented
555
        from bzrlib.conflicts import ConflictList
1534.10.12 by Aaron Bentley
Merge produces new conflicts
556
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
557
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
558
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
559
            tree.set_conflicts(ConflictList())
1534.10.12 by Aaron Bentley
Merge produces new conflicts
560
        except UnsupportedOperation:
561
            raise TestSkipped
1534.10.22 by Aaron Bentley
Got ConflictList implemented
562
        self.assertEqual(tree.conflicts(), ConflictList())
1534.10.14 by Aaron Bentley
Made revert clear conflicts
563
564
    def test_revert_clear_conflicts(self):
565
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
566
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
567
        tree.revert(["blo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
568
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
569
        tree.revert(["bloo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
570
        self.assertEqual(len(tree.conflicts()), 0)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
571
572
    def test_revert_clear_conflicts2(self):
573
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
574
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
575
        tree.revert([])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
576
        self.assertEqual(len(tree.conflicts()), 0)