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