~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_add.py

  • Committer: wang
  • Date: 2006-10-29 13:41:32 UTC
  • mto: (2104.4.1 wang_65714)
  • mto: This revision was merged to the branch mainline in revision 2109.
  • Revision ID: wang@ubuntu-20061029134132-3d7f4216f20c4aef
Replace python's difflib by patiencediff because the worst case 
performance is cubic for difflib and people commiting large data 
files are often hurt by this. The worst case performance of patience is 
quadratic. Fix bug 65714.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
1
18
import os
2
19
import unittest
3
20
 
4
21
from bzrlib import errors, ignores, osutils
5
 
from bzrlib.add import smart_add, smart_add_tree
 
22
from bzrlib.add import (
 
23
    AddAction,
 
24
    AddFromBaseAction,
 
25
    smart_add,
 
26
    smart_add_tree,
 
27
    )
6
28
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
7
29
from bzrlib.errors import NoSuchFile
8
30
from bzrlib.inventory import InventoryFile, Inventory
99
121
    def test_add_dry_run(self):
100
122
        """Test a dry run add, make sure nothing is added."""
101
123
        from bzrlib.commands import run_bzr
102
 
        ignores._set_user_ignores(['./.bazaar'])
103
124
        eq = self.assertEqual
104
125
        wt = self.make_branch_and_tree('.')
105
126
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
118
139
        from bzrlib.commands import run_bzr
119
140
        wt = self.make_branch_and_tree('.')
120
141
        # The default ignore list includes '*.py[co]', but not CVS
121
 
        ignores._set_user_ignores(['./.bazaar', '*.py[co]'])
 
142
        ignores._set_user_ignores(['*.py[co]'])
122
143
        self.build_tree(['inertiatic/', 'inertiatic/esp', 'inertiatic/CVS',
123
144
                        'inertiatic/foo.pyc'])
124
145
        added, ignored = smart_add_tree(wt, u'.')
128
149
        self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
129
150
 
130
151
 
 
152
class AddCustomIDAction(AddAction):
 
153
 
 
154
    def __call__(self, inv, parent_ie, path, kind):
 
155
        # The first part just logs if appropriate
 
156
        # Now generate a custom id
 
157
        file_id = kind + '-' + path.raw_path.replace('/', '%')
 
158
        if self.should_print:
 
159
            self._to_file.write('added %s with id %s\n' 
 
160
                                % (path.raw_path, file_id))
 
161
        return file_id
 
162
 
 
163
 
131
164
class TestSmartAddTree(TestCaseWithTransport):
132
165
    """Test smart adds with a specified branch."""
133
166
 
211
244
            self.assertEqual(None, wt.path2id(path.rstrip('/')),
212
245
                    'Accidentally added path: %s' % (path,))
213
246
 
 
247
    def test_custom_ids(self):
 
248
        sio = StringIO()
 
249
        action = AddCustomIDAction(to_file=sio, should_print=True)
 
250
        self.build_tree(['file1', 'dir1/', 'dir1/file2'])
 
251
 
 
252
        wt = self.make_branch_and_tree('.')
 
253
        smart_add_tree(wt, ['.'], action=action)
 
254
        # The order of adds is not strictly fixed:
 
255
        sio.seek(0)
 
256
        lines = sorted(sio.readlines())
 
257
        self.assertEqualDiff(['added dir1 with id directory-dir1\n',
 
258
                              'added dir1/file2 with id file-dir1%file2\n',
 
259
                              'added file1 with id file-file1\n',
 
260
                             ], lines)
 
261
        self.assertEqual([('', wt.inventory.root.file_id),
 
262
                          ('dir1', 'directory-dir1'),
 
263
                          ('dir1/file2', 'file-dir1%file2'),
 
264
                          ('file1', 'file-file1'),
 
265
                         ], [(path, ie.file_id) for path, ie
 
266
                                in wt.inventory.iter_entries()])
 
267
 
 
268
 
 
269
class TestAddFrom(TestCaseWithTransport):
 
270
    """Tests for AddFromBaseAction"""
 
271
 
 
272
    def make_base_tree(self):
 
273
        self.base_tree = self.make_branch_and_tree('base')
 
274
        self.build_tree(['base/a', 'base/b',
 
275
                         'base/dir/', 'base/dir/a',
 
276
                         'base/dir/subdir/',
 
277
                         'base/dir/subdir/b',
 
278
                        ])
 
279
        self.base_tree.add(['a', 'b', 'dir', 'dir/a',
 
280
                            'dir/subdir', 'dir/subdir/b'])
 
281
        self.base_tree.commit('creating initial tree.')
 
282
 
 
283
    def add_helper(self, base_tree, base_path, new_tree, file_list,
 
284
                   should_print=False):
 
285
        to_file = StringIO()
 
286
        base_tree.lock_read()
 
287
        try:
 
288
            new_tree.lock_write()
 
289
            try:
 
290
                action = AddFromBaseAction(base_tree, base_path,
 
291
                                           to_file=to_file,
 
292
                                           should_print=should_print)
 
293
                smart_add_tree(new_tree, file_list, action=action)
 
294
            finally:
 
295
                new_tree.unlock()
 
296
        finally:
 
297
            base_tree.unlock()
 
298
        return to_file.getvalue()
 
299
 
 
300
    def test_copy_all(self):
 
301
        self.make_base_tree()
 
302
        new_tree = self.make_branch_and_tree('new')
 
303
        files = ['a', 'b',
 
304
                 'dir/', 'dir/a',
 
305
                 'dir/subdir/',
 
306
                 'dir/subdir/b',
 
307
                ]
 
308
        self.build_tree(['new/' + fn for fn in files])
 
309
        self.add_helper(self.base_tree, '', new_tree, ['new'])
 
310
 
 
311
        for fn in files:
 
312
            base_file_id = self.base_tree.path2id(fn)
 
313
            new_file_id = new_tree.path2id(fn)
 
314
            self.assertEqual(base_file_id, new_file_id)
 
315
 
 
316
    def test_copy_from_dir(self):
 
317
        self.make_base_tree()
 
318
        new_tree = self.make_branch_and_tree('new')
 
319
 
 
320
        self.build_tree(['new/a', 'new/b', 'new/c',
 
321
                         'new/subdir/', 'new/subdir/b', 'new/subdir/d'])
 
322
        new_tree.set_root_id(self.base_tree.get_root_id())
 
323
        self.add_helper(self.base_tree, 'dir', new_tree, ['new'])
 
324
 
 
325
        # We know 'a' and 'b' exist in the root, and they are being added
 
326
        # in a new 'root'. Since ROOT ids have been set as the same, we will
 
327
        # use those ids
 
328
        self.assertEqual(self.base_tree.path2id('a'),
 
329
                         new_tree.path2id('a'))
 
330
        self.assertEqual(self.base_tree.path2id('b'),
 
331
                         new_tree.path2id('b'))
 
332
 
 
333
        # Because we specified 'dir/' as the base path, and we have
 
334
        # nothing named 'subdir' in the base tree, we should grab the
 
335
        # ids from there
 
336
        self.assertEqual(self.base_tree.path2id('dir/subdir'),
 
337
                         new_tree.path2id('subdir'))
 
338
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
 
339
                         new_tree.path2id('subdir/b'))
 
340
 
 
341
        # These should get newly generated ids
 
342
        c_id = new_tree.path2id('c')
 
343
        self.assertNotEqual(None, c_id)
 
344
        self.failIf(c_id in self.base_tree)
 
345
 
 
346
        d_id = new_tree.path2id('subdir/d')
 
347
        self.assertNotEqual(None, d_id)
 
348
        self.failIf(d_id in self.base_tree)
 
349
 
 
350
    def test_copy_existing_dir(self):
 
351
        self.make_base_tree()
 
352
        new_tree = self.make_branch_and_tree('new')
 
353
        self.build_tree(['new/subby/', 'new/subby/a', 'new/subby/b'])
 
354
 
 
355
        subdir_file_id = self.base_tree.path2id('dir/subdir')
 
356
        new_tree.add(['subby'], [subdir_file_id])
 
357
        self.add_helper(self.base_tree, '', new_tree, ['new'])
 
358
        # Because 'subby' already points to subdir, we should add
 
359
        # 'b' with the same id
 
360
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
 
361
                         new_tree.path2id('subby/b'))
 
362
 
 
363
        # 'subby/a' should be added with a new id because there is no
 
364
        # matching path or child of 'subby'.
 
365
        a_id = new_tree.path2id('subby/a')
 
366
        self.assertNotEqual(None, a_id)
 
367
        self.failIf(a_id in self.base_tree)
 
368
 
214
369
 
215
370
class TestAddNonNormalized(TestCaseWithTransport):
216
371
 
280
435
 
281
436
    def run_action(self, output):
282
437
        from bzrlib.add import AddAction, FastPath
283
 
        from cStringIO import StringIO
284
438
        inv = Inventory()
285
439
        stdout = StringIO()
286
440
        action = AddAction(to_file=stdout, should_print=bool(output))