/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1852.15.19 by John Arbash Meinel
[merge] bzr.dev 2255
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
2
# Authors:  Robert Collins <robert.collins@canonical.com>
2255.13.4 by Martin Pool
merge
3
#           and others
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
from cStringIO import StringIO
20
import os
1711.7.19 by John Arbash Meinel
file:// urls look slightly different on win32
21
import sys
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
22
23
import bzrlib
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
24
from bzrlib import branch, bzrdir, errors, osutils, urlutils, workingtree
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
25
from bzrlib.errors import (NotBranchError, NotVersionedError,
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
26
                           UnsupportedOperation, PathsNotVersionedError)
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
27
from bzrlib.inventory import Inventory
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
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
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
3034.4.9 by Alexander Belchenko
skip test_workingtree.TestWorkingTree.test_case_sensitive for WT2
33
                                WorkingTree, WorkingTree2)
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
34
from bzrlib.conflicts import ConflictList, TextConflict, ContentsConflict
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
35
1711.7.19 by John Arbash Meinel
file:// urls look slightly different on win32
36
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
37
class TestWorkingTree(TestCaseWithWorkingTree):
38
1732.1.8 by John Arbash Meinel
Adding a test for list_files
39
    def test_list_files(self):
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
40
        tree = self.make_branch_and_tree('.')
1732.1.8 by John Arbash Meinel
Adding a test for list_files
41
        self.build_tree(['dir/', 'file'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
42
        if has_symlinks():
43
            os.symlink('target', 'symlink')
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
44
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
45
        files = list(tree.list_files())
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
46
        tree.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
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
1732.1.8 by John Arbash Meinel
Adding a test for list_files
52
    def test_list_files_sorted(self):
53
        tree = self.make_branch_and_tree('.')
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
54
        self.build_tree(['dir/', 'file', 'dir/file', 'dir/b',
55
                         'dir/subdir/', 'a', 'dir/subfile',
56
                         'zz_dir/', 'zz_dir/subfile'])
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
57
        tree.lock_read()
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
58
        files = [(path, kind) for (path, v, kind, file_id, entry)
59
                               in tree.list_files()]
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
60
        tree.unlock()
1732.1.8 by John Arbash Meinel
Adding a test for list_files
61
        self.assertEqual([
62
            ('a', 'file'),
63
            ('dir', 'directory'),
64
            ('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.
65
            ('zz_dir', 'directory'),
1732.1.8 by John Arbash Meinel
Adding a test for list_files
66
            ], files)
67
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.
68
        tree.add(['dir', 'zz_dir'])
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
69
        tree.lock_read()
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
70
        files = [(path, kind) for (path, v, kind, file_id, entry)
71
                               in tree.list_files()]
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
72
        tree.unlock()
1732.1.8 by John Arbash Meinel
Adding a test for list_files
73
        self.assertEqual([
74
            ('a', 'file'),
75
            ('dir', 'directory'),
76
            ('dir/b', 'file'),
77
            ('dir/file', 'file'),
78
            ('dir/subdir', 'directory'),
79
            ('dir/subfile', 'file'),
80
            ('file', 'file'),
1732.1.22 by John Arbash Meinel
Bug in list_files if the last entry in a directory is another directory
81
            ('zz_dir', 'directory'),
82
            ('zz_dir/subfile', 'file'),
1732.1.8 by John Arbash Meinel
Adding a test for list_files
83
            ], files)
84
1551.10.29 by Aaron Bentley
Fix tree.list_files when file kind changes
85
    def test_list_files_kind_change(self):
86
        tree = self.make_branch_and_tree('tree')
87
        self.build_tree(['tree/filename'])
88
        tree.add('filename', 'file-id')
89
        os.unlink('tree/filename')
90
        self.build_tree(['tree/filename/'])
91
        tree.lock_read()
92
        self.addCleanup(tree.unlock)
93
        result = list(tree.list_files())
94
        self.assertEqual(1, len(result))
95
        self.assertEqual(('filename', 'V', 'directory', 'file-id'),
96
                         result[0][:4])
97
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
98
    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.
99
        branch = self.make_branch_and_tree('.').branch
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
100
        local_base = urlutils.local_path_from_url(branch.base)
101
102
        # Empty opens '.'
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
103
        wt, relpath = WorkingTree.open_containing()
104
        self.assertEqual('', relpath)
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
105
        self.assertEqual(wt.basedir + '/', local_base)
106
107
        # '.' opens this dir
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
108
        wt, relpath = WorkingTree.open_containing(u'.')
109
        self.assertEqual('', relpath)
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
110
        self.assertEqual(wt.basedir + '/', local_base)
111
112
        # './foo' finds '.' and a relpath of 'foo'
113
        wt, relpath = WorkingTree.open_containing('./foo')
114
        self.assertEqual('foo', relpath)
115
        self.assertEqual(wt.basedir + '/', local_base)
116
117
        # abspath(foo) finds '.' and relpath of 'foo'
118
        wt, relpath = WorkingTree.open_containing('./foo')
119
        wt, relpath = WorkingTree.open_containing(getcwd() + '/foo')
120
        self.assertEqual('foo', relpath)
121
        self.assertEqual(wt.basedir + '/', local_base)
122
123
        # can even be a url: finds '.' and relpath of 'foo'
124
        wt, relpath = WorkingTree.open_containing('./foo')
125
        wt, relpath = WorkingTree.open_containing(
126
                    urlutils.local_path_to_url(getcwd() + '/foo'))
127
        self.assertEqual('foo', relpath)
128
        self.assertEqual(wt.basedir + '/', local_base)
129
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
130
    def test_basic_relpath(self):
131
        # 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.
132
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
133
        self.assertEqual('child',
134
                         tree.relpath(pathjoin(getcwd(), 'child')))
135
136
    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.
137
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
138
        tree.lock_read()
139
        self.assertEqual('r', tree.branch.peek_lock_mode())
140
        tree.unlock()
141
        self.assertEqual(None, tree.branch.peek_lock_mode())
142
        tree.lock_write()
143
        self.assertEqual('w', tree.branch.peek_lock_mode())
144
        tree.unlock()
145
        self.assertEqual(None, tree.branch.peek_lock_mode())
146
 
147
    def test_revert(self):
148
        """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.
149
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
150
151
        self.build_tree(['hello.txt'])
152
        file('hello.txt', 'w').write('initial hello')
153
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
154
        self.assertRaises(PathsNotVersionedError,
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
155
                          tree.revert, ['hello.txt'])
156
        tree.add(['hello.txt'])
157
        tree.commit('create initial hello.txt')
158
159
        self.check_file_contents('hello.txt', 'initial hello')
160
        file('hello.txt', 'w').write('new hello')
161
        self.check_file_contents('hello.txt', 'new hello')
162
163
        # revert file modified since last revision
164
        tree.revert(['hello.txt'])
165
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
166
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
167
168
        # reverting again does not clobber the backup
169
        tree.revert(['hello.txt'])
170
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
171
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.10.28 by Aaron Bentley
Use numbered backup files
172
        
173
        # backup files are numbered
174
        file('hello.txt', 'w').write('new hello2')
175
        tree.revert(['hello.txt'])
176
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
177
        self.check_file_contents('hello.txt.~1~', 'new hello')
178
        self.check_file_contents('hello.txt.~2~', 'new hello2')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
179
1558.12.7 by Aaron Bentley
Fixed revert with missing files
180
    def test_revert_missing(self):
181
        # Revert a file that has been deleted since last commit
182
        tree = self.make_branch_and_tree('.')
183
        file('hello.txt', 'w').write('initial hello')
184
        tree.add('hello.txt')
185
        tree.commit('added hello.txt')
186
        os.unlink('hello.txt')
187
        tree.remove('hello.txt')
188
        tree.revert(['hello.txt'])
189
        self.failUnlessExists('hello.txt')
190
1740.6.1 by Martin Pool
Remove Scratch objects used by doctests
191
    def test_versioned_files_not_unknown(self):
192
        tree = self.make_branch_and_tree('.')
1831.1.1 by Martin Pool
[merge] remove default ignore list & update
193
        self.build_tree(['hello.txt'])
1740.6.1 by Martin Pool
Remove Scratch objects used by doctests
194
        tree.add('hello.txt')
195
        self.assertEquals(list(tree.unknowns()),
196
                          [])
1831.1.1 by Martin Pool
[merge] remove default ignore list & update
197
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
198
    def test_unknowns(self):
199
        tree = self.make_branch_and_tree('.')
200
        self.build_tree(['hello.txt',
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
201
                         'hello.txt.~1~'])
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
202
        self.build_tree_contents([('.bzrignore', '*.~*\n')])
203
        tree.add('.bzrignore')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
204
        self.assertEquals(list(tree.unknowns()),
205
                          ['hello.txt'])
206
207
    def test_initialize(self):
208
        # 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.
209
        t = self.make_branch_and_tree('.')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
210
        b = branch.Branch.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
211
        self.assertEqual(t.branch.base, b.base)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
212
        t2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
213
        self.assertEqual(t.basedir, t2.basedir)
214
        self.assertEqual(b.base, t2.branch.base)
215
        # TODO maybe we should check the branch format? not sure if its
216
        # appropriate here.
217
218
    def test_rename_dirs(self):
219
        """Test renaming directories and the files within them."""
220
        wt = self.make_branch_and_tree('.')
221
        b = wt.branch
222
        self.build_tree(['dir/', 'dir/sub/', 'dir/sub/file'])
223
        wt.add(['dir', 'dir/sub', 'dir/sub/file'])
224
225
        wt.commit('create initial state')
226
227
        revid = b.revision_history()[0]
228
        self.log('first revision_id is {%s}' % revid)
229
        
230
        inv = b.repository.get_revision_inventory(revid)
231
        self.log('contents of inventory: %r' % inv.entries())
232
233
        self.check_inventory_shape(inv,
2545.3.2 by James Westby
Add a test for check_inventory_shape.
234
                                   ['dir/', 'dir/sub/', 'dir/sub/file'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
235
        wt.rename_one('dir', 'newdir')
236
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
237
        wt.lock_read()
238
        self.check_inventory_shape(wt.inventory,
2545.3.2 by James Westby
Add a test for check_inventory_shape.
239
                                   ['newdir/', 'newdir/sub/', 'newdir/sub/file'])
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
240
        wt.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
241
        wt.rename_one('newdir/sub', 'newdir/newsub')
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
242
        wt.lock_read()
243
        self.check_inventory_shape(wt.inventory,
2545.3.2 by James Westby
Add a test for check_inventory_shape.
244
                                   ['newdir/', 'newdir/newsub/',
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
245
                                    'newdir/newsub/file'])
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
246
        wt.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
247
248
    def test_add_in_unversioned(self):
249
        """Try to add a file in an unversioned directory.
250
251
        "bzr add" adds the parent as necessary, but simple working tree add
252
        doesn't do that.
253
        """
254
        from bzrlib.errors import NotVersionedError
255
        wt = self.make_branch_and_tree('.')
256
        self.build_tree(['foo/',
257
                         'foo/hello'])
258
        self.assertRaises(NotVersionedError,
259
                          wt.add,
260
                          'foo/hello')
261
262
    def test_add_missing(self):
263
        # adding a msising file -> NoSuchFile
264
        wt = self.make_branch_and_tree('.')
265
        self.assertRaises(errors.NoSuchFile, wt.add, 'fpp')
266
267
    def test_remove_verbose(self):
268
        #FIXME the remove api should not print or otherwise depend on the
269
        # text UI - RBC 20060124
270
        wt = self.make_branch_and_tree('.')
271
        self.build_tree(['hello'])
272
        wt.add(['hello'])
273
        wt.commit(message='add hello')
274
        stdout = StringIO()
275
        stderr = StringIO()
276
        self.assertEqual(None, self.apply_redirected(None, stdout, stderr,
277
                                                     wt.remove,
278
                                                     ['hello'],
279
                                                     verbose=True))
280
        self.assertEqual('?       hello\n', stdout.getvalue())
281
        self.assertEqual('', stderr.getvalue())
282
283
    def test_clone_trivial(self):
284
        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.
285
        cloned_dir = wt.bzrdir.clone('target')
286
        cloned = cloned_dir.open_workingtree()
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
287
        self.assertEqual(cloned.get_parent_ids(), wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
288
289
    def test_last_revision(self):
290
        wt = self.make_branch_and_tree('source')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
291
        self.assertEqual([], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
292
        wt.commit('A', allow_pointless=True, rev_id='A')
2249.5.7 by John Arbash Meinel
Make sure WorkingTree revision_ids are also returned as utf8 strings
293
        parent_ids = wt.get_parent_ids()
294
        self.assertEqual(['A'], parent_ids)
295
        for parent_id in parent_ids:
296
            self.assertIsInstance(parent_id, str)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
297
298
    def test_set_last_revision(self):
299
        wt = self.make_branch_and_tree('source')
1908.1.1 by Robert Collins
Relax WorkingTree.set_last-revision to allow any revision to be set.
300
        # set last-revision to one not in the history
301
        wt.set_last_revision('A')
302
        # set it back to None for an empty tree.
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
303
        wt.set_last_revision('null:')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
304
        wt.commit('A', allow_pointless=True, rev_id='A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
305
        self.assertEqual(['A'], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
306
        # None is aways in the branch
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
307
        wt.set_last_revision('null:')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
308
        self.assertEqual([], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
309
        # and now we can set it to 'A'
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
310
        # because some formats mutate the branch to set it on the tree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
311
        # we need to alter the branch to let this pass.
2230.3.27 by Aaron Bentley
Skip arbitrary revision-history test for Branch6
312
        try:
313
            wt.branch.set_revision_history(['A', 'B'])
314
        except errors.NoSuchRevision, e:
315
            self.assertEqual('B', e.revision)
316
            raise TestSkipped("Branch format does not permit arbitrary"
317
                              " history")
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
318
        wt.set_last_revision('A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
319
        self.assertEqual(['A'], wt.get_parent_ids())
2229.2.1 by Aaron Bentley
Reject reserved ids in versiondfile, tree, branch and repository
320
        self.assertRaises(errors.ReservedId, wt.set_last_revision, 'A:')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
321
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
322
    def test_set_last_revision_different_to_branch(self):
323
        # working tree formats from the meta-dir format and newer support
324
        # setting the last revision on a tree independently of that on the 
325
        # branch. Its concievable that some future formats may want to 
326
        # couple them again (i.e. because its really a smart server and
327
        # the working tree will always match the branch). So we test
328
        # that formats where initialising a branch does not initialise a 
329
        # tree - and thus have separable entities - support skewing the 
330
        # two things.
331
        branch = self.make_branch('tree')
332
        try:
333
            # if there is a working tree now, this is not supported.
334
            branch.bzrdir.open_workingtree()
335
            return
336
        except errors.NoWorkingTree:
337
            pass
338
        wt = branch.bzrdir.create_workingtree()
339
        wt.commit('A', allow_pointless=True, rev_id='A')
340
        wt.set_last_revision(None)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
341
        self.assertEqual([], wt.get_parent_ids())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
342
        self.assertEqual('A', wt.branch.last_revision())
343
        # and now we can set it back to 'A'
344
        wt.set_last_revision('A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
345
        self.assertEqual(['A'], wt.get_parent_ids())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
346
        self.assertEqual('A', wt.branch.last_revision())
347
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
348
    def test_clone_and_commit_preserves_last_revision(self):
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
349
        """Doing a commit into a clone tree does not affect the source."""
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
350
        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.
351
        cloned_dir = wt.bzrdir.clone('target')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
352
        wt.commit('A', allow_pointless=True, rev_id='A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
353
        self.assertNotEqual(cloned_dir.open_workingtree().get_parent_ids(),
354
                            wt.get_parent_ids())
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.
355
356
    def test_clone_preserves_content(self):
357
        wt = self.make_branch_and_tree('source')
2255.2.51 by John Arbash Meinel
simple rewrap for 79 char lines
358
        self.build_tree(['added', 'deleted', 'notadded'],
359
                        transport=wt.bzrdir.transport.clone('..'))
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.
360
        wt.add('deleted', 'deleted')
361
        wt.commit('add deleted')
362
        wt.remove('deleted')
363
        wt.add('added', 'added')
364
        cloned_dir = wt.bzrdir.clone('target')
365
        cloned = cloned_dir.open_workingtree()
366
        cloned_transport = cloned.bzrdir.transport.clone('..')
367
        self.assertFalse(cloned_transport.has('deleted'))
368
        self.assertTrue(cloned_transport.has('added'))
369
        self.assertFalse(cloned_transport.has('notadded'))
370
        self.assertEqual('added', cloned.path2id('added'))
371
        self.assertEqual(None, cloned.path2id('deleted'))
372
        self.assertEqual(None, cloned.path2id('notadded'))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
373
        
374
    def test_basis_tree_returns_last_revision(self):
375
        wt = self.make_branch_and_tree('.')
376
        self.build_tree(['foo'])
377
        wt.add('foo', 'foo-id')
378
        wt.commit('A', rev_id='A')
379
        wt.rename_one('foo', 'bar')
380
        wt.commit('B', rev_id='B')
1908.6.3 by Robert Collins
Tidy up the last_revision_id and add_pending_merge conversion to use cleaner apis.
381
        wt.set_parent_ids(['B'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
382
        tree = wt.basis_tree()
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
383
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
384
        self.failUnless(tree.has_filename('bar'))
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
385
        tree.unlock()
1908.6.3 by Robert Collins
Tidy up the last_revision_id and add_pending_merge conversion to use cleaner apis.
386
        wt.set_parent_ids(['A'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
387
        tree = wt.basis_tree()
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
388
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
389
        self.failUnless(tree.has_filename('foo'))
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
390
        tree.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
391
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.
392
    def test_clone_tree_revision(self):
393
        # make a tree with a last-revision,
394
        # and clone it with a different last-revision, this should switch
395
        # do it.
396
        #
397
        # also test that the content is merged
398
        # and conflicts recorded.
399
        # This should merge between the trees - local edits should be preserved
400
        # but other changes occured.
401
        # we test this by having one file that does
402
        # not change between two revisions, and another that does -
403
        # if the changed one is not changed, fail,
404
        # if the one that did not change has lost a local change, fail.
405
        # 
406
        raise TestSkipped('revision limiting is not implemented yet.')
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
407
408
    def test_initialize_with_revision_id(self):
409
        # a bzrdir can construct a working tree for itself @ a specific revision.
410
        source = self.make_branch_and_tree('source')
411
        source.commit('a', rev_id='a', allow_pointless=True)
412
        source.commit('b', rev_id='b', allow_pointless=True)
413
        self.build_tree(['new/'])
414
        made_control = self.bzrdir_format.initialize('new')
415
        source.branch.repository.clone(made_control)
416
        source.branch.clone(made_control)
417
        made_tree = self.workingtree_format.initialize(made_control, revision_id='a')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
418
        self.assertEqual(['a'], made_tree.get_parent_ids())
1508.1.23 by Robert Collins
Test that the working tree last revision is indeed set during commit.
419
1508.1.24 by Robert Collins
Add update command for use with checkouts.
420
    def test_update_sets_last_revision(self):
421
        # working tree formats from the meta-dir format and newer support
422
        # setting the last revision on a tree independently of that on the 
423
        # branch. Its concievable that some future formats may want to 
424
        # couple them again (i.e. because its really a smart server and
425
        # the working tree will always match the branch). So we test
426
        # that formats where initialising a branch does not initialise a 
427
        # tree - and thus have separable entities - support skewing the 
428
        # two things.
429
        main_branch = self.make_branch('tree')
430
        try:
431
            # if there is a working tree now, this is not supported.
432
            main_branch.bzrdir.open_workingtree()
433
            return
434
        except errors.NoWorkingTree:
435
            pass
436
        wt = main_branch.bzrdir.create_workingtree()
437
        # create an out of date working tree by making a checkout in this
438
        # current format
439
        self.build_tree(['checkout/', 'tree/file'])
440
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
441
        branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
442
        old_tree = self.workingtree_format.initialize(checkout)
443
        # now commit to 'tree'
444
        wt.add('file')
445
        wt.commit('A', rev_id='A')
446
        # and update old_tree
447
        self.assertEqual(0, old_tree.update())
448
        self.failUnlessExists('checkout/file')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
449
        self.assertEqual(['A'], old_tree.get_parent_ids())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
450
1731.1.33 by Aaron Bentley
Revert no-special-root changes
451
    def test_update_sets_root_id(self):
452
        """Ensure tree root is set properly by update.
453
        
454
        Since empty trees don't have root_ids, but workingtrees do,
455
        an update of a checkout of revision 0 to a new revision,  should set
456
        the root id.
457
        """
458
        wt = self.make_branch_and_tree('tree')
459
        main_branch = wt.branch
460
        # create an out of date working tree by making a checkout in this
461
        # current format
462
        self.build_tree(['checkout/', 'tree/file'])
1731.1.43 by Aaron Bentley
Merge more checkout changes
463
        checkout = main_branch.create_checkout('checkout')
1731.1.33 by Aaron Bentley
Revert no-special-root changes
464
        # now commit to 'tree'
465
        wt.add('file')
466
        wt.commit('A', rev_id='A')
467
        # and update checkout 
468
        self.assertEqual(0, checkout.update())
469
        self.failUnlessExists('checkout/file')
470
        self.assertEqual(wt.get_root_id(), checkout.get_root_id())
471
        self.assertNotEqual(None, wt.get_root_id())
472
1508.1.24 by Robert Collins
Add update command for use with checkouts.
473
    def test_update_returns_conflict_count(self):
474
        # working tree formats from the meta-dir format and newer support
475
        # setting the last revision on a tree independently of that on the 
476
        # branch. Its concievable that some future formats may want to 
477
        # couple them again (i.e. because its really a smart server and
478
        # the working tree will always match the branch). So we test
479
        # that formats where initialising a branch does not initialise a 
480
        # tree - and thus have separable entities - support skewing the 
481
        # two things.
482
        main_branch = self.make_branch('tree')
483
        try:
484
            # if there is a working tree now, this is not supported.
485
            main_branch.bzrdir.open_workingtree()
486
            return
487
        except errors.NoWorkingTree:
488
            pass
489
        wt = main_branch.bzrdir.create_workingtree()
490
        # create an out of date working tree by making a checkout in this
491
        # current format
492
        self.build_tree(['checkout/', 'tree/file'])
493
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
494
        branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
495
        old_tree = self.workingtree_format.initialize(checkout)
496
        # now commit to 'tree'
497
        wt.add('file')
498
        wt.commit('A', rev_id='A')
499
        # and add a file file to the checkout
500
        self.build_tree(['checkout/file'])
501
        old_tree.add('file')
502
        # and update old_tree
503
        self.assertEqual(1, old_tree.update())
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
504
        self.assertEqual(['A'], old_tree.get_parent_ids())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
505
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
506
    def test_merge_revert(self):
507
        from bzrlib.merge import merge_inner
508
        this = self.make_branch_and_tree('b1')
509
        open('b1/a', 'wb').write('a test\n')
510
        this.add('a')
511
        open('b1/b', 'wb').write('b test\n')
512
        this.add('b')
513
        this.commit(message='')
514
        base = this.bzrdir.clone('b2').open_workingtree()
515
        open('b2/a', 'wb').write('b test\n')
516
        other = this.bzrdir.clone('b3').open_workingtree()
517
        open('b3/a', 'wb').write('c test\n')
518
        open('b3/c', 'wb').write('c test\n')
519
        other.add('c')
520
521
        open('b1/b', 'wb').write('q test\n')
522
        open('b1/d', 'wb').write('d test\n')
523
        merge_inner(this.branch, other, base, this_tree=this)
524
        self.assertNotEqual(open('b1/a', 'rb').read(), 'a test\n')
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
525
        this.revert()
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
526
        self.assertEqual(open('b1/a', 'rb').read(), 'a test\n')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
527
        self.assertIs(os.path.exists('b1/b.~1~'), True)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
528
        self.assertIs(os.path.exists('b1/c'), False)
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
529
        self.assertIs(os.path.exists('b1/a.~1~'), False)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
530
        self.assertIs(os.path.exists('b1/d'), True)
1534.7.200 by Aaron Bentley
Merge from mainline
531
1587.1.10 by Robert Collins
update updates working tree and branch together.
532
    def test_update_updates_bound_branch_no_local_commits(self):
533
        # doing an update in a tree updates the branch its bound to too.
534
        master_tree = self.make_branch_and_tree('master')
535
        tree = self.make_branch_and_tree('tree')
536
        try:
537
            tree.branch.bind(master_tree.branch)
538
        except errors.UpgradeRequired:
539
            # legacy branches cannot bind
540
            return
541
        master_tree.commit('foo', rev_id='foo', allow_pointless=True)
542
        tree.update()
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
543
        self.assertEqual(['foo'], tree.get_parent_ids())
1587.1.10 by Robert Collins
update updates working tree and branch together.
544
        self.assertEqual('foo', tree.branch.last_revision())
1587.1.11 by Robert Collins
Local commits appear to be working properly.
545
546
    def test_update_turns_local_commit_into_merge(self):
547
        # 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.
548
        # makes pending-merges. 
549
        # this is done so that 'bzr update; bzr revert' will always produce
550
        # an exact copy of the 'logical branch' - the referenced branch for
551
        # a checkout, and the master for a bound branch.
552
        # its possible that we should instead have 'bzr update' when there
553
        # is nothing new on the master leave the current commits intact and
554
        # alter 'revert' to revert to the master always. But for now, its
555
        # good.
1587.1.11 by Robert Collins
Local commits appear to be working properly.
556
        master_tree = self.make_branch_and_tree('master')
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
557
        master_tip = master_tree.commit('first master commit')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
558
        tree = self.make_branch_and_tree('tree')
559
        try:
560
            tree.branch.bind(master_tree.branch)
561
        except errors.UpgradeRequired:
562
            # legacy branches cannot bind
563
            return
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
564
        # sync with master
565
        tree.update()
566
        # work locally
1587.1.11 by Robert Collins
Local commits appear to be working properly.
567
        tree.commit('foo', rev_id='foo', allow_pointless=True, local=True)
568
        tree.commit('bar', rev_id='bar', allow_pointless=True, local=True)
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
569
        # sync with master prepatory to committing
1587.1.11 by Robert Collins
Local commits appear to be working properly.
570
        tree.update()
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
571
        # which should have pivoted the local tip into a merge
572
        self.assertEqual([master_tip, 'bar'], tree.get_parent_ids())
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
573
        # and the local branch history should match the masters now.
574
        self.assertEqual(master_tree.branch.revision_history(),
575
            tree.branch.revision_history())
1587.1.11 by Robert Collins
Local commits appear to be working properly.
576
2255.2.156 by Martin Pool
Merge WorkingTree implementation back from trunk
577
    def test_merge_modified_detects_corruption(self):
578
        # FIXME: This doesn't really test that it works; also this is not
579
        # implementation-independent. mbp 20070226
1558.3.3 by Aaron Bentley
Fix error handling for merge_modified
580
        tree = self.make_branch_and_tree('master')
1955.3.14 by John Arbash Meinel
Correctly fix the workingtree put() test fixes
581
        tree._control_files.put('merge-hashes', StringIO('asdfasdf'))
1558.3.3 by Aaron Bentley
Fix error handling for merge_modified
582
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
583
2298.1.1 by Martin Pool
Add test for merge_modified
584
    def test_merge_modified(self):
585
        # merge_modified stores a map from file id to hash
586
        tree = self.make_branch_and_tree('tree')
587
        d = {'file-id': osutils.sha_string('hello')}
588
        self.build_tree_contents([('tree/somefile', 'hello')])
589
        tree.lock_write()
590
        try:
591
            tree.add(['somefile'], ['file-id'])
592
            tree.set_merge_modified(d)
593
            mm = tree.merge_modified()
594
            self.assertEquals(mm, d)
595
        finally:
596
            tree.unlock()
597
        mm = tree.merge_modified()
598
        self.assertEquals(mm, d)
599
1534.10.22 by Aaron Bentley
Got ConflictList implemented
600
    def test_conflicts(self):
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
601
        from bzrlib.tests.test_conflicts import example_conflicts
602
        tree = self.make_branch_and_tree('master')
603
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
604
            tree.set_conflicts(example_conflicts)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
605
        except UnsupportedOperation:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
606
            raise TestSkipped('set_conflicts not supported')
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
607
            
608
        tree2 = WorkingTree.open('master')
1534.10.22 by Aaron Bentley
Got ConflictList implemented
609
        self.assertEqual(tree2.conflicts(), example_conflicts)
1955.3.14 by John Arbash Meinel
Correctly fix the workingtree put() test fixes
610
        tree2._control_files.put('conflicts', StringIO(''))
611
        self.assertRaises(errors.ConflictFormatError, 
612
                          tree2.conflicts)
613
        tree2._control_files.put('conflicts', StringIO('a'))
614
        self.assertRaises(errors.ConflictFormatError, 
615
                          tree2.conflicts)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
616
617
    def make_merge_conflicts(self):
2255.2.32 by Robert Collins
Make test_clear_merge_conflicts pass for dirstate. This involved working
618
        from bzrlib.merge import merge_inner
1534.10.12 by Aaron Bentley
Merge produces new conflicts
619
        tree = self.make_branch_and_tree('mine')
620
        file('mine/bloo', 'wb').write('one')
1534.10.14 by Aaron Bentley
Made revert clear conflicts
621
        file('mine/blo', 'wb').write('on')
2255.2.32 by Robert Collins
Make test_clear_merge_conflicts pass for dirstate. This involved working
622
        tree.add(['bloo', 'blo'])
1534.10.12 by Aaron Bentley
Merge produces new conflicts
623
        tree.commit("blah", allow_pointless=False)
2255.5.3 by John Arbash Meinel
XXX Workaround the DirStateRevisionTree bug until we get a proper fix, tests pass again
624
        base = tree.branch.repository.revision_tree(tree.last_revision())
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
625
        bzrdir.BzrDir.open("mine").sprout("other")
1534.10.12 by Aaron Bentley
Merge produces new conflicts
626
        file('other/bloo', 'wb').write('two')
627
        othertree = WorkingTree.open('other')
628
        othertree.commit('blah', allow_pointless=False)
629
        file('mine/bloo', 'wb').write('three')
630
        tree.commit("blah", allow_pointless=False)
631
        merge_inner(tree.branch, othertree, base, this_tree=tree)
632
        return tree
633
634
    def test_merge_conflicts(self):
635
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
636
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
637
638
    def test_clear_merge_conflicts(self):
639
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
640
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
641
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
642
            tree.set_conflicts(ConflictList())
1534.10.12 by Aaron Bentley
Merge produces new conflicts
643
        except UnsupportedOperation:
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
644
            raise TestSkipped('unsupported operation')
1534.10.22 by Aaron Bentley
Got ConflictList implemented
645
        self.assertEqual(tree.conflicts(), ConflictList())
1534.10.14 by Aaron Bentley
Made revert clear conflicts
646
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
647
    def test_add_conflicts(self):
648
        tree = self.make_branch_and_tree('tree')
649
        try:
650
            tree.add_conflicts([TextConflict('path_a')])
651
        except UnsupportedOperation:
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
652
            raise TestSkipped('unsupported operation')
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
653
        self.assertEqual(ConflictList([TextConflict('path_a')]),
654
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
655
        tree.add_conflicts([TextConflict('path_a')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
656
        self.assertEqual(ConflictList([TextConflict('path_a')]), 
657
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
658
        tree.add_conflicts([ContentsConflict('path_a')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
659
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
660
                                       TextConflict('path_a')]),
661
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
662
        tree.add_conflicts([TextConflict('path_b')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
663
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
664
                                       TextConflict('path_a'),
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
665
                                       TextConflict('path_b')]),
666
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
667
1534.10.14 by Aaron Bentley
Made revert clear conflicts
668
    def test_revert_clear_conflicts(self):
669
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
670
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
671
        tree.revert(["blo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
672
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
673
        tree.revert(["bloo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
674
        self.assertEqual(len(tree.conflicts()), 0)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
675
676
    def test_revert_clear_conflicts2(self):
677
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
678
        self.assertEqual(len(tree.conflicts()), 1)
2748.3.2 by Aaron Bentley
Fix revert, remove-tree, and various tests to use None for 'no files specified'
679
        tree.revert()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
680
        self.assertEqual(len(tree.conflicts()), 0)
1624.3.22 by Olaf Conradi
Merge bzr.dev
681
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
682
    def test_format_description(self):
683
        tree = self.make_branch_and_tree('tree')
684
        text = tree._format.get_format_description()
685
        self.failUnless(len(text))
1681.1.1 by Robert Collins
Make WorkingTree.branch a read only property. (Robert Collins)
686
687
    def test_branch_attribute_is_not_settable(self):
688
        # the branch attribute is an aspect of the working tree, not a
689
        # configurable attribute
690
        tree = self.make_branch_and_tree('tree')
691
        def set_branch():
692
            tree.branch = tree.branch
693
        self.assertRaises(AttributeError, set_branch)
694
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
695
    def test_list_files_versioned_before_ignored(self):
696
        """A versioned file matching an ignore rule should not be ignored."""
697
        tree = self.make_branch_and_tree('.')
698
        self.build_tree(['foo.pyc'])
699
        # ensure that foo.pyc is ignored
700
        self.build_tree_contents([('.bzrignore', 'foo.pyc')])
701
        tree.add('foo.pyc', 'anid')
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
702
        tree.lock_read()
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
703
        files = sorted(list(tree.list_files()))
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
704
        tree.unlock()
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
705
        self.assertEqual((u'.bzrignore', '?', 'file', None), files[0][:-1])
706
        self.assertEqual((u'foo.pyc', 'V', 'file', 'anid'), files[1][:-1])
707
        self.assertEqual(2, len(files))
1711.8.2 by John Arbash Meinel
Test that WorkingTree locks Branch before self, and unlocks self before Branch
708
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
709
    def test_non_normalized_add_accessible(self):
710
        try:
711
            self.build_tree([u'a\u030a'])
712
        except UnicodeError:
713
            raise TestSkipped('Filesystem does not support unicode filenames')
714
        tree = self.make_branch_and_tree('.')
715
        orig = osutils.normalized_filename
716
        osutils.normalized_filename = osutils._accessible_normalized_filename
717
        try:
718
            tree.add([u'a\u030a'])
2255.2.58 by Robert Collins
Fix the way we used osutils.normalized_filename in dirstate to support overriding in tests - and document this in the original location it was used.
719
            tree.lock_read()
1907.1.3 by Aaron Bentley
Fixed unicode test cases
720
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
721
                    [(path, ie.kind) for path,ie in 
722
                                tree.inventory.iter_entries()])
2255.2.58 by Robert Collins
Fix the way we used osutils.normalized_filename in dirstate to support overriding in tests - and document this in the original location it was used.
723
            tree.unlock()
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
724
        finally:
725
            osutils.normalized_filename = orig
726
727
    def test_non_normalized_add_inaccessible(self):
728
        try:
729
            self.build_tree([u'a\u030a'])
730
        except UnicodeError:
731
            raise TestSkipped('Filesystem does not support unicode filenames')
732
        tree = self.make_branch_and_tree('.')
733
        orig = osutils.normalized_filename
734
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
735
        try:
736
            self.assertRaises(errors.InvalidNormalization,
737
                tree.add, [u'a\u030a'])
738
        finally:
739
            osutils.normalized_filename = orig
2123.3.9 by Steffen Eichenberg
added tests for deprecated API workingtree.move
740
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
741
    def test__write_inventory(self):
742
        # The private interface _write_inventory is currently used by transform.
743
        tree = self.make_branch_and_tree('.')
744
        # if we write write an inventory then do a walkdirs we should get back
745
        # missing entries, and actual, and unknowns as appropriate.
746
        self.build_tree(['present', 'unknown'])
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
747
        inventory = Inventory(tree.get_root_id())
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
748
        inventory.add_path('missing', 'file', 'missing-id')
749
        inventory.add_path('present', 'file', 'present-id')
2255.2.28 by Robert Collins
TestWorkingTree.test__write_inventory needs to lock the tree before calling _write_inventory for dirstate.
750
        # there is no point in being able to write an inventory to an unlocked
751
        # tree object - its a low level api not a convenience api.
752
        tree.lock_write()
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
753
        tree._write_inventory(inventory)
2255.2.28 by Robert Collins
TestWorkingTree.test__write_inventory needs to lock the tree before calling _write_inventory for dirstate.
754
        tree.unlock()
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
755
        tree.lock_read()
756
        try:
757
            present_stat = os.lstat('present')
758
            unknown_stat = os.lstat('unknown')
759
            expected_results = [
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
760
                (('', tree.get_root_id()),
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
761
                 [('missing', 'missing', 'unknown', None, 'missing-id', 'file'),
762
                  ('present', 'present', 'file', present_stat, 'present-id', 'file'),
763
                  ('unknown', 'unknown', 'file', unknown_stat, None, None),
764
                 ]
765
                )]
766
            self.assertEqual(expected_results, list(tree.walkdirs()))
767
        finally:
768
            tree.unlock()
2255.7.56 by Robert Collins
Document behaviour of tree.path2id("path/").
769
770
    def test_path2id(self):
2255.7.62 by Robert Collins
Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
771
        # smoke test for path2id
2255.7.56 by Robert Collins
Document behaviour of tree.path2id("path/").
772
        tree = self.make_branch_and_tree('.')
773
        self.build_tree(['foo'])
774
        tree.add(['foo'], ['foo-id'])
775
        self.assertEqual('foo-id', tree.path2id('foo'))
776
        # the next assertion is for backwards compatability with WorkingTree3,
777
        # though its probably a bad idea, it makes things work. Perhaps
778
        # it should raise a deprecation warning?
779
        self.assertEqual('foo-id', tree.path2id('foo/'))
2255.7.62 by Robert Collins
Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
780
781
    def test_filter_unversioned_files(self):
782
        # smoke test for filter_unversioned_files
783
        tree = self.make_branch_and_tree('.')
784
        paths = ['here-and-versioned', 'here-and-not-versioned',
785
            'not-here-and-versioned', 'not-here-and-not-versioned']
786
        tree.add(['here-and-versioned', 'not-here-and-versioned'],
787
            kinds=['file', 'file'])
788
        self.build_tree(['here-and-versioned', 'here-and-not-versioned'])
789
        tree.lock_read()
790
        self.addCleanup(tree.unlock)
791
        self.assertEqual(
792
            set(['not-here-and-not-versioned', 'here-and-not-versioned']),
793
            tree.filter_unversioned_files(paths))
2255.2.200 by Martin Pool
Add simple test for WorkingTree.kind
794
795
    def test_detect_real_kind(self):
796
        # working trees report the real kind of the file on disk, not the kind
797
        # they had when they were first added
798
        # create one file of every interesting type
799
        tree = self.make_branch_and_tree('.')
800
        self.build_tree(['file', 'directory/'])
801
        names = ['file', 'directory']
802
        if has_symlinks():
803
            os.symlink('target', 'symlink')
804
            names.append('symlink')
805
        tree.add(names, [n + '-id' for n in names])
806
        if tree.supports_tree_reference():
807
            sub_tree = self.make_branch_and_tree('tree-reference')
808
            sub_tree.set_root_id('tree-reference-id')
809
            sub_tree.commit('message')
810
            names.append('tree-reference')
811
            tree.add_reference(sub_tree)
812
        # now when we first look, we should see everything with the same kind
813
        # with which they were initially added
814
        for n in names:
815
            actual_kind = tree.kind(n + '-id')
816
            self.assertEqual(n, actual_kind)
817
        # move them around so the names no longer correspond to the types
818
        os.rename(names[0], 'tmp')
819
        for i in range(1, len(names)):
820
            os.rename(names[i], names[i-1])
821
        os.rename('tmp', names[-1])
2255.2.202 by Martin Pool
WorkingTree_4.kind should report tree-references if they're
822
        # now look and expect to see the correct types again
823
        for i in range(len(names)):
824
            actual_kind = tree.kind(names[i-1] + '-id')
825
            expected_kind = names[i]
826
            self.assertEqual(expected_kind, actual_kind)
2499.3.1 by Aaron Bentley
Fix Workingtree4.get_file_sha1 on missing files
827
828
    def test_missing_file_sha1(self):
829
        """If a file is missing, its sha1 should be reported as None."""
830
        tree = self.make_branch_and_tree('.')
831
        tree.lock_write()
832
        self.addCleanup(tree.unlock)
833
        self.build_tree(['file'])
834
        tree.add('file', 'file-id')
835
        tree.commit('file added')
836
        os.unlink('file')
837
        self.assertIs(None, tree.get_file_sha1('file-id'))
1551.15.56 by Aaron Bentley
Raise NoSuchId when get_file_sha1 is invoked with a baed file id
838
839
    def test_no_file_sha1(self):
840
        """If a file is not present, get_file_sha1 should raise NoSuchId"""
841
        tree = self.make_branch_and_tree('.')
842
        tree.lock_write()
843
        self.addCleanup(tree.unlock)
844
        self.assertRaises(errors.NoSuchId, tree.get_file_sha1, 'file-id')
845
        self.build_tree(['file'])
846
        tree.add('file', 'file-id')
847
        tree.commit('foo')
848
        tree.remove('file')
849
        self.assertRaises(errors.NoSuchId, tree.get_file_sha1, 'file-id')
3034.4.5 by Aaron Bentley
Add workingtree test for case_insensitive var
850
851
    def test_case_sensitive(self):
852
        """If filesystem is case-sensitive, tree should report this.
853
854
        We check case-sensitivity by creating a file with a lowercase name,
855
        then testing whether it exists with an uppercase name.
856
        """
3034.4.9 by Alexander Belchenko
skip test_workingtree.TestWorkingTree.test_case_sensitive for WT2
857
        self.build_tree(['filename'])
3034.4.5 by Aaron Bentley
Add workingtree test for case_insensitive var
858
        if os.path.exists('FILENAME'):
859
            case_sensitive = False
860
        else:
861
            case_sensitive = True
862
        tree = self.make_branch_and_tree('test')
3034.4.9 by Alexander Belchenko
skip test_workingtree.TestWorkingTree.test_case_sensitive for WT2
863
        if tree.__class__ == WorkingTree2:
864
            raise TestSkipped('WorkingTree2 is not supported')
3034.4.5 by Aaron Bentley
Add workingtree test for case_insensitive var
865
        self.assertEqual(case_sensitive, tree.case_sensitive)