1# Copyright (C) 2006, 2007, 2009-2012, 2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 17"""Tests for the 'checkout' CLI command.""" 18 19import os 20 21from breezy import ( 22 branch as _mod_branch, 23 controldir, 24 errors, 25 workingtree, 26 ) 27from breezy.bzr import ( 28 bzrdir, 29 ) 30from breezy.tests import ( 31 TestCaseWithTransport, 32 ) 33from breezy.tests.features import ( 34 HardlinkFeature, 35 ) 36 37 38class TestCheckout(TestCaseWithTransport): 39 40 def setUp(self): 41 super(TestCheckout, self).setUp() 42 tree = controldir.ControlDir.create_standalone_workingtree('branch') 43 tree.commit('1', rev_id=b'1', allow_pointless=True) 44 self.build_tree(['branch/added_in_2']) 45 tree.add('added_in_2') 46 tree.commit('2', rev_id=b'2') 47 48 def test_checkout_makes_bound_branch(self): 49 self.run_bzr('checkout branch checkout') 50 # if we have a checkout, the branch base should be 'branch' 51 source = controldir.ControlDir.open('branch') 52 result = controldir.ControlDir.open('checkout') 53 self.assertEqual(source.open_branch().controldir.root_transport.base, 54 result.open_branch().get_bound_location()) 55 56 def test_checkout_light_makes_checkout(self): 57 self.run_bzr('checkout --lightweight branch checkout') 58 # if we have a checkout, the branch base should be 'branch' 59 source = controldir.ControlDir.open('branch') 60 result = controldir.ControlDir.open('checkout') 61 self.assertEqual(source.open_branch().controldir.root_transport.base, 62 result.open_branch().controldir.root_transport.base) 63 64 def test_checkout_dash_r(self): 65 out, err = self.run_bzr(['checkout', '-r', '-2', 'branch', 'checkout']) 66 # the working tree should now be at revision '1' with the content 67 # from 1. 68 result = controldir.ControlDir.open('checkout') 69 self.assertEqual([b'1'], result.open_workingtree().get_parent_ids()) 70 self.assertPathDoesNotExist('checkout/added_in_2') 71 72 def test_checkout_light_dash_r(self): 73 out, err = self.run_bzr(['checkout', '--lightweight', '-r', '-2', 74 'branch', 'checkout']) 75 # the working tree should now be at revision '1' with the content 76 # from 1. 77 result = controldir.ControlDir.open('checkout') 78 self.assertEqual([b'1'], result.open_workingtree().get_parent_ids()) 79 self.assertPathDoesNotExist('checkout/added_in_2') 80 81 def test_checkout_into_empty_dir(self): 82 self.make_controldir('checkout') 83 out, err = self.run_bzr(['checkout', 'branch', 'checkout']) 84 result = controldir.ControlDir.open('checkout') 85 tree = result.open_workingtree() 86 branch = result.open_branch() 87 88 def test_checkout_reconstitutes_working_trees(self): 89 # doing a 'brz checkout' in the directory of a branch with no tree 90 # or a 'brz checkout path' with path the name of a directory with 91 # a branch with no tree will reconsistute the tree. 92 os.mkdir('treeless-branch') 93 branch = controldir.ControlDir.create_branch_convenience( 94 'treeless-branch', 95 force_new_tree=False, 96 format=bzrdir.BzrDirMetaFormat1()) 97 # check no tree was created 98 self.assertRaises(errors.NoWorkingTree, 99 branch.controldir.open_workingtree) 100 out, err = self.run_bzr('checkout treeless-branch') 101 # we should have a tree now 102 branch.controldir.open_workingtree() 103 # with no diff 104 out, err = self.run_bzr('diff treeless-branch') 105 106 # now test with no parameters 107 branch = controldir.ControlDir.create_branch_convenience( 108 '.', 109 force_new_tree=False, 110 format=bzrdir.BzrDirMetaFormat1()) 111 # check no tree was created 112 self.assertRaises(errors.NoWorkingTree, 113 branch.controldir.open_workingtree) 114 out, err = self.run_bzr('checkout') 115 # we should have a tree now 116 branch.controldir.open_workingtree() 117 # with no diff 118 out, err = self.run_bzr('diff') 119 120 def _test_checkout_existing_dir(self, lightweight): 121 source = self.make_branch_and_tree('source') 122 self.build_tree_contents([('source/file1', b'content1'), 123 ('source/file2', b'content2'), ]) 124 source.add(['file1', 'file2']) 125 source.commit('added files') 126 self.build_tree_contents([('target/', b''), 127 ('target/file1', b'content1'), 128 ('target/file2', b'content3'), ]) 129 cmd = ['checkout', 'source', 'target'] 130 if lightweight: 131 cmd.append('--lightweight') 132 self.run_bzr('checkout source target') 133 # files with unique content should be moved 134 self.assertPathExists('target/file2.moved') 135 # files with content matching tree should not be moved 136 self.assertPathDoesNotExist('target/file1.moved') 137 138 def test_checkout_existing_dir_heavy(self): 139 self._test_checkout_existing_dir(False) 140 141 def test_checkout_existing_dir_lightweight(self): 142 self._test_checkout_existing_dir(True) 143 144 def test_checkout_in_branch_with_r(self): 145 branch = _mod_branch.Branch.open('branch') 146 branch.controldir.destroy_workingtree() 147 self.run_bzr('checkout -r 1', working_dir='branch') 148 tree = workingtree.WorkingTree.open('branch') 149 self.assertEqual(b'1', tree.last_revision()) 150 branch.controldir.destroy_workingtree() 151 self.run_bzr('checkout -r 0', working_dir='branch') 152 self.assertEqual(b'null:', tree.last_revision()) 153 154 def test_checkout_files_from(self): 155 branch = _mod_branch.Branch.open('branch') 156 self.run_bzr(['checkout', 'branch', 'branch2', '--files-from', 157 'branch']) 158 159 def test_checkout_hardlink(self): 160 self.requireFeature(HardlinkFeature) 161 source = self.make_branch_and_tree('source') 162 self.build_tree(['source/file1']) 163 source.add('file1') 164 source.commit('added file') 165 out, err = self.run_bzr('checkout source target --hardlink') 166 source_stat = os.stat('source/file1') 167 target_stat = os.stat('target/file1') 168 self.assertEqual(source_stat, target_stat) 169 170 def test_checkout_hardlink_files_from(self): 171 self.requireFeature(HardlinkFeature) 172 source = self.make_branch_and_tree('source') 173 self.build_tree(['source/file1']) 174 source.add('file1') 175 source.commit('added file') 176 source.controldir.sprout('second') 177 out, err = self.run_bzr('checkout source target --hardlink' 178 ' --files-from second') 179 second_stat = os.stat('second/file1') 180 target_stat = os.stat('target/file1') 181 self.assertEqual(second_stat, target_stat) 182 183 def test_colo_checkout(self): 184 source = self.make_branch_and_tree('source', format='development-colo') 185 self.build_tree(['source/file1']) 186 source.add('file1') 187 source.commit('added file') 188 target = source.controldir.sprout('file:second,branch=somebranch', 189 create_tree_if_local=False) 190 out, err = self.run_bzr('checkout file:,branch=somebranch .', 191 working_dir='second') 192 # We should always be creating a lighweight checkout for colocated 193 # branches. 194 self.assertEqual( 195 target.open_branch(name='somebranch').user_url, 196 target.get_branch_reference(name="")) 197