~bzr-pqm/bzr/bzr.dev

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