/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
from cStringIO import StringIO
1092.1.26 by Robert Collins
start writing star-topology test, realise we need smart-add change
18
import os
19
import unittest
20
1836.1.22 by John Arbash Meinel
[merge] bzr.dev 1861
21
from bzrlib import errors, ignores, osutils
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
22
from bzrlib.add import (
23
    AddAction,
24
    AddFromBaseAction,
25
    smart_add_tree,
26
    )
1830.3.6 by John Arbash Meinel
Test that smart_add_tree does the right thing in the presence of non-normalized filenames
27
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
28
from bzrlib.errors import NoSuchFile
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
29
from bzrlib.inventory import InventoryFile, Inventory
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
30
from bzrlib.workingtree import WorkingTree
1092.1.26 by Robert Collins
start writing star-topology test, realise we need smart-add change
31
1830.3.4 by John Arbash Meinel
A couple no-op cleanups
32
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
33
class TestSmartAdd(TestCaseWithTransport):
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
34
35
    def test_add_dot_from_root(self):
36
        """Test adding . from the root of the tree.""" 
37
        paths = ("original/", "original/file1", "original/file2")
38
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
39
        wt = self.make_branch_and_tree('.')
40
        smart_add_tree(wt, (u".",))
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
41
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
42
            self.assertNotEqual(wt.path2id(path), None)
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
43
44
    def test_add_dot_from_subdir(self):
45
        """Test adding . from a subdir of the tree.""" 
46
        paths = ("original/", "original/file1", "original/file2")
47
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
48
        wt = self.make_branch_and_tree('.')
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
49
        os.chdir("original")
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
50
        smart_add_tree(wt, (u".",))
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
51
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
52
            self.assertNotEqual(wt.path2id(path), None)
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
53
54
    def test_add_tree_from_above_tree(self):
55
        """Test adding a tree from above the tree.""" 
56
        paths = ("original/", "original/file1", "original/file2")
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
57
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
58
                        "branch/original/file2")
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
59
        self.build_tree(branch_paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
60
        wt = self.make_branch_and_tree('branch')
61
        smart_add_tree(wt, ("branch",))
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
62
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
63
            self.assertNotEqual(wt.path2id(path), None)
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
64
65
    def test_add_above_tree_preserves_tree(self):
66
        """Test nested trees are not affect by an add above them."""
67
        paths = ("original/", "original/file1", "original/file2")
1143 by Martin Pool
- remove dead code and remove some small errors (pychecker)
68
        child_paths = ("path",)
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
69
        full_child_paths = ("original/child", "original/child/path")
70
        build_paths = ("original/", "original/file1", "original/file2", 
71
                       "original/child/", "original/child/path")
1143 by Martin Pool
- remove dead code and remove some small errors (pychecker)
72
        
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
73
        self.build_tree(build_paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
74
        wt = self.make_branch_and_tree('.')
75
        child_tree = self.make_branch_and_tree('original/child')
1757.2.9 by Robert Collins
Remove spurious u cast from test_smart_add.py
76
        smart_add_tree(wt, (".",))
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
77
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
78
            self.assertNotEqual((path, wt.path2id(path)),
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
79
                                (path, None))
80
        for path in full_child_paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
81
            self.assertEqual((path, wt.path2id(path)),
1092.1.27 by Robert Collins
two bugfixes to smart_add - do not add paths from nested trees to the parent tree, and do not mutate the user supplied file list
82
                             (path, None))
83
        for path in child_paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
84
            self.assertEqual(child_tree.path2id(path), None)
1092.1.28 by Robert Collins
test adding lists of paths
85
86
    def test_add_paths(self):
87
        """Test smart-adding a list of paths."""
88
        paths = ("file1", "file2")
89
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
90
        wt = self.make_branch_and_tree('.')
91
        smart_add_tree(wt, paths)
1092.1.28 by Robert Collins
test adding lists of paths
92
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
93
            self.assertNotEqual(wt.path2id(path), None)
1757.2.5 by Robert Collins
De-dup the add list so we only walk subtrees once for add.
94
    
95
    def test_add_ignored_nested_paths(self):
96
        """Test smart-adding a list of paths which includes ignored ones."""
97
        wt = self.make_branch_and_tree('.')
98
        tree_shape = ("adir/", "adir/CVS/", "adir/CVS/afile", "adir/CVS/afile2")
99
        add_paths = ("adir/CVS", "adir/CVS/afile", "adir")
100
        expected_paths = ("adir", "adir/CVS", "adir/CVS/afile", "adir/CVS/afile2")
101
        self.build_tree(tree_shape)
102
        smart_add_tree(wt, add_paths)
103
        for path in expected_paths:
104
            self.assertNotEqual(wt.path2id(path), None, "No id added for %s" % path)
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
105
106
    def test_add_dry_run(self):
107
        """Test a dry run add, make sure nothing is added."""
108
        from bzrlib.commands import run_bzr
109
        eq = self.assertEqual
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
110
        wt = self.make_branch_and_tree('.')
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
111
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
112
        eq(list(wt.unknowns()), ['inertiatic'])
2530.3.4 by Martin Pool
Deprecate run_bzr_captured in favour of just run_bzr
113
        self.run_bzr('add --dry-run .')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
114
        eq(list(wt.unknowns()), ['inertiatic'])
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
115
1185.56.2 by Michael Ellerman
Raise NoSuchFile when someone tries to add a non-existant file.
116
    def test_add_non_existant(self):
117
        """Test smart-adding a file that does not exist."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
118
        wt = self.make_branch_and_tree('.')
119
        self.assertRaises(NoSuchFile, smart_add_tree, wt, 'non-existant-file')
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
120
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
121
    def test_returns_and_ignores(self):
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
122
        """Correctly returns added/ignored files"""
123
        from bzrlib.commands import run_bzr
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
124
        wt = self.make_branch_and_tree('.')
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
125
        # The default ignore list includes '*.py[co]', but not CVS
1987.1.2 by John Arbash Meinel
Remove the unneeded _set_user_ignores(['./.bazaar']) now that home has moved
126
        ignores._set_user_ignores(['*.py[co]'])
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
127
        self.build_tree(['inertiatic/', 'inertiatic/esp', 'inertiatic/CVS',
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
128
                        'inertiatic/foo.pyc'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
129
        added, ignored = smart_add_tree(wt, u'.')
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
130
        self.assertSubset(('inertiatic', 'inertiatic/esp', 'inertiatic/CVS'),
131
                          added)
1836.1.15 by John Arbash Meinel
Updated WorkingTree to use the new user-level ignores.
132
        self.assertSubset(('*.py[co]',), ignored)
133
        self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
134
135
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
136
class AddCustomIDAction(AddAction):
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
137
138
    def __call__(self, inv, parent_ie, path, kind):
139
        # The first part just logs if appropriate
140
        # Now generate a custom id
2309.4.9 by John Arbash Meinel
WorkingTree.merged_modified() needs to switch back to utf8 file ids.
141
        file_id = osutils.safe_file_id(kind + '-'
142
                                       + path.raw_path.replace('/', '%'),
143
                                       warn=False)
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
144
        if self.should_print:
2309.4.9 by John Arbash Meinel
WorkingTree.merged_modified() needs to switch back to utf8 file ids.
145
            self._to_file.write('added %s with id %s\n'
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
146
                                % (path.raw_path, file_id))
147
        return file_id
148
149
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
150
class TestSmartAddTree(TestCaseWithTransport):
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
151
    """Test smart adds with a specified branch."""
152
153
    def test_add_dot_from_root(self):
154
        """Test adding . from the root of the tree.""" 
155
        paths = ("original/", "original/file1", "original/file2")
156
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
157
        wt = self.make_branch_and_tree('.')
158
        smart_add_tree(wt, (u".",))
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
159
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
160
            self.assertNotEqual(wt.path2id(path), None)
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
161
162
    def test_add_dot_from_subdir(self):
163
        """Test adding . from a subdir of the tree.""" 
164
        paths = ("original/", "original/file1", "original/file2")
165
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
166
        wt = self.make_branch_and_tree('.')
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
167
        os.chdir("original")
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
168
        smart_add_tree(wt, (u".",))
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
169
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
170
            self.assertNotEqual(wt.path2id(path), None)
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
171
172
    def test_add_tree_from_above_tree(self):
173
        """Test adding a tree from above the tree.""" 
174
        paths = ("original/", "original/file1", "original/file2")
175
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
176
                        "branch/original/file2")
177
        self.build_tree(branch_paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
178
        tree = self.make_branch_and_tree('branch')
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
179
        smart_add_tree(tree, ("branch",))
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
180
        for path in paths:
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
181
            self.assertNotEqual(tree.path2id(path), None)
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
182
183
    def test_add_above_tree_preserves_tree(self):
184
        """Test nested trees are not affect by an add above them."""
185
        paths = ("original/", "original/file1", "original/file2")
186
        child_paths = ("path")
187
        full_child_paths = ("original/child", "original/child/path")
188
        build_paths = ("original/", "original/file1", "original/file2", 
189
                       "original/child/", "original/child/path")
190
        self.build_tree(build_paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
191
        tree = self.make_branch_and_tree('.')
192
        child_tree = self.make_branch_and_tree("original/child")
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
193
        smart_add_tree(tree, (u".",))
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
194
        for path in paths:
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
195
            self.assertNotEqual((path, tree.path2id(path)),
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
196
                                (path, None))
197
        for path in full_child_paths:
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
198
            self.assertEqual((path, tree.path2id(path)),
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
199
                             (path, None))
200
        for path in child_paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
201
            self.assertEqual(child_tree.path2id(path), None)
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
202
203
    def test_add_paths(self):
204
        """Test smart-adding a list of paths."""
205
        paths = ("file1", "file2")
206
        self.build_tree(paths)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
207
        wt = self.make_branch_and_tree('.')
208
        smart_add_tree(wt, paths)
1092.1.29 by Robert Collins
break smart_add into smart_add and smart_add_branch which will accept a branch parameter
209
        for path in paths:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
210
            self.assertNotEqual(wt.path2id(path), None)
211
1850.2.1 by John Arbash Meinel
Fix bug #52578, smart-add wasn't recursing all supplied directories.
212
    def test_add_multiple_dirs(self):
213
        """Test smart adding multiple directories at once."""
214
        added_paths = ['file1', 'file2',
215
                       'dir1/', 'dir1/file3',
216
                       'dir1/subdir2/', 'dir1/subdir2/file4',
217
                       'dir2/', 'dir2/file5',
218
                      ]
219
        not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
220
        self.build_tree(added_paths)
221
        self.build_tree(not_added)
222
223
        wt = self.make_branch_and_tree('.')
224
        smart_add_tree(wt, ['file1', 'file2', 'dir1', 'dir2'])
225
226
        for path in added_paths:
227
            self.assertNotEqual(None, wt.path2id(path.rstrip('/')),
228
                    'Failed to add path: %s' % (path,))
229
        for path in not_added:
230
            self.assertEqual(None, wt.path2id(path.rstrip('/')),
231
                    'Accidentally added path: %s' % (path,))
232
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
233
    def test_custom_ids(self):
234
        sio = StringIO()
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
235
        action = AddCustomIDAction(to_file=sio, should_print=True)
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
236
        self.build_tree(['file1', 'dir1/', 'dir1/file2'])
237
238
        wt = self.make_branch_and_tree('.')
239
        smart_add_tree(wt, ['.'], action=action)
1911.3.5 by John Arbash Meinel
There is no strict ordering file addition, other than directories are added before child files
240
        # The order of adds is not strictly fixed:
241
        sio.seek(0)
242
        lines = sorted(sio.readlines())
243
        self.assertEqualDiff(['added dir1 with id directory-dir1\n',
244
                              'added dir1/file2 with id file-dir1%file2\n',
245
                              'added file1 with id file-file1\n',
246
                             ], lines)
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
247
        wt.lock_read()
248
        self.addCleanup(wt.unlock)
249
        self.assertEqual([('', wt.path2id('')),
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
250
                          ('dir1', 'directory-dir1'),
251
                          ('dir1/file2', 'file-dir1%file2'),
252
                          ('file1', 'file-file1'),
253
                         ], [(path, ie.file_id) for path, ie
254
                                in wt.inventory.iter_entries()])
255
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
256
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
257
class TestAddFrom(TestCaseWithTransport):
258
    """Tests for AddFromBaseAction"""
259
260
    def make_base_tree(self):
261
        self.base_tree = self.make_branch_and_tree('base')
262
        self.build_tree(['base/a', 'base/b',
263
                         'base/dir/', 'base/dir/a',
264
                         'base/dir/subdir/',
265
                         'base/dir/subdir/b',
266
                        ])
267
        self.base_tree.add(['a', 'b', 'dir', 'dir/a',
268
                            'dir/subdir', 'dir/subdir/b'])
269
        self.base_tree.commit('creating initial tree.')
270
271
    def add_helper(self, base_tree, base_path, new_tree, file_list,
272
                   should_print=False):
273
        to_file = StringIO()
274
        base_tree.lock_read()
275
        try:
276
            new_tree.lock_write()
277
            try:
278
                action = AddFromBaseAction(base_tree, base_path,
279
                                           to_file=to_file,
280
                                           should_print=should_print)
281
                smart_add_tree(new_tree, file_list, action=action)
282
            finally:
283
                new_tree.unlock()
284
        finally:
285
            base_tree.unlock()
286
        return to_file.getvalue()
287
288
    def test_copy_all(self):
289
        self.make_base_tree()
290
        new_tree = self.make_branch_and_tree('new')
291
        files = ['a', 'b',
292
                 'dir/', 'dir/a',
293
                 'dir/subdir/',
294
                 'dir/subdir/b',
295
                ]
296
        self.build_tree(['new/' + fn for fn in files])
297
        self.add_helper(self.base_tree, '', new_tree, ['new'])
298
299
        for fn in files:
300
            base_file_id = self.base_tree.path2id(fn)
301
            new_file_id = new_tree.path2id(fn)
302
            self.assertEqual(base_file_id, new_file_id)
303
304
    def test_copy_from_dir(self):
305
        self.make_base_tree()
306
        new_tree = self.make_branch_and_tree('new')
307
308
        self.build_tree(['new/a', 'new/b', 'new/c',
309
                         'new/subdir/', 'new/subdir/b', 'new/subdir/d'])
1731.1.46 by Aaron Bentley
merge from bzr.dev
310
        new_tree.set_root_id(self.base_tree.get_root_id())
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
311
        self.add_helper(self.base_tree, 'dir', new_tree, ['new'])
312
1731.1.46 by Aaron Bentley
merge from bzr.dev
313
        # We know 'a' and 'b' exist in the root, and they are being added
314
        # in a new 'root'. Since ROOT ids have been set as the same, we will
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
315
        # use those ids
316
        self.assertEqual(self.base_tree.path2id('a'),
317
                         new_tree.path2id('a'))
318
        self.assertEqual(self.base_tree.path2id('b'),
319
                         new_tree.path2id('b'))
320
321
        # Because we specified 'dir/' as the base path, and we have
322
        # nothing named 'subdir' in the base tree, we should grab the
323
        # ids from there
324
        self.assertEqual(self.base_tree.path2id('dir/subdir'),
325
                         new_tree.path2id('subdir'))
326
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
327
                         new_tree.path2id('subdir/b'))
328
329
        # These should get newly generated ids
330
        c_id = new_tree.path2id('c')
331
        self.assertNotEqual(None, c_id)
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
332
        self.base_tree.lock_read()
333
        self.addCleanup(self.base_tree.unlock)
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
334
        self.failIf(c_id in self.base_tree)
335
336
        d_id = new_tree.path2id('subdir/d')
337
        self.assertNotEqual(None, d_id)
338
        self.failIf(d_id in self.base_tree)
339
340
    def test_copy_existing_dir(self):
341
        self.make_base_tree()
342
        new_tree = self.make_branch_and_tree('new')
343
        self.build_tree(['new/subby/', 'new/subby/a', 'new/subby/b'])
344
345
        subdir_file_id = self.base_tree.path2id('dir/subdir')
346
        new_tree.add(['subby'], [subdir_file_id])
347
        self.add_helper(self.base_tree, '', new_tree, ['new'])
348
        # Because 'subby' already points to subdir, we should add
349
        # 'b' with the same id
350
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
351
                         new_tree.path2id('subby/b'))
352
353
        # 'subby/a' should be added with a new id because there is no
354
        # matching path or child of 'subby'.
355
        a_id = new_tree.path2id('subby/a')
356
        self.assertNotEqual(None, a_id)
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
357
        self.base_tree.lock_read()
358
        self.addCleanup(self.base_tree.unlock)
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
359
        self.failIf(a_id in self.base_tree)
360
361
1830.3.6 by John Arbash Meinel
Test that smart_add_tree does the right thing in the presence of non-normalized filenames
362
class TestAddNonNormalized(TestCaseWithTransport):
363
364
    def make(self):
365
        try:
366
            self.build_tree([u'a\u030a'])
367
        except UnicodeError:
368
            raise TestSkipped('Filesystem cannot create unicode filenames')
369
370
        self.wt = self.make_branch_and_tree('.')
371
372
    def test_accessible_explicit(self):
373
        self.make()
374
        orig = osutils.normalized_filename
375
        osutils.normalized_filename = osutils._accessible_normalized_filename
376
        try:
377
            smart_add_tree(self.wt, [u'a\u030a'])
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
378
            self.wt.lock_read()
379
            self.addCleanup(self.wt.unlock)
1907.1.3 by Aaron Bentley
Fixed unicode test cases
380
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
381
                    [(path, ie.kind) for path,ie in 
382
                        self.wt.inventory.iter_entries()])
1830.3.6 by John Arbash Meinel
Test that smart_add_tree does the right thing in the presence of non-normalized filenames
383
        finally:
384
            osutils.normalized_filename = orig
385
386
    def test_accessible_implicit(self):
387
        self.make()
388
        orig = osutils.normalized_filename
389
        osutils.normalized_filename = osutils._accessible_normalized_filename
390
        try:
391
            smart_add_tree(self.wt, [])
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
392
            self.wt.lock_read()
393
            self.addCleanup(self.wt.unlock)
1907.1.3 by Aaron Bentley
Fixed unicode test cases
394
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
395
                    [(path, ie.kind) for path,ie in 
396
                        self.wt.inventory.iter_entries()])
1830.3.6 by John Arbash Meinel
Test that smart_add_tree does the right thing in the presence of non-normalized filenames
397
        finally:
398
            osutils.normalized_filename = orig
399
400
    def test_inaccessible_explicit(self):
401
        self.make()
402
        orig = osutils.normalized_filename
403
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
404
        try:
405
            self.assertRaises(errors.InvalidNormalization,
406
                    smart_add_tree, self.wt, [u'a\u030a'])
407
        finally:
408
            osutils.normalized_filename = orig
409
410
    def test_inaccessible_implicit(self):
411
        self.make()
412
        orig = osutils.normalized_filename
413
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
414
        try:
415
            # TODO: jam 20060701 In the future, this should probably
416
            #       just ignore files that don't fit the normalization
417
            #       rules, rather than exploding
418
            self.assertRaises(errors.InvalidNormalization,
419
                    smart_add_tree, self.wt, [])
420
        finally:
421
            osutils.normalized_filename = orig
422
423
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
424
class TestAddActions(TestCase):
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
425
1757.2.6 by Robert Collins
Steps towards a nicer smart add - unwind the conditional add logic - having parents not in the inventory was overly complicating the rest of the code.
426
    def test_quiet(self):
427
        self.run_action("")
428
429
    def test__print(self):
430
        self.run_action("added path\n")
431
432
    def run_action(self, output):
1757.2.3 by Robert Collins
Get add tests passing.
433
        from bzrlib.add import AddAction, FastPath
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
434
        inv = Inventory()
1092.1.30 by Robert Collins
change smart_add reporting of added files to callback with the entry, and change the inventory.add signature to return the added entry
435
        stdout = StringIO()
1757.2.6 by Robert Collins
Steps towards a nicer smart add - unwind the conditional add logic - having parents not in the inventory was overly complicating the rest of the code.
436
        action = AddAction(to_file=stdout, should_print=bool(output))
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
437
1757.2.3 by Robert Collins
Get add tests passing.
438
        self.apply_redirected(None, stdout, None, action, inv, None, FastPath('path'), 'file')
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
439
        self.assertEqual(stdout.getvalue(), output)