~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2007-2011 Canonical Ltd
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
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
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
16
17
"""Tests for bzrlib.switch."""
18
19
20
import os
21
5162.3.1 by Aaron Bentley
Fix switch/merge when a ConfigurableFileMerger is used.
22
from bzrlib import (
23
    branch,
24
    errors,
6538.1.20 by Aaron Bentley
Cleanup
25
    lock,
5162.3.1 by Aaron Bentley
Fix switch/merge when a ConfigurableFileMerger is used.
26
    merge as _mod_merge,
27
    switch,
28
    tests,
6538.1.15 by Aaron Bentley
Switch.switch stores and restores changes.
29
    workingtree,
5579.3.1 by Jelmer Vernooij
Remove unused imports.
30
    )
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
31
32
33
class TestSwitch(tests.TestCaseWithTransport):
34
3078.2.2 by Ian Clatworthy
get switch tests passing on heavyweight checkouts
35
    def setUp(self):
36
        super(TestSwitch, self).setUp()
37
        self.lightweight = True
38
6538.1.15 by Aaron Bentley
Switch.switch stores and restores changes.
39
    @staticmethod
40
    def _master_if_present(branch):
41
        master = branch.get_master_branch()
42
        if master:
43
            return master
44
        else:
45
            return branch
46
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
47
    def _setup_tree(self):
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
48
        tree = self.make_branch_and_tree('branch-1')
49
        self.build_tree(['branch-1/file-1'])
50
        tree.add('file-1')
51
        tree.commit('rev1')
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
52
        return tree
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
53
6538.1.16 by Aaron Bentley
Restore uncommitted changes even if revisions are same.
54
    def _setup_uncommitted(self, same_revision=False):
6538.1.15 by Aaron Bentley
Switch.switch stores and restores changes.
55
        tree = self._setup_tree()
56
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
57
        self.build_tree(['branch-1/file-2'])
6538.1.16 by Aaron Bentley
Restore uncommitted changes even if revisions are same.
58
        if not same_revision:
59
            tree.add('file-2')
60
            tree.remove('file-1')
61
            tree.commit('rev2')
6538.1.15 by Aaron Bentley
Switch.switch stores and restores changes.
62
        checkout = tree.branch.create_checkout('checkout',
63
            lightweight=self.lightweight)
64
        self.build_tree(['checkout/file-3'])
65
        checkout.add('file-3')
66
        return checkout, to_branch
67
68
    def test_switch_store_uncommitted(self):
69
        """Test switch updates tree and stores uncommitted changes."""
70
        checkout, to_branch = self._setup_uncommitted()
71
        self.assertPathDoesNotExist('checkout/file-1')
72
        self.assertPathExists('checkout/file-2')
73
        switch.switch(checkout.bzrdir, to_branch, store_uncommitted=True)
74
        self.assertPathExists('checkout/file-1')
75
        self.assertPathDoesNotExist('checkout/file-2')
76
        self.assertPathDoesNotExist('checkout/file-3')
77
78
    def test_switch_restore_uncommitted(self):
79
        """Test switch updates tree and restores uncommitted changes."""
80
        checkout, to_branch = self._setup_uncommitted()
81
        old_branch = self._master_if_present(checkout.branch)
82
        self.assertPathDoesNotExist('checkout/file-1')
83
        self.assertPathExists('checkout/file-2')
84
        self.assertPathExists('checkout/file-3')
85
        switch.switch(checkout.bzrdir, to_branch, store_uncommitted=True)
86
        checkout = workingtree.WorkingTree.open('checkout')
87
        switch.switch(checkout.bzrdir, old_branch, store_uncommitted=True)
88
        self.assertPathDoesNotExist('checkout/file-1')
89
        self.assertPathExists('checkout/file-2')
90
        self.assertPathExists('checkout/file-3')
91
6538.1.16 by Aaron Bentley
Restore uncommitted changes even if revisions are same.
92
    def test_switch_restore_uncommitted_same_revision(self):
93
        """Test switch updates tree and restores uncommitted changes."""
94
        checkout, to_branch = self._setup_uncommitted(same_revision=True)
95
        old_branch = self._master_if_present(checkout.branch)
96
        switch.switch(checkout.bzrdir, to_branch, store_uncommitted=True)
97
        checkout = workingtree.WorkingTree.open('checkout')
98
        switch.switch(checkout.bzrdir, old_branch, store_uncommitted=True)
99
        self.assertPathExists('checkout/file-3')
100
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
101
    def test_switch_updates(self):
102
        """Test switch updates tree and keeps uncommitted changes."""
6538.1.15 by Aaron Bentley
Switch.switch stores and restores changes.
103
        checkout, to_branch = self._setup_uncommitted()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
104
        self.assertPathDoesNotExist('checkout/file-1')
105
        self.assertPathExists('checkout/file-2')
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
106
        switch.switch(checkout.bzrdir, to_branch)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
107
        self.assertPathExists('checkout/file-1')
108
        self.assertPathDoesNotExist('checkout/file-2')
109
        self.assertPathExists('checkout/file-3')
2999.1.1 by Ian Clatworthy
migrate switch command into the core - was in BzrTools
110
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
111
    def test_switch_after_branch_moved(self):
112
        """Test switch after the branch is moved."""
113
        tree = self._setup_tree()
3078.2.2 by Ian Clatworthy
get switch tests passing on heavyweight checkouts
114
        checkout = tree.branch.create_checkout('checkout',
115
            lightweight=self.lightweight)
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
116
        self.build_tree(['branch-1/file-2'])
117
        tree.add('file-2')
118
        tree.remove('file-1')
119
        tree.commit('rev2')
3044.1.4 by Martin Pool
Set default format to pack-0.92
120
        self.build_tree(['checkout/file-3'])
121
        checkout.add('file-3')
122
        checkout_dir = checkout.bzrdir
123
        # rename the branch on disk, the checkout object is now invalid.
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
124
        os.rename('branch-1', 'branch-2')
125
        to_branch = branch.Branch.open('branch-2')
3078.2.5 by Ian Clatworthy
make switch fail without --force if branch missing
126
        # Check fails without --force
4340.1.1 by Jelmer Vernooij
Mention --force when bzr switch fails to open the current master branch.
127
        err = self.assertRaises(
128
            (errors.BzrCommandError, errors.NotBranchError),
3078.2.5 by Ian Clatworthy
make switch fail without --force if branch missing
129
            switch.switch, checkout.bzrdir, to_branch)
4340.1.1 by Jelmer Vernooij
Mention --force when bzr switch fails to open the current master branch.
130
        if isinstance(err, errors.BzrCommandError):
131
            self.assertContainsRe(str(err),
132
                'Unable to connect to current master branch .*'
133
                'To switch anyway, use --force.')
3078.2.5 by Ian Clatworthy
make switch fail without --force if branch missing
134
        switch.switch(checkout.bzrdir, to_branch, force=True)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
135
        self.assertPathDoesNotExist('checkout/file-1')
136
        self.assertPathExists('checkout/file-2')
137
        self.assertPathExists('checkout/file-3')
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
138
139
    def test_switch_when_pending_merges(self):
140
        """Test graceful failure if pending merges are outstanding."""
141
        # Create 2 branches and a checkout
142
        tree = self._setup_tree()
143
        tree2 = tree.bzrdir.sprout('branch-2').open_workingtree()
3078.2.2 by Ian Clatworthy
get switch tests passing on heavyweight checkouts
144
        checkout = tree.branch.create_checkout('checkout',
145
            lightweight=self.lightweight)
2999.1.3 by Ian Clatworthy
fix pending merge detection and test
146
        # Change tree2 and merge it into the checkout without committing
147
        self.build_tree(['branch-2/file-2'])
148
        tree2.add('file-2')
149
        tree2.commit('rev2')
150
        checkout.merge_from_branch(tree2.branch)
151
        # Check the error reporting is as expected
152
        err = self.assertRaises(errors.BzrCommandError,
153
            switch.switch, checkout.bzrdir, tree2.branch)
154
        self.assertContainsRe(str(err),
155
            "Pending merges must be committed or reverted before using switch")
3078.2.2 by Ian Clatworthy
get switch tests passing on heavyweight checkouts
156
3984.5.1 by Daniel Watkins
Added whitebox test.
157
    def test_switch_with_revision(self):
158
        """Test switch when a revision is given."""
159
        # Create a tree with 2 revisions
3984.5.3 by Daniel Watkins
Updated testcase.
160
        tree = self.make_branch_and_tree('branch-1')
161
        self.build_tree(['branch-1/file-1'])
162
        tree.add('file-1')
163
        tree.commit(rev_id='rev1', message='rev1')
3984.5.1 by Daniel Watkins
Added whitebox test.
164
        self.build_tree(['branch-1/file-2'])
165
        tree.add('file-2')
3984.5.3 by Daniel Watkins
Updated testcase.
166
        tree.commit(rev_id='rev2', message='rev2')
3984.5.1 by Daniel Watkins
Added whitebox test.
167
        # Check it out and switch to revision 1
168
        checkout = tree.branch.create_checkout('checkout',
3984.5.21 by Andrew Bennetts
Merge lp:bzr.
169
            lightweight=self.lightweight)
3984.5.12 by Daniel Watkins
Convert test back to taking a revision_id.
170
        switch.switch(checkout.bzrdir, tree.branch, revision_id="rev1")
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
171
        self.assertPathExists('checkout/file-1')
172
        self.assertPathDoesNotExist('checkout/file-2')
3984.5.1 by Daniel Watkins
Added whitebox test.
173
4634.123.7 by John Arbash Meinel
Add direct tests that 'bzr switch' can handle root-id changes.
174
    def test_switch_changing_root_id(self):
175
        tree = self._setup_tree()
176
        tree2 = self.make_branch_and_tree('tree-2')
177
        tree2.set_root_id('custom-root-id')
178
        self.build_tree(['tree-2/file-2'])
179
        tree2.add(['file-2'])
180
        tree2.commit('rev1b')
181
        checkout = tree.branch.create_checkout('checkout',
182
            lightweight=self.lightweight)
183
        switch.switch(checkout.bzrdir, tree2.branch)
184
        self.assertEqual('custom-root-id', tree2.get_root_id())
185
5162.3.1 by Aaron Bentley
Fix switch/merge when a ConfigurableFileMerger is used.
186
    def test_switch_configurable_file_merger(self):
187
        class DummyMerger(_mod_merge.ConfigurableFileMerger):
188
            name_prefix = 'file'
189
190
        _mod_merge.Merger.hooks.install_named_hook(
191
            'merge_file_content', DummyMerger,
192
            'test factory')
193
        foo = self.make_branch('foo')
194
        checkout = foo.create_checkout('checkout', lightweight=True)
195
        self.build_tree_contents([('checkout/file', 'a')])
196
        checkout.add('file')
197
        checkout.commit('a')
198
        bar = foo.bzrdir.sprout('bar').open_workingtree()
199
        self.build_tree_contents([('bar/file', 'b')])
200
        bar.commit('b')
201
        self.build_tree_contents([('checkout/file', 'c')])
202
        switch.switch(checkout.bzrdir, bar.branch)
203
3078.2.2 by Ian Clatworthy
get switch tests passing on heavyweight checkouts
204
205
class TestSwitchHeavyweight(TestSwitch):
206
207
    def setUp(self):
208
        super(TestSwitchHeavyweight, self).setUp()
209
        self.lightweight = False
3078.2.4 by Ian Clatworthy
Add test for local commits handling
210
211
    def test_switch_with_local_commits(self):
212
        """Test switch complains about local commits unless --force given."""
213
        tree = self._setup_tree()
214
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
215
        self.build_tree(['branch-1/file-2'])
216
        tree.add('file-2')
217
        tree.remove('file-1')
218
        tree.commit('rev2')
219
        checkout = tree.branch.create_checkout('checkout')
220
        self.build_tree(['checkout/file-3'])
221
        checkout.add('file-3')
222
        checkout.commit(message='local only commit', local=True)
223
        self.build_tree(['checkout/file-4'])
224
        # Check the error reporting is as expected
225
        err = self.assertRaises(errors.BzrCommandError,
226
            switch.switch, checkout.bzrdir, to_branch)
227
        self.assertContainsRe(str(err),
228
            'Cannot switch as local commits found in the checkout.')
229
        # Check all is ok when force is given
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
230
        self.assertPathDoesNotExist('checkout/file-1')
231
        self.assertPathExists('checkout/file-2')
3078.2.4 by Ian Clatworthy
Add test for local commits handling
232
        switch.switch(checkout.bzrdir, to_branch, force=True)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
233
        self.assertPathExists('checkout/file-1')
234
        self.assertPathDoesNotExist('checkout/file-2')
235
        self.assertPathDoesNotExist('checkout/file-3')
236
        self.assertPathExists('checkout/file-4')
3078.2.4 by Ian Clatworthy
Add test for local commits handling
237
        # Check that the checkout is a true mirror of the bound branch
3445.2.1 by John Arbash Meinel
Add tests for Branch.missing_revisions and deprecate it.
238
        self.assertEqual(to_branch.last_revision_info(),
239
                         checkout.branch.last_revision_info())