1
# Copyright (C) 2005 by Canonical Ltd
2
# -*- coding: utf-8 -*-
1
# Copyright (C) 2006, 2007, 2009-2012 Canonical Ltd
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
6
5
# the Free Software Foundation; either version 2 of the License, or
7
6
# (at your option) any later version.
9
8
# This program is distributed in the hope that it will be useful,
10
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
11
# GNU General Public License for more details.
14
13
# You should have received a copy of the GNU General Public License
15
14
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
17
"""Tests for the 'checkout' CLI command."""
20
from cStringIO import StringIO
26
import bzrlib.bzrdir as bzrdir
27
import bzrlib.errors as errors
28
from bzrlib.tests.blackbox import ExternalBase
31
class TestCheckout(ExternalBase):
22
branch as _mod_branch,
28
from bzrlib.tests import (
29
TestCaseWithTransport,
31
from bzrlib.tests.matchers import ContainsNoVfsCalls
32
from bzrlib.tests.features import (
37
class TestCheckout(TestCaseWithTransport):
34
40
super(TestCheckout, self).setUp()
35
tree = bzrdir.BzrDir.create_standalone_workingtree('branch')
41
tree = controldir.ControlDir.create_standalone_workingtree('branch')
36
42
tree.commit('1', rev_id='1', allow_pointless=True)
37
43
self.build_tree(['branch/added_in_2'])
38
44
tree.add('added_in_2')
39
45
tree.commit('2', rev_id='2')
41
47
def test_checkout_makes_bound_branch(self):
42
self.runbzr('checkout branch checkout')
48
self.run_bzr('checkout branch checkout')
43
49
# if we have a checkout, the branch base should be 'branch'
44
source = bzrdir.BzrDir.open('branch')
45
result = bzrdir.BzrDir.open('checkout')
50
source = controldir.ControlDir.open('branch')
51
result = controldir.ControlDir.open('checkout')
46
52
self.assertEqual(source.open_branch().bzrdir.root_transport.base,
47
53
result.open_branch().get_bound_location())
49
55
def test_checkout_light_makes_checkout(self):
50
self.runbzr('checkout --lightweight branch checkout')
56
self.run_bzr('checkout --lightweight branch checkout')
51
57
# if we have a checkout, the branch base should be 'branch'
52
source = bzrdir.BzrDir.open('branch')
53
result = bzrdir.BzrDir.open('checkout')
58
source = controldir.ControlDir.open('branch')
59
result = controldir.ControlDir.open('checkout')
54
60
self.assertEqual(source.open_branch().bzrdir.root_transport.base,
55
61
result.open_branch().bzrdir.root_transport.base)
57
63
def test_checkout_dash_r(self):
58
self.runbzr('checkout -r -2 branch checkout')
64
out, err = self.run_bzr(['checkout', '-r', '-2', 'branch', 'checkout'])
59
65
# the working tree should now be at revision '1' with the content
61
result = bzrdir.BzrDir.open('checkout')
62
self.assertEqual('1', result.open_workingtree().last_revision())
63
self.failIfExists('checkout/added_in_2')
67
result = controldir.ControlDir.open('checkout')
68
self.assertEqual(['1'], result.open_workingtree().get_parent_ids())
69
self.assertPathDoesNotExist('checkout/added_in_2')
65
71
def test_checkout_light_dash_r(self):
66
self.runbzr('checkout --lightweight -r -2 branch checkout')
72
out, err = self.run_bzr(['checkout','--lightweight', '-r', '-2',
73
'branch', 'checkout'])
67
74
# the working tree should now be at revision '1' with the content
69
result = bzrdir.BzrDir.open('checkout')
70
self.assertEqual('1', result.open_workingtree().last_revision())
71
self.failIfExists('checkout/added_in_2')
76
result = controldir.ControlDir.open('checkout')
77
self.assertEqual(['1'], result.open_workingtree().get_parent_ids())
78
self.assertPathDoesNotExist('checkout/added_in_2')
80
def test_checkout_into_empty_dir(self):
81
self.make_bzrdir('checkout')
82
out, err = self.run_bzr(['checkout', 'branch', 'checkout'])
83
result = controldir.ControlDir.open('checkout')
84
tree = result.open_workingtree()
85
branch = result.open_branch()
73
87
def test_checkout_reconstitutes_working_trees(self):
74
88
# doing a 'bzr checkout' in the directory of a branch with no tree
75
89
# or a 'bzr checkout path' with path the name of a directory with
76
90
# a branch with no tree will reconsistute the tree.
77
91
os.mkdir('treeless-branch')
78
branch = bzrdir.BzrDir.create_branch_convenience(
92
branch = controldir.ControlDir.create_branch_convenience(
80
94
force_new_tree=False,
81
95
format=bzrdir.BzrDirMetaFormat1())
82
96
# check no tree was created
83
97
self.assertRaises(errors.NoWorkingTree, branch.bzrdir.open_workingtree)
84
out, err = self.run_bzr('checkout', 'treeless-branch')
98
out, err = self.run_bzr('checkout treeless-branch')
85
99
# we should have a tree now
86
100
branch.bzrdir.open_workingtree()
88
out, err = self.run_bzr('diff', 'treeless-branch')
102
out, err = self.run_bzr('diff treeless-branch')
90
104
# now test with no parameters
91
branch = bzrdir.BzrDir.create_branch_convenience(
105
branch = controldir.ControlDir.create_branch_convenience(
93
107
force_new_tree=False,
94
108
format=bzrdir.BzrDirMetaFormat1())
99
113
branch.bzrdir.open_workingtree()
101
115
out, err = self.run_bzr('diff')
117
def _test_checkout_existing_dir(self, lightweight):
118
source = self.make_branch_and_tree('source')
119
self.build_tree_contents([('source/file1', 'content1'),
120
('source/file2', 'content2'),])
121
source.add(['file1', 'file2'])
122
source.commit('added files')
123
self.build_tree_contents([('target/', ''),
124
('target/file1', 'content1'),
125
('target/file2', 'content3'),])
126
cmd = ['checkout', 'source', 'target']
128
cmd.append('--lightweight')
129
self.run_bzr('checkout source target')
130
# files with unique content should be moved
131
self.assertPathExists('target/file2.moved')
132
# files with content matching tree should not be moved
133
self.assertPathDoesNotExist('target/file1.moved')
135
def test_checkout_existing_dir_heavy(self):
136
self._test_checkout_existing_dir(False)
138
def test_checkout_existing_dir_lightweight(self):
139
self._test_checkout_existing_dir(True)
141
def test_checkout_in_branch_with_r(self):
142
branch = _mod_branch.Branch.open('branch')
143
branch.bzrdir.destroy_workingtree()
144
self.run_bzr('checkout -r 1', working_dir='branch')
145
tree = workingtree.WorkingTree.open('branch')
146
self.assertEqual('1', tree.last_revision())
147
branch.bzrdir.destroy_workingtree()
148
self.run_bzr('checkout -r 0', working_dir='branch')
149
self.assertEqual('null:', tree.last_revision())
151
def test_checkout_files_from(self):
152
branch = _mod_branch.Branch.open('branch')
153
self.run_bzr(['checkout', 'branch', 'branch2', '--files-from',
156
def test_checkout_hardlink(self):
157
self.requireFeature(HardlinkFeature)
158
source = self.make_branch_and_tree('source')
159
self.build_tree(['source/file1'])
161
source.commit('added file')
162
out, err = self.run_bzr('checkout source target --hardlink')
163
source_stat = os.stat('source/file1')
164
target_stat = os.stat('target/file1')
165
self.assertEqual(source_stat, target_stat)
167
def test_checkout_hardlink_files_from(self):
168
self.requireFeature(HardlinkFeature)
169
source = self.make_branch_and_tree('source')
170
self.build_tree(['source/file1'])
172
source.commit('added file')
173
source.bzrdir.sprout('second')
174
out, err = self.run_bzr('checkout source target --hardlink'
175
' --files-from second')
176
second_stat = os.stat('second/file1')
177
target_stat = os.stat('target/file1')
178
self.assertEqual(second_stat, target_stat)
180
def test_colo_checkout(self):
181
source = self.make_branch_and_tree('source', format='development-colo')
182
self.build_tree(['source/file1'])
184
source.commit('added file')
185
target = source.bzrdir.sprout('file:second,branch=somebranch',
186
create_tree_if_local=False)
187
out, err = self.run_bzr('checkout file:,branch=somebranch .',
188
working_dir='second')
189
# We should always be creating a lighweight checkout for colocated
192
target.open_branch(name='somebranch').base,
193
target.get_branch_reference(name=""))
196
class TestSmartServerCheckout(TestCaseWithTransport):
198
def test_heavyweight_checkout(self):
199
self.setup_smart_server_with_call_log()
200
t = self.make_branch_and_tree('from')
201
for count in range(9):
202
t.commit(message='commit %d' % count)
203
self.reset_smart_call_log()
204
out, err = self.run_bzr(['checkout', self.get_url('from'), 'target'])
205
# This figure represent the amount of work to perform this use case. It
206
# is entirely ok to reduce this number if a test fails due to rpc_count
207
# being too low. If rpc_count increases, more network roundtrips have
208
# become necessary for this use case. Please do not adjust this number
209
# upwards without agreement from bzr's network support maintainers.
210
self.assertLength(10, self.hpss_calls)
211
self.assertLength(1, self.hpss_connections)
212
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
214
def test_lightweight_checkout(self):
215
self.setup_smart_server_with_call_log()
216
t = self.make_branch_and_tree('from')
217
for count in range(9):
218
t.commit(message='commit %d' % count)
219
self.reset_smart_call_log()
220
out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
222
# This figure represent the amount of work to perform this use case. It
223
# is entirely ok to reduce this number if a test fails due to rpc_count
224
# being too low. If rpc_count increases, more network roundtrips have
225
# become necessary for this use case. Please do not adjust this number
226
# upwards without agreement from bzr's network support maintainers.
227
self.assertLength(13, self.hpss_calls)
228
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)