/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
27
from bzrlib.errors import NotBranchError, NotVersionedError
28
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.
29
from bzrlib.tests import TestSkipped
30
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
31
from bzrlib.trace import mutter
32
import bzrlib.workingtree as workingtree
33
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
34
                                WorkingTree)
35
36
37
class TestWorkingTree(TestCaseWithWorkingTree):
38
39
    def test_listfiles(self):
40
        tree = self.make_branch_and_tree('.')
41
        os.mkdir('dir')
42
        print >> open('file', 'w'), "content"
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
51
    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.
52
        branch = self.make_branch_and_tree('.').branch
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
53
        wt, relpath = WorkingTree.open_containing()
54
        self.assertEqual('', relpath)
55
        self.assertEqual(wt.basedir + '/', branch.base)
56
        wt, relpath = WorkingTree.open_containing(u'.')
57
        self.assertEqual('', relpath)
58
        self.assertEqual(wt.basedir + '/', branch.base)
59
        wt, relpath = WorkingTree.open_containing('./foo')
60
        self.assertEqual('foo', relpath)
61
        self.assertEqual(wt.basedir + '/', branch.base)
62
        wt, relpath = WorkingTree.open_containing('file://' + getcwd() + '/foo')
63
        self.assertEqual('foo', relpath)
64
        self.assertEqual(wt.basedir + '/', branch.base)
65
66
    def test_basic_relpath(self):
67
        # 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.
68
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
69
        self.assertEqual('child',
70
                         tree.relpath(pathjoin(getcwd(), 'child')))
71
72
    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.
73
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
74
        tree.lock_read()
75
        self.assertEqual('r', tree.branch.peek_lock_mode())
76
        tree.unlock()
77
        self.assertEqual(None, tree.branch.peek_lock_mode())
78
        tree.lock_write()
79
        self.assertEqual('w', tree.branch.peek_lock_mode())
80
        tree.unlock()
81
        self.assertEqual(None, tree.branch.peek_lock_mode())
82
 
83
    def get_pullable_trees(self):
84
        self.build_tree(['from/', 'from/file', 'to/'])
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.
85
        tree = self.make_branch_and_tree('from')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
86
        tree.add('file')
87
        tree.commit('foo', 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.
88
        tree_b = self.make_branch_and_tree('to')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
89
        return tree, tree_b
90
 
91
    def test_pull(self):
92
        tree_a, tree_b = self.get_pullable_trees()
93
        tree_b.pull(tree_a.branch)
94
        self.failUnless(tree_b.branch.repository.has_revision('A'))
95
        self.assertEqual('A', tree_b.last_revision())
96
97
    def test_pull_overwrites(self):
98
        tree_a, tree_b = self.get_pullable_trees()
99
        tree_b.commit('foo', rev_id='B')
100
        self.assertEqual(['B'], tree_b.branch.revision_history())
101
        tree_b.pull(tree_a.branch, overwrite=True)
102
        self.failUnless(tree_b.branch.repository.has_revision('A'))
103
        self.failUnless(tree_b.branch.repository.has_revision('B'))
104
        self.assertEqual('A', tree_b.last_revision())
105
106
    def test_revert(self):
107
        """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.
108
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
109
110
        self.build_tree(['hello.txt'])
111
        file('hello.txt', 'w').write('initial hello')
112
113
        self.assertRaises(NotVersionedError,
114
                          tree.revert, ['hello.txt'])
115
        tree.add(['hello.txt'])
116
        tree.commit('create initial hello.txt')
117
118
        self.check_file_contents('hello.txt', 'initial hello')
119
        file('hello.txt', 'w').write('new hello')
120
        self.check_file_contents('hello.txt', 'new hello')
121
122
        # revert file modified since last revision
123
        tree.revert(['hello.txt'])
124
        self.check_file_contents('hello.txt', 'initial hello')
125
        self.check_file_contents('hello.txt~', 'new hello')
126
127
        # reverting again does not clobber the backup
128
        tree.revert(['hello.txt'])
129
        self.check_file_contents('hello.txt', 'initial hello')
130
        self.check_file_contents('hello.txt~', 'new hello')
131
132
    def test_unknowns(self):
133
        tree = self.make_branch_and_tree('.')
134
        self.build_tree(['hello.txt',
135
                         'hello.txt~'])
136
        self.assertEquals(list(tree.unknowns()),
137
                          ['hello.txt'])
138
139
    def test_hashcache(self):
140
        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.
141
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
142
        self.build_tree(['hello.txt',
143
                         'hello.txt~'])
144
        tree.add('hello.txt')
145
        pause()
146
        sha = tree.get_file_sha1(tree.path2id('hello.txt'))
147
        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.
148
        tree2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
149
        sha2 = tree2.get_file_sha1(tree2.path2id('hello.txt'))
150
        self.assertEqual(0, tree2._hashcache.miss_count)
151
        self.assertEqual(1, tree2._hashcache.hit_count)
152
153
    def test_initialize(self):
154
        # 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.
155
        t = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
156
        b = Branch.open('.')
157
        self.assertEqual(t.branch.base, b.base)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
158
        t2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
159
        self.assertEqual(t.basedir, t2.basedir)
160
        self.assertEqual(b.base, t2.branch.base)
161
        # TODO maybe we should check the branch format? not sure if its
162
        # appropriate here.
163
164
    def test_rename_dirs(self):
165
        """Test renaming directories and the files within them."""
166
        wt = self.make_branch_and_tree('.')
167
        b = wt.branch
168
        self.build_tree(['dir/', 'dir/sub/', 'dir/sub/file'])
169
        wt.add(['dir', 'dir/sub', 'dir/sub/file'])
170
171
        wt.commit('create initial state')
172
173
        revid = b.revision_history()[0]
174
        self.log('first revision_id is {%s}' % revid)
175
        
176
        inv = b.repository.get_revision_inventory(revid)
177
        self.log('contents of inventory: %r' % inv.entries())
178
179
        self.check_inventory_shape(inv,
180
                                   ['dir', 'dir/sub', 'dir/sub/file'])
181
182
        wt.rename_one('dir', 'newdir')
183
184
        self.check_inventory_shape(wt.read_working_inventory(),
185
                                   ['newdir', 'newdir/sub', 'newdir/sub/file'])
186
187
        wt.rename_one('newdir/sub', 'newdir/newsub')
188
        self.check_inventory_shape(wt.read_working_inventory(),
189
                                   ['newdir', 'newdir/newsub',
190
                                    'newdir/newsub/file'])
191
192
    def test_add_in_unversioned(self):
193
        """Try to add a file in an unversioned directory.
194
195
        "bzr add" adds the parent as necessary, but simple working tree add
196
        doesn't do that.
197
        """
198
        from bzrlib.errors import NotVersionedError
199
        wt = self.make_branch_and_tree('.')
200
        self.build_tree(['foo/',
201
                         'foo/hello'])
202
        self.assertRaises(NotVersionedError,
203
                          wt.add,
204
                          'foo/hello')
205
206
    def test_add_missing(self):
207
        # adding a msising file -> NoSuchFile
208
        wt = self.make_branch_and_tree('.')
209
        self.assertRaises(errors.NoSuchFile, wt.add, 'fpp')
210
211
    def test_remove_verbose(self):
212
        #FIXME the remove api should not print or otherwise depend on the
213
        # text UI - RBC 20060124
214
        wt = self.make_branch_and_tree('.')
215
        self.build_tree(['hello'])
216
        wt.add(['hello'])
217
        wt.commit(message='add hello')
218
        stdout = StringIO()
219
        stderr = StringIO()
220
        self.assertEqual(None, self.apply_redirected(None, stdout, stderr,
221
                                                     wt.remove,
222
                                                     ['hello'],
223
                                                     verbose=True))
224
        self.assertEqual('?       hello\n', stdout.getvalue())
225
        self.assertEqual('', stderr.getvalue())
226
227
    def test_clone_trivial(self):
228
        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.
229
        cloned_dir = wt.bzrdir.clone('target')
230
        cloned = cloned_dir.open_workingtree()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
231
        self.assertEqual(cloned.last_revision(), wt.last_revision())
232
233
    def test_last_revision(self):
234
        wt = self.make_branch_and_tree('source')
235
        self.assertEqual(None, wt.last_revision())
236
        wt.commit('A', allow_pointless=True, rev_id='A')
237
        self.assertEqual('A', wt.last_revision())
238
239
    def test_set_last_revision(self):
240
        wt = self.make_branch_and_tree('source')
241
        self.assertEqual(None, wt.last_revision())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
242
        # cannot set the last revision to one not in the branch history.
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
243
        self.assertRaises(errors.NoSuchRevision, wt.set_last_revision, 'A')
244
        wt.commit('A', allow_pointless=True, rev_id='A')
245
        self.assertEqual('A', wt.last_revision())
246
        # None is aways in the branch
247
        wt.set_last_revision(None)
248
        self.assertEqual(None, wt.last_revision())
249
        # and now we can set it to 'A'
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
250
        # because some formats mutate the branch to set it on the tree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
251
        # we need to alter the branch to let this pass.
252
        wt.branch.set_revision_history(['A', 'B'])
253
        wt.set_last_revision('A')
254
        self.assertEqual('A', wt.last_revision())
255
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
256
    def test_set_last_revision_different_to_branch(self):
257
        # working tree formats from the meta-dir format and newer support
258
        # setting the last revision on a tree independently of that on the 
259
        # branch. Its concievable that some future formats may want to 
260
        # couple them again (i.e. because its really a smart server and
261
        # the working tree will always match the branch). So we test
262
        # that formats where initialising a branch does not initialise a 
263
        # tree - and thus have separable entities - support skewing the 
264
        # two things.
265
        branch = self.make_branch('tree')
266
        try:
267
            # if there is a working tree now, this is not supported.
268
            branch.bzrdir.open_workingtree()
269
            return
270
        except errors.NoWorkingTree:
271
            pass
272
        wt = branch.bzrdir.create_workingtree()
273
        wt.commit('A', allow_pointless=True, rev_id='A')
274
        wt.set_last_revision(None)
275
        self.assertEqual(None, wt.last_revision())
276
        self.assertEqual('A', wt.branch.last_revision())
277
        # and now we can set it back to 'A'
278
        wt.set_last_revision('A')
279
        self.assertEqual('A', wt.last_revision())
280
        self.assertEqual('A', wt.branch.last_revision())
281
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
282
    def test_clone_and_commit_preserves_last_revision(self):
283
        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.
284
        cloned_dir = wt.bzrdir.clone('target')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
285
        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.
286
        self.assertNotEqual(cloned_dir.open_workingtree().last_revision(),
287
                            wt.last_revision())
288
289
    def test_clone_preserves_content(self):
290
        wt = self.make_branch_and_tree('source')
291
        self.build_tree(['added', 'deleted', 'notadded'], transport=wt.bzrdir.transport.clone('..'))
292
        wt.add('deleted', 'deleted')
293
        wt.commit('add deleted')
294
        wt.remove('deleted')
295
        wt.add('added', 'added')
296
        cloned_dir = wt.bzrdir.clone('target')
297
        cloned = cloned_dir.open_workingtree()
298
        cloned_transport = cloned.bzrdir.transport.clone('..')
299
        self.assertFalse(cloned_transport.has('deleted'))
300
        self.assertTrue(cloned_transport.has('added'))
301
        self.assertFalse(cloned_transport.has('notadded'))
302
        self.assertEqual('added', cloned.path2id('added'))
303
        self.assertEqual(None, cloned.path2id('deleted'))
304
        self.assertEqual(None, cloned.path2id('notadded'))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
305
        
306
    def test_basis_tree_returns_last_revision(self):
307
        wt = self.make_branch_and_tree('.')
308
        self.build_tree(['foo'])
309
        wt.add('foo', 'foo-id')
310
        wt.commit('A', rev_id='A')
311
        wt.rename_one('foo', 'bar')
312
        wt.commit('B', rev_id='B')
313
        wt.set_last_revision('B')
314
        tree = wt.basis_tree()
315
        self.failUnless(tree.has_filename('bar'))
316
        wt.set_last_revision('A')
317
        tree = wt.basis_tree()
318
        self.failUnless(tree.has_filename('foo'))
319
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.
320
    def test_clone_tree_revision(self):
321
        # make a tree with a last-revision,
322
        # and clone it with a different last-revision, this should switch
323
        # do it.
324
        #
325
        # also test that the content is merged
326
        # and conflicts recorded.
327
        # This should merge between the trees - local edits should be preserved
328
        # but other changes occured.
329
        # we test this by having one file that does
330
        # not change between two revisions, and another that does -
331
        # if the changed one is not changed, fail,
332
        # if the one that did not change has lost a local change, fail.
333
        # 
334
        raise TestSkipped('revision limiting is not implemented yet.')
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
335
336
    def test_initialize_with_revision_id(self):
337
        # a bzrdir can construct a working tree for itself @ a specific revision.
338
        source = self.make_branch_and_tree('source')
339
        source.commit('a', rev_id='a', allow_pointless=True)
340
        source.commit('b', rev_id='b', allow_pointless=True)
341
        self.build_tree(['new/'])
342
        made_control = self.bzrdir_format.initialize('new')
343
        source.branch.repository.clone(made_control)
344
        source.branch.clone(made_control)
345
        made_tree = self.workingtree_format.initialize(made_control, revision_id='a')
346
        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.
347
348
    def test_commit_sets_last_revision(self):
349
        tree = self.make_branch_and_tree('tree')
350
        tree.commit('foo', rev_id='foo', allow_pointless=True)
351
        self.assertEqual('foo', tree.last_revision())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
352
353
    def test_update_sets_last_revision(self):
354
        # working tree formats from the meta-dir format and newer support
355
        # setting the last revision on a tree independently of that on the 
356
        # branch. Its concievable that some future formats may want to 
357
        # couple them again (i.e. because its really a smart server and
358
        # the working tree will always match the branch). So we test
359
        # that formats where initialising a branch does not initialise a 
360
        # tree - and thus have separable entities - support skewing the 
361
        # two things.
362
        main_branch = self.make_branch('tree')
363
        try:
364
            # if there is a working tree now, this is not supported.
365
            main_branch.bzrdir.open_workingtree()
366
            return
367
        except errors.NoWorkingTree:
368
            pass
369
        wt = main_branch.bzrdir.create_workingtree()
370
        # create an out of date working tree by making a checkout in this
371
        # current format
372
        self.build_tree(['checkout/', 'tree/file'])
373
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1508.1.25 by Robert Collins
Update per review comments.
374
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
375
        old_tree = self.workingtree_format.initialize(checkout)
376
        # now commit to 'tree'
377
        wt.add('file')
378
        wt.commit('A', rev_id='A')
379
        # and update old_tree
380
        self.assertEqual(0, old_tree.update())
381
        self.failUnlessExists('checkout/file')
382
        self.assertEqual('A', old_tree.last_revision())
383
384
    def test_update_returns_conflict_count(self):
385
        # working tree formats from the meta-dir format and newer support
386
        # setting the last revision on a tree independently of that on the 
387
        # branch. Its concievable that some future formats may want to 
388
        # couple them again (i.e. because its really a smart server and
389
        # the working tree will always match the branch). So we test
390
        # that formats where initialising a branch does not initialise a 
391
        # tree - and thus have separable entities - support skewing the 
392
        # two things.
393
        main_branch = self.make_branch('tree')
394
        try:
395
            # if there is a working tree now, this is not supported.
396
            main_branch.bzrdir.open_workingtree()
397
            return
398
        except errors.NoWorkingTree:
399
            pass
400
        wt = main_branch.bzrdir.create_workingtree()
401
        # create an out of date working tree by making a checkout in this
402
        # current format
403
        self.build_tree(['checkout/', 'tree/file'])
404
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1508.1.25 by Robert Collins
Update per review comments.
405
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
406
        old_tree = self.workingtree_format.initialize(checkout)
407
        # now commit to 'tree'
408
        wt.add('file')
409
        wt.commit('A', rev_id='A')
410
        # and add a file file to the checkout
411
        self.build_tree(['checkout/file'])
412
        old_tree.add('file')
413
        # and update old_tree
414
        self.assertEqual(1, old_tree.update())
415
        self.assertEqual('A', old_tree.last_revision())
416