1# Copyright (C) 2010 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"""Weave-era branch implementations.""" 18 19from ... import ( 20 errors, 21 lockable_files, 22 ) 23 24from ...decorators import ( 25 only_raises, 26 ) 27from ...lock import LogicalLockResult 28from ...trace import mutter 29 30from ...branch import ( 31 BranchFormat, 32 BranchWriteLockResult, 33 ) 34from ...bzr.fullhistory import ( 35 FullHistoryBzrBranch, 36 ) 37 38 39class BzrBranch4(FullHistoryBzrBranch): 40 """Branch format 4.""" 41 42 def lock_write(self, token=None): 43 """Lock the branch for write operations. 44 45 :param token: A token to permit reacquiring a previously held and 46 preserved lock. 47 :return: A BranchWriteLockResult. 48 """ 49 if not self.is_locked(): 50 self._note_lock('w') 51 # All-in-one needs to always unlock/lock. 52 self.repository._warn_if_deprecated(self) 53 self.repository.lock_write() 54 try: 55 return BranchWriteLockResult(self.unlock, 56 self.control_files.lock_write(token=token)) 57 except: 58 self.repository.unlock() 59 raise 60 61 def lock_read(self): 62 """Lock the branch for read operations. 63 64 :return: A breezy.lock.LogicalLockResult. 65 """ 66 if not self.is_locked(): 67 self._note_lock('r') 68 # All-in-one needs to always unlock/lock. 69 self.repository._warn_if_deprecated(self) 70 self.repository.lock_read() 71 try: 72 self.control_files.lock_read() 73 return LogicalLockResult(self.unlock) 74 except: 75 self.repository.unlock() 76 raise 77 78 @only_raises(errors.LockNotHeld, errors.LockBroken) 79 def unlock(self): 80 if self.control_files._lock_count == 2 and self.conf_store is not None: 81 self.conf_store.save_changes() 82 try: 83 self.control_files.unlock() 84 finally: 85 # All-in-one needs to always unlock/lock. 86 self.repository.unlock() 87 if not self.control_files.is_locked(): 88 # we just released the lock 89 self._clear_cached_state() 90 91 def _get_checkout_format(self, lightweight=False): 92 """Return the most suitable metadir for a checkout of this branch. 93 """ 94 from .repository import RepositoryFormat7 95 from ...bzr.bzrdir import BzrDirMetaFormat1 96 format = BzrDirMetaFormat1() 97 if lightweight: 98 format.set_branch_format(self._format) 99 format.repository_format = self.controldir._format.repository_format 100 else: 101 format.repository_format = RepositoryFormat7() 102 return format 103 104 def unbind(self): 105 raise errors.UpgradeRequired(self.user_url) 106 107 def bind(self, other): 108 raise errors.UpgradeRequired(self.user_url) 109 110 def set_bound_location(self, location): 111 raise NotImplementedError(self.set_bound_location) 112 113 def get_bound_location(self): 114 return None 115 116 def update(self): 117 return None 118 119 def get_master_branch(self, possible_transports=None): 120 return None 121 122 123class BzrBranchFormat4(BranchFormat): 124 """Bzr branch format 4. 125 126 This format has: 127 - a revision-history file. 128 - a branch-lock lock file [ to be shared with the bzrdir ] 129 130 It does not support binding. 131 """ 132 133 def initialize(self, a_controldir, name=None, repository=None, 134 append_revisions_only=None): 135 """Create a branch of this format in a_controldir. 136 137 :param a_controldir: The bzrdir to initialize the branch in 138 :param name: Name of colocated branch to create, if any 139 :param repository: Repository for this branch (unused) 140 """ 141 if append_revisions_only: 142 raise errors.UpgradeRequired(a_controldir.user_url) 143 if repository is not None: 144 raise NotImplementedError( 145 "initialize(repository=<not None>) on %r" % (self,)) 146 if not [isinstance(a_controldir._format, format) for format in 147 self._compatible_bzrdirs]: 148 raise errors.IncompatibleFormat(self, a_controldir._format) 149 utf8_files = [('revision-history', b''), 150 ('branch-name', b''), 151 ] 152 mutter('creating branch %r in %s', self, a_controldir.user_url) 153 branch_transport = a_controldir.get_branch_transport(self, name=name) 154 control_files = lockable_files.LockableFiles(branch_transport, 155 'branch-lock', lockable_files.TransportLock) 156 control_files.create_lock() 157 try: 158 control_files.lock_write() 159 except errors.LockContention: 160 lock_taken = False 161 else: 162 lock_taken = True 163 try: 164 for (filename, content) in utf8_files: 165 branch_transport.put_bytes( 166 filename, content, 167 mode=a_controldir._get_file_mode()) 168 finally: 169 if lock_taken: 170 control_files.unlock() 171 branch = self.open(a_controldir, name, _found=True, 172 found_repository=None) 173 self._run_post_branch_init_hooks(a_controldir, name, branch) 174 return branch 175 176 def __init__(self): 177 super(BzrBranchFormat4, self).__init__() 178 from .bzrdir import ( 179 BzrDirFormat4, BzrDirFormat5, BzrDirFormat6, 180 ) 181 self._matchingcontroldir = BzrDirFormat6() 182 self._compatible_bzrdirs = [BzrDirFormat4, BzrDirFormat5, 183 BzrDirFormat6] 184 185 def network_name(self): 186 """The network name for this format is the control dirs disk label.""" 187 return self._matchingcontroldir.get_format_string() 188 189 def get_format_description(self): 190 return "Branch format 4" 191 192 def open(self, a_controldir, name=None, _found=False, ignore_fallbacks=False, 193 found_repository=None, possible_transports=None): 194 """See BranchFormat.open().""" 195 if name is None: 196 name = a_controldir._get_selected_branch() 197 if name != "": 198 raise errors.NoColocatedBranchSupport(self) 199 if not _found: 200 # we are being called directly and must probe. 201 raise NotImplementedError 202 if found_repository is None: 203 found_repository = a_controldir.open_repository() 204 return BzrBranch4(_format=self, 205 _control_files=a_controldir._control_files, 206 a_controldir=a_controldir, 207 name=name, 208 _repository=found_repository, 209 possible_transports=possible_transports) 210 211 def __str__(self): 212 return "Bazaar-NG branch format 4" 213 214 def supports_leaving_lock(self): 215 return False 216 217 supports_reference_locations = False 218