~bzr-pqm/bzr/bzr.dev

2568.2.4 by Robert Collins
* ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
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
2568.2.4 by Robert Collins
* ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now
19
from bzrlib import osutils
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
20
from bzrlib.add import (
21
    AddAction,
22
    AddFromBaseAction,
23
    )
2568.2.4 by Robert Collins
* ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now
24
from bzrlib.tests import TestCase, TestCaseWithTransport
25
from bzrlib.inventory import Inventory
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
26
27
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
28
class AddCustomIDAction(AddAction):
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
29
30
    def __call__(self, inv, parent_ie, path, kind):
31
        # The first part just logs if appropriate
32
        # Now generate a custom id
2309.4.9 by John Arbash Meinel
WorkingTree.merged_modified() needs to switch back to utf8 file ids.
33
        file_id = osutils.safe_file_id(kind + '-'
34
                                       + path.raw_path.replace('/', '%'),
35
                                       warn=False)
1911.3.1 by John Arbash Meinel
Updated smart_add so that the AddAction can return a custom id.
36
        if self.should_print:
2309.4.9 by John Arbash Meinel
WorkingTree.merged_modified() needs to switch back to utf8 file ids.
37
            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.
38
                                % (path.raw_path, file_id))
39
        return file_id
40
41
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
42
class TestAddFrom(TestCaseWithTransport):
43
    """Tests for AddFromBaseAction"""
44
45
    def make_base_tree(self):
46
        self.base_tree = self.make_branch_and_tree('base')
47
        self.build_tree(['base/a', 'base/b',
48
                         'base/dir/', 'base/dir/a',
49
                         'base/dir/subdir/',
50
                         'base/dir/subdir/b',
51
                        ])
52
        self.base_tree.add(['a', 'b', 'dir', 'dir/a',
53
                            'dir/subdir', 'dir/subdir/b'])
54
        self.base_tree.commit('creating initial tree.')
55
56
    def add_helper(self, base_tree, base_path, new_tree, file_list,
57
                   should_print=False):
58
        to_file = StringIO()
59
        base_tree.lock_read()
60
        try:
61
            new_tree.lock_write()
62
            try:
63
                action = AddFromBaseAction(base_tree, base_path,
64
                                           to_file=to_file,
65
                                           should_print=should_print)
2568.2.4 by Robert Collins
* ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now
66
                new_tree.smart_add(file_list, action=action)
1911.3.2 by John Arbash Meinel
Adding the AddFromBaseAction, which tries to reuse file ids from another tree
67
            finally:
68
                new_tree.unlock()
69
        finally:
70
            base_tree.unlock()
71
        return to_file.getvalue()
72
73
    def test_copy_all(self):
74
        self.make_base_tree()
75
        new_tree = self.make_branch_and_tree('new')
76
        files = ['a', 'b',
77
                 'dir/', 'dir/a',
78
                 'dir/subdir/',
79
                 'dir/subdir/b',
80
                ]
81
        self.build_tree(['new/' + fn for fn in files])
82
        self.add_helper(self.base_tree, '', new_tree, ['new'])
83
84
        for fn in files:
85
            base_file_id = self.base_tree.path2id(fn)
86
            new_file_id = new_tree.path2id(fn)
87
            self.assertEqual(base_file_id, new_file_id)
88
89
    def test_copy_from_dir(self):
90
        self.make_base_tree()
91
        new_tree = self.make_branch_and_tree('new')
92
93
        self.build_tree(['new/a', 'new/b', 'new/c',
94
                         'new/subdir/', 'new/subdir/b', 'new/subdir/d'])
1731.1.46 by Aaron Bentley
merge from bzr.dev
95
        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
96
        self.add_helper(self.base_tree, 'dir', new_tree, ['new'])
97
1731.1.46 by Aaron Bentley
merge from bzr.dev
98
        # We know 'a' and 'b' exist in the root, and they are being added
99
        # 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
100
        # use those ids
101
        self.assertEqual(self.base_tree.path2id('a'),
102
                         new_tree.path2id('a'))
103
        self.assertEqual(self.base_tree.path2id('b'),
104
                         new_tree.path2id('b'))
105
106
        # Because we specified 'dir/' as the base path, and we have
107
        # nothing named 'subdir' in the base tree, we should grab the
108
        # ids from there
109
        self.assertEqual(self.base_tree.path2id('dir/subdir'),
110
                         new_tree.path2id('subdir'))
111
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
112
                         new_tree.path2id('subdir/b'))
113
114
        # These should get newly generated ids
115
        c_id = new_tree.path2id('c')
116
        self.assertNotEqual(None, c_id)
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
117
        self.base_tree.lock_read()
118
        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
119
        self.failIf(c_id in self.base_tree)
120
121
        d_id = new_tree.path2id('subdir/d')
122
        self.assertNotEqual(None, d_id)
123
        self.failIf(d_id in self.base_tree)
124
125
    def test_copy_existing_dir(self):
126
        self.make_base_tree()
127
        new_tree = self.make_branch_and_tree('new')
128
        self.build_tree(['new/subby/', 'new/subby/a', 'new/subby/b'])
129
130
        subdir_file_id = self.base_tree.path2id('dir/subdir')
131
        new_tree.add(['subby'], [subdir_file_id])
132
        self.add_helper(self.base_tree, '', new_tree, ['new'])
133
        # Because 'subby' already points to subdir, we should add
134
        # 'b' with the same id
135
        self.assertEqual(self.base_tree.path2id('dir/subdir/b'),
136
                         new_tree.path2id('subby/b'))
137
138
        # 'subby/a' should be added with a new id because there is no
139
        # matching path or child of 'subby'.
140
        a_id = new_tree.path2id('subby/a')
141
        self.assertNotEqual(None, a_id)
2255.7.57 by Robert Collins
Fix test_smart_add tests for dirstate - mainly inventory outside locks issues.
142
        self.base_tree.lock_read()
143
        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
144
        self.failIf(a_id in self.base_tree)
145
146
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
147
class TestAddActions(TestCase):
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
148
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.
149
    def test_quiet(self):
150
        self.run_action("")
151
152
    def test__print(self):
153
        self.run_action("added path\n")
154
155
    def run_action(self, output):
2568.2.4 by Robert Collins
* ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now
156
        from bzrlib.add import AddAction
2568.2.5 by Robert Collins
* ``bzrlib.add.FastPath`` is now private and moved to
157
        from bzrlib.mutabletree import _FastPath
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
158
        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
159
        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.
160
        action = AddAction(to_file=stdout, should_print=bool(output))
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
161
2568.2.5 by Robert Collins
* ``bzrlib.add.FastPath`` is now private and moved to
162
        self.apply_redirected(None, stdout, None, action, inv, None,
163
            _FastPath('path'), 'file')
1185.53.2 by Michael Ellerman
Add tests for bzr add --dry-run
164
        self.assertEqual(stdout.getvalue(), output)