bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 1553.5.28
by Martin Pool [merge] from bzr.dev before integration | 1 | # Copyright (C) 2005, 2006 Canonical Ltd
 | 
| 1185.65.22
by Robert Collins lockable_files was extracted from branch.py - give it a copyright statement | 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 16 | ||
| 1185.65.29
by Robert Collins Implement final review suggestions. | 17 | from cStringIO import StringIO | 
| 18 | import codecs | |
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 19 | #import traceback
 | 
| 1185.70.3
by Martin Pool Various updates to make storage branch mergeable: | 20 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 21 | import bzrlib | 
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 22 | from bzrlib.decorators import * | 
| 1185.65.10
by Robert Collins Rename Controlfiles to LockableFiles. | 23 | import bzrlib.errors as errors | 
| 1694.2.6
by Martin Pool [merge] bzr.dev | 24 | from bzrlib.errors import BzrError | 
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 25 | from bzrlib.osutils import file_iterator, safe_unicode | 
| 1185.65.29
by Robert Collins Implement final review suggestions. | 26 | from bzrlib.symbol_versioning import * | 
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 27 | from bzrlib.trace import mutter, note | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 28 | import bzrlib.transactions as transactions | 
| 1185.65.10
by Robert Collins Rename Controlfiles to LockableFiles. | 29 | |
| 1553.5.41
by Martin Pool Add new LockableFiles.LockDirStrategy; not used yet | 30 | # XXX: The tracking here of lock counts and whether the lock is held is
 | 
| 31 | # somewhat redundant with what's done in LockDir; the main difference is that
 | |
| 32 | # LockableFiles permits reentrancy.
 | |
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 33 | |
| 1185.66.3
by Aaron Bentley Renamed ControlFiles to LockableFiles | 34 | class LockableFiles(object): | 
| 1553.5.38
by Martin Pool More explanation for LockableFiles | 35 | """Object representing a set of related files locked within the same scope. | 
| 36 | ||
| 37 |     These files are used by a WorkingTree, Repository or Branch, and should
 | |
| 38 |     generally only be touched by that object.
 | |
| 39 | ||
| 40 |     LockableFiles also provides some policy on top of Transport for encoding
 | |
| 41 |     control files as utf-8.
 | |
| 42 | ||
| 1553.5.39
by Martin Pool More lock docs | 43 |     LockableFiles manage a lock count and can be locked repeatedly by
 | 
| 44 |     a single caller.  (The underlying lock implementation generally does not
 | |
| 45 |     support this.)
 | |
| 46 | ||
| 1553.5.38
by Martin Pool More explanation for LockableFiles | 47 |     Instances of this class are often called control_files.
 | 
| 48 |     
 | |
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 49 |     This object builds on top of a Transport, which is used to actually write
 | 
| 50 |     the files to disk, and an OSLock or LockDir, which controls how access to
 | |
| 51 |     the files is controlled.  The particular type of locking used is set when
 | |
| 52 |     the object is constructed.  In older formats OSLocks are used everywhere.
 | |
| 53 |     in newer formats a LockDir is used for Repositories and Branches, and 
 | |
| 54 |     OSLocks for the local filesystem.
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 55 |     """
 | 
| 1185.65.10
by Robert Collins Rename Controlfiles to LockableFiles. | 56 | |
| 1553.5.47
by Martin Pool cleanup LockableFiles | 57 |     # _lock_mode: None, or 'r' or 'w'
 | 
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 58 | |
| 1553.5.47
by Martin Pool cleanup LockableFiles | 59 |     # _lock_count: If _lock_mode is true, a positive count of the number of
 | 
| 60 |     # times the lock has been taken *by this process*.   
 | |
| 61 | ||
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 62 |     # If set to False (by a plugin, etc) BzrBranch will not set the
 | 
| 63 |     # mode on created files or directories
 | |
| 64 | _set_file_mode = True | |
| 65 | _set_dir_mode = True | |
| 1185.65.10
by Robert Collins Rename Controlfiles to LockableFiles. | 66 | |
| 1553.5.63
by Martin Pool Lock type is now mandatory for LockableFiles constructor | 67 | def __init__(self, transport, lock_name, lock_class): | 
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 68 | """Create a LockableFiles group | 
| 69 | ||
| 70 |         :param transport: Transport pointing to the directory holding the 
 | |
| 71 |             control files and lock.
 | |
| 72 |         :param lock_name: Name of the lock guarding these files.
 | |
| 1553.5.47
by Martin Pool cleanup LockableFiles | 73 |         :param lock_class: Class of lock strategy to use: typically
 | 
| 74 |             either LockDir or TransportLock.
 | |
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 75 |         """
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 76 | object.__init__(self) | 
| 77 | self._transport = transport | |
| 78 | self.lock_name = lock_name | |
| 79 | self._transaction = None | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 80 | self._find_modes() | 
| 1553.5.47
by Martin Pool cleanup LockableFiles | 81 | self._lock_mode = None | 
| 82 | self._lock_count = 0 | |
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 83 | esc_name = self._escape(lock_name) | 
| 1608.2.1
by Martin Pool [merge] Storage filename escaping | 84 | self._lock = lock_class(transport, esc_name, | 
| 1553.5.59
by Martin Pool Pass file/mode bits through to creation of lock files/dirs | 85 | file_modebits=self._file_mode, | 
| 86 | dir_modebits=self._dir_mode) | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 87 | |
| 1553.5.60
by Martin Pool New LockableFiles.create_lock() method | 88 | def create_lock(self): | 
| 89 | """Create the lock. | |
| 90 | ||
| 91 |         This should normally be called only when the LockableFiles directory
 | |
| 92 |         is first created on disk.
 | |
| 93 |         """
 | |
| 1666.1.4
by Robert Collins * 'Metadir' is now the default disk format. This improves behaviour in | 94 | self._lock.create(mode=self._dir_mode) | 
| 1553.5.60
by Martin Pool New LockableFiles.create_lock() method | 95 | |
| 1553.5.53
by Martin Pool Add LockableFiles __repr__ | 96 | def __repr__(self): | 
| 97 | return '%s(%r)' % (self.__class__.__name__, | |
| 98 | self._transport) | |
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 99 | def __str__(self): | 
| 100 | return 'LockableFiles(%s, %s)' % (self.lock_name, self._transport.base) | |
| 101 | ||
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 102 | def __del__(self): | 
| 1608.2.1
by Martin Pool [merge] Storage filename escaping | 103 | if self.is_locked(): | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 104 |             # XXX: This should show something every time, and be suitable for
 | 
| 105 |             # headless operation and embedding
 | |
| 1185.67.9
by Aaron Bentley Fixed most bugs | 106 | from warnings import warn | 
| 1185.65.10
by Robert Collins Rename Controlfiles to LockableFiles. | 107 | warn("file group %r was not explicitly unlocked" % self) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 108 | self._lock.unlock() | 
| 1553.5.53
by Martin Pool Add LockableFiles __repr__ | 109 | |
| 1687.1.6
by Robert Collins Extend LockableFiles to support break_lock() calls. | 110 | def break_lock(self): | 
| 111 | """Break the lock of this lockable files group if it is held. | |
| 112 | ||
| 113 |         The current ui factory will be used to prompt for user conformation.
 | |
| 114 |         """
 | |
| 115 | self._lock.break_lock() | |
| 116 | ||
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 117 | def _escape(self, file_or_path): | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 118 | if not isinstance(file_or_path, basestring): | 
| 119 | file_or_path = '/'.join(file_or_path) | |
| 120 | if file_or_path == '': | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 121 | return u'' | 
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 122 | return bzrlib.transport.urlescape(safe_unicode(file_or_path)) | 
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 123 | |
| 124 | def _find_modes(self): | |
| 125 | """Determine the appropriate modes for files and directories.""" | |
| 126 | try: | |
| 1534.4.28
by Robert Collins first cut at merge from integration. | 127 | st = self._transport.stat('.') | 
| 128 | except errors.TransportNotPossible: | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 129 | self._dir_mode = 0755 | 
| 130 | self._file_mode = 0644 | |
| 131 | else: | |
| 132 | self._dir_mode = st.st_mode & 07777 | |
| 133 |             # Remove the sticky and execute bits for files
 | |
| 134 | self._file_mode = self._dir_mode & ~07111 | |
| 135 | if not self._set_dir_mode: | |
| 136 | self._dir_mode = None | |
| 137 | if not self._set_file_mode: | |
| 138 | self._file_mode = None | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 139 | |
| 140 | def controlfilename(self, file_or_path): | |
| 141 | """Return location relative to branch.""" | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 142 | return self._transport.abspath(self._escape(file_or_path)) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 143 | |
| 1534.1.15
by Robert Collins * The internal storage of history, and logical branch identity have now | 144 | @deprecated_method(zero_eight) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 145 | def controlfile(self, file_or_path, mode='r'): | 
| 146 | """Open a control file for this branch. | |
| 147 | ||
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 148 |         There are two classes of file in a lockable directory: text
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 149 |         and binary.  binary files are untranslated byte streams.  Text
 | 
| 150 |         control files are stored with Unix newlines and in UTF-8, even
 | |
| 151 |         if the platform or locale defaults are different.
 | |
| 152 | ||
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 153 |         Such files are not openable in write mode : they are managed via
 | 
| 154 |         put and put_utf8 which atomically replace old versions using
 | |
| 155 |         atomicfile.
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 156 |         """
 | 
| 157 | ||
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 158 | relpath = self._escape(file_or_path) | 
| 1553.5.43
by Martin Pool Get LockableFiles tests running against LockDir | 159 |         # TODO: codecs.open() buffers linewise, so it was overloaded with
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 160 |         # a much larger buffer, do we need to do the same for getreader/getwriter?
 | 
| 161 | if mode == 'rb': | |
| 1185.65.29
by Robert Collins Implement final review suggestions. | 162 | return self.get(relpath) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 163 | elif mode == 'wb': | 
| 1185.65.12
by Robert Collins Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8. | 164 | raise BzrError("Branch.controlfile(mode='wb') is not supported, use put[_utf8]") | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 165 | elif mode == 'r': | 
| 1185.65.29
by Robert Collins Implement final review suggestions. | 166 | return self.get_utf8(relpath) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 167 | elif mode == 'w': | 
| 1185.65.12
by Robert Collins Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8. | 168 | raise BzrError("Branch.controlfile(mode='w') is not supported, use put[_utf8]") | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 169 | else: | 
| 170 | raise BzrError("invalid controlfile mode %r" % mode) | |
| 171 | ||
| 1185.65.29
by Robert Collins Implement final review suggestions. | 172 |     @needs_read_lock
 | 
| 173 | def get(self, relpath): | |
| 174 | """Get a file as a bytestream.""" | |
| 175 | relpath = self._escape(relpath) | |
| 176 | return self._transport.get(relpath) | |
| 177 | ||
| 178 |     @needs_read_lock
 | |
| 179 | def get_utf8(self, relpath): | |
| 180 | """Get a file as a unicode stream.""" | |
| 181 | relpath = self._escape(relpath) | |
| 182 |         # DO NOT introduce an errors=replace here.
 | |
| 183 | return codecs.getreader('utf-8')(self._transport.get(relpath)) | |
| 184 | ||
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 185 |     @needs_write_lock
 | 
| 1185.65.12
by Robert Collins Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8. | 186 | def put(self, path, file): | 
| 187 | """Write a file. | |
| 188 |         
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 189 |         :param path: The path to put the file, relative to the .bzr control
 | 
| 190 |                      directory
 | |
| 191 |         :param f: A file-like or string object whose contents should be copied.
 | |
| 192 |         """
 | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 193 | self._transport.put(self._escape(path), file, mode=self._file_mode) | 
| 1185.65.12
by Robert Collins Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8. | 194 | |
| 1185.65.27
by Robert Collins Tweak storage towards mergability. | 195 |     @needs_write_lock
 | 
| 1185.65.29
by Robert Collins Implement final review suggestions. | 196 | def put_utf8(self, path, a_string): | 
| 197 | """Write a string, encoding as utf-8. | |
| 1185.65.12
by Robert Collins Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8. | 198 | |
| 1185.65.29
by Robert Collins Implement final review suggestions. | 199 |         :param path: The path to put the string, relative to the transport root.
 | 
| 200 |         :param string: A file-like or string object whose contents should be copied.
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 201 |         """
 | 
| 1185.67.7
by Aaron Bentley Refactored a bit | 202 |         # IterableFile would not be needed if Transport.put took iterables
 | 
| 203 |         # instead of files.  ADHB 2005-12-25
 | |
| 1185.65.17
by Robert Collins Merge from integration, mode-changes are broken. | 204 |         # RBC 20060103 surely its not needed anyway, with codecs transcode
 | 
| 205 |         # file support ?
 | |
| 1185.69.2
by John Arbash Meinel Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch | 206 |         # JAM 20060103 We definitely don't want encode(..., 'replace')
 | 
| 207 |         # these are valuable files which should have exact contents.
 | |
| 1185.65.29
by Robert Collins Implement final review suggestions. | 208 | if not isinstance(a_string, basestring): | 
| 209 | raise errors.BzrBadParameterNotString(a_string) | |
| 210 | self.put(path, StringIO(a_string.encode('utf-8'))) | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 211 | |
| 212 | def lock_write(self): | |
| 1551.2.3
by Aaron Bentley Removed lock-related log spam [recommit] | 213 |         # mutter("lock write: %s (%s)", self, self._lock_count)
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 214 |         # TODO: Upgrade locking to support using a Transport,
 | 
| 215 |         # and potentially a remote locking protocol
 | |
| 216 | if self._lock_mode: | |
| 1594.2.22
by Robert Collins Ensure that lockable files calls finish() on transactions.: | 217 | if self._lock_mode != 'w' or not self.get_transaction().writeable(): | 
| 1694.2.6
by Martin Pool [merge] bzr.dev | 218 | raise errors.ReadOnlyError(self) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 219 | self._lock_count += 1 | 
| 220 | else: | |
| 1553.5.47
by Martin Pool cleanup LockableFiles | 221 | self._lock.lock_write() | 
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 222 |             #note('write locking %s', self)
 | 
| 223 |             #traceback.print_stack()
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 224 | self._lock_mode = 'w' | 
| 225 | self._lock_count = 1 | |
| 1563.2.34
by Robert Collins Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction | 226 | self._set_transaction(transactions.WriteTransaction()) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 227 | |
| 228 | def lock_read(self): | |
| 1551.2.3
by Aaron Bentley Removed lock-related log spam [recommit] | 229 |         # mutter("lock read: %s (%s)", self, self._lock_count)
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 230 | if self._lock_mode: | 
| 231 | assert self._lock_mode in ('r', 'w'), \ | |
| 232 | "invalid lock mode %r" % self._lock_mode | |
| 233 | self._lock_count += 1 | |
| 234 | else: | |
| 1553.5.47
by Martin Pool cleanup LockableFiles | 235 | self._lock.lock_read() | 
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 236 |             #note('read locking %s', self)
 | 
| 237 |             #traceback.print_stack()
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 238 | self._lock_mode = 'r' | 
| 239 | self._lock_count = 1 | |
| 240 | self._set_transaction(transactions.ReadOnlyTransaction()) | |
| 241 |             # 5K may be excessive, but hey, its a knob.
 | |
| 242 | self.get_transaction().set_cache_size(5000) | |
| 243 | ||
| 244 | def unlock(self): | |
| 1551.2.3
by Aaron Bentley Removed lock-related log spam [recommit] | 245 |         # mutter("unlock: %s (%s)", self, self._lock_count)
 | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 246 | if not self._lock_mode: | 
| 1553.5.36
by Martin Pool Clean up duplicate BranchNotLocked error and rename to ObjectNotLocked | 247 | raise errors.LockNotHeld(self) | 
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 248 | if self._lock_count > 1: | 
| 249 | self._lock_count -= 1 | |
| 250 | else: | |
| 1185.80.2
by John Arbash Meinel Traced double locking code to WorkingTree creating its own control files. | 251 |             #note('unlocking %s', self)
 | 
| 252 |             #traceback.print_stack()
 | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 253 | self._finish_transaction() | 
| 1687.1.6
by Robert Collins Extend LockableFiles to support break_lock() calls. | 254 | try: | 
| 255 | self._lock.unlock() | |
| 256 | finally: | |
| 257 | self._lock_mode = self._lock_count = None | |
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 258 | |
| 1553.5.35
by Martin Pool Start break-lock --show | 259 | def is_locked(self): | 
| 260 | """Return true if this LockableFiles group is locked""" | |
| 261 | return self._lock_count >= 1 | |
| 262 | ||
| 1694.2.6
by Martin Pool [merge] bzr.dev | 263 | def get_physical_lock_status(self): | 
| 264 | """Return physical lock status. | |
| 265 |         
 | |
| 266 |         Returns true if a lock is held on the transport. If no lock is held, or
 | |
| 267 |         the underlying locking mechanism does not support querying lock
 | |
| 268 |         status, false is returned.
 | |
| 269 |         """
 | |
| 270 | try: | |
| 271 | return self._lock.peek() is not None | |
| 272 | except NotImplementedError: | |
| 273 | return False | |
| 274 | ||
| 1185.65.1
by Aaron Bentley Refactored out ControlFiles and RevisionStore from _Branch | 275 | def get_transaction(self): | 
| 276 | """Return the current active transaction. | |
| 277 | ||
| 278 |         If no transaction is active, this returns a passthrough object
 | |
| 279 |         for which all data is immediately flushed and no caching happens.
 | |
| 280 |         """
 | |
| 281 | if self._transaction is None: | |
| 282 | return transactions.PassThroughTransaction() | |
| 283 | else: | |
| 284 | return self._transaction | |
| 285 | ||
| 286 | def _set_transaction(self, new_transaction): | |
| 287 | """Set a new active transaction.""" | |
| 288 | if self._transaction is not None: | |
| 289 | raise errors.LockError('Branch %s is in a transaction already.' % | |
| 290 | self) | |
| 291 | self._transaction = new_transaction | |
| 292 | ||
| 293 | def _finish_transaction(self): | |
| 294 | """Exit the current transaction.""" | |
| 295 | if self._transaction is None: | |
| 296 | raise errors.LockError('Branch %s is not in a transaction' % | |
| 297 | self) | |
| 298 | transaction = self._transaction | |
| 299 | self._transaction = None | |
| 300 | transaction.finish() | |
| 1553.5.40
by Martin Pool Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats. | 301 | |
| 302 | ||
| 1553.5.45
by Martin Pool Clean up Transport-based locks for old branches | 303 | class TransportLock(object): | 
| 304 | """Locking method which uses transport-dependent locks. | |
| 305 | ||
| 306 |     On the local filesystem these transform into OS-managed locks.
 | |
| 307 | ||
| 308 |     These do not guard against concurrent access via different
 | |
| 309 |     transports.
 | |
| 310 | ||
| 311 |     This is suitable for use only in WorkingTrees (which are at present
 | |
| 312 |     always local).
 | |
| 1553.5.40
by Martin Pool Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats. | 313 |     """
 | 
| 1553.5.59
by Martin Pool Pass file/mode bits through to creation of lock files/dirs | 314 | def __init__(self, transport, escaped_name, file_modebits, dir_modebits): | 
| 1553.5.40
by Martin Pool Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats. | 315 | self._transport = transport | 
| 316 | self._escaped_name = escaped_name | |
| 1553.5.59
by Martin Pool Pass file/mode bits through to creation of lock files/dirs | 317 | self._file_modebits = file_modebits | 
| 318 | self._dir_modebits = dir_modebits | |
| 1553.5.40
by Martin Pool Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats. | 319 | |
| 1687.1.6
by Robert Collins Extend LockableFiles to support break_lock() calls. | 320 | def break_lock(self): | 
| 321 | raise NotImplementedError(self.break_lock) | |
| 322 | ||
| 1553.5.40
by Martin Pool Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats. | 323 | def lock_write(self): | 
| 324 | self._lock = self._transport.lock_write(self._escaped_name) | |
| 325 | ||
| 326 | def lock_read(self): | |
| 327 | self._lock = self._transport.lock_read(self._escaped_name) | |
| 328 | ||
| 329 | def unlock(self): | |
| 330 | self._lock.unlock() | |
| 331 | self._lock = None | |
| 332 | ||
| 1694.2.6
by Martin Pool [merge] bzr.dev | 333 | def peek(self): | 
| 334 | raise NotImplementedError() | |
| 335 | ||
| 1666.1.4
by Robert Collins * 'Metadir' is now the default disk format. This improves behaviour in | 336 | def create(self, mode=None): | 
| 1553.5.59
by Martin Pool Pass file/mode bits through to creation of lock files/dirs | 337 | """Create lock mechanism""" | 
| 338 |         # for old-style locks, create the file now
 | |
| 1553.5.60
by Martin Pool New LockableFiles.create_lock() method | 339 | self._transport.put(self._escaped_name, StringIO(), | 
| 340 | mode=self._file_modebits) |