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