/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5752.3.8 by John Arbash Meinel
Merge bzr.dev 5764 to resolve release-notes (aka NEWS) conflicts
1
# Copyright (C) 2005-2011 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.65.22 by Robert Collins
lockable_files was extracted from branch.py - give it a copyright statement
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.65.22 by Robert Collins
lockable_files was extracted from branch.py - give it a copyright statement
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.65.22 by Robert Collins
lockable_files was extracted from branch.py - give it a copyright statement
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
1185.65.22 by Robert Collins
lockable_files was extracted from branch.py - give it a copyright statement
16
6379.6.1 by Jelmer Vernooij
Import absolute_import in a few places.
17
from __future__ import absolute_import
18
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
19
from .lazy_import import lazy_import
3535.5.1 by John Arbash Meinel
cleanup a few imports to be lazily loaded.
20
lazy_import(globals(), """
21
import warnings
22
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
23
from breezy import (
3468.3.3 by Martin Pool
Fix import
24
    counted_lock,
3535.5.1 by John Arbash Meinel
cleanup a few imports to be lazily loaded.
25
    errors,
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
26
    lock,
3535.5.1 by John Arbash Meinel
cleanup a few imports to be lazily loaded.
27
    osutils,
28
    transactions,
29
    urlutils,
30
    )
31
""")
32
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
33
from .decorators import (
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
34
    only_raises,
3535.5.1 by John Arbash Meinel
cleanup a few imports to be lazily loaded.
35
    )
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
36
1185.65.10 by Robert Collins
Rename Controlfiles to LockableFiles.
37
1185.66.3 by Aaron Bentley
Renamed ControlFiles to LockableFiles
38
class LockableFiles(object):
1553.5.38 by Martin Pool
More explanation for LockableFiles
39
    """Object representing a set of related files locked within the same scope.
40
4570.3.1 by Martin Pool
Update LockableFiles docstring
41
    This coordinates access to the lock along with providing a transaction.
1553.5.38 by Martin Pool
More explanation for LockableFiles
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.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
48
49
    This class is now deprecated; code should move to using the Transport
50
    directly for file operations and using the lock or CountedLock for
3407.2.9 by Martin Pool
doc
51
    locking.
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
52
3407.2.19 by Martin Pool
CountedLock should manage lock tokens
53
    :ivar _lock: The real underlying lock (e.g. a LockDir)
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
54
    :ivar _lock_count: If _lock_mode is true, a positive count of the number
55
        of times the lock has been taken (and not yet released) *by this
56
        process*, through this particular object instance.
57
    :ivar _lock_mode: None, or 'r' or 'w'
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
58
    """
1185.65.10 by Robert Collins
Rename Controlfiles to LockableFiles.
59
1553.5.63 by Martin Pool
Lock type is now mandatory for LockableFiles constructor
60
    def __init__(self, transport, lock_name, lock_class):
1553.5.43 by Martin Pool
Get LockableFiles tests running against LockDir
61
        """Create a LockableFiles group
62
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
63
        :param transport: Transport pointing to the directory holding the
1553.5.43 by Martin Pool
Get LockableFiles tests running against LockDir
64
            control files and lock.
65
        :param lock_name: Name of the lock guarding these files.
1553.5.47 by Martin Pool
cleanup LockableFiles
66
        :param lock_class: Class of lock strategy to use: typically
67
            either LockDir or TransportLock.
1553.5.43 by Martin Pool
Get LockableFiles tests running against LockDir
68
        """
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
69
        self._transport = transport
70
        self.lock_name = lock_name
71
        self._transaction = None
1553.5.47 by Martin Pool
cleanup LockableFiles
72
        self._lock_mode = None
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
73
        self._lock_count = 0
1685.1.43 by John Arbash Meinel
Bug in lockable files when _find_mode throws
74
        self._find_modes()
1553.5.43 by Martin Pool
Get LockableFiles tests running against LockDir
75
        esc_name = self._escape(lock_name)
1608.2.1 by Martin Pool
[merge] Storage filename escaping
76
        self._lock = lock_class(transport, esc_name,
1553.5.59 by Martin Pool
Pass file/mode bits through to creation of lock files/dirs
77
                                file_modebits=self._file_mode,
78
                                dir_modebits=self._dir_mode)
3468.3.3 by Martin Pool
Fix import
79
        self._counted_lock = counted_lock.CountedLock(self._lock)
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
80
1553.5.60 by Martin Pool
New LockableFiles.create_lock() method
81
    def create_lock(self):
82
        """Create the lock.
83
84
        This should normally be called only when the LockableFiles directory
85
        is first created on disk.
86
        """
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
87
        self._lock.create(mode=self._dir_mode)
1553.5.60 by Martin Pool
New LockableFiles.create_lock() method
88
1553.5.53 by Martin Pool
Add LockableFiles __repr__
89
    def __repr__(self):
90
        return '%s(%r)' % (self.__class__.__name__,
91
                           self._transport)
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
92
1185.80.2 by John Arbash Meinel
Traced double locking code to WorkingTree creating its own control files.
93
    def __str__(self):
94
        return 'LockableFiles(%s, %s)' % (self.lock_name, self._transport.base)
95
1687.1.6 by Robert Collins
Extend LockableFiles to support break_lock() calls.
96
    def break_lock(self):
97
        """Break the lock of this lockable files group if it is held.
98
99
        The current ui factory will be used to prompt for user conformation.
100
        """
101
        self._lock.break_lock()
102
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
103
    def _escape(self, file_or_path):
3834.2.2 by Martin Pool
Deprecated LockableFiles._escape
104
        """DEPRECATED: Do not use outside this class"""
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
105
        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
106
            return u''
6677.1.1 by Martin
Go back to native str for urls and many other py3 changes
107
        return urlutils.escape(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
108
109
    def _find_modes(self):
3416.2.1 by Martin Pool
Add BzrDir._get_file_mode and _get_dir_mode
110
        """Determine the appropriate modes for files and directories.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
111
4570.3.4 by Martin Pool
Doc
112
        :deprecated: Replaced by BzrDir._find_creation_modes.
3416.2.1 by Martin Pool
Add BzrDir._get_file_mode and _get_dir_mode
113
        """
3407.2.19 by Martin Pool
CountedLock should manage lock tokens
114
        # XXX: The properties created by this can be removed or deprecated
115
        # once all the _get_text_store methods etc no longer use them.
116
        # -- mbp 20080512
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
117
        try:
1534.4.28 by Robert Collins
first cut at merge from integration.
118
            st = self._transport.stat('.')
119
        except errors.TransportNotPossible:
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
120
            self._dir_mode = 0o755
121
            self._file_mode = 0o644
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
122
        else:
3107.2.1 by John Arbash Meinel
Fix LockableFiles to not use modes that allow the user to write to things they create.
123
            # Check the directory mode, but also make sure the created
124
            # directories and files are read-write for this user. This is
125
            # mostly a workaround for filesystems which lie about being able to
126
            # write to a directory (cygwin & win32)
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
127
            self._dir_mode = (st.st_mode & 0o7777) | 0o0700
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
128
            # Remove the sticky and execute bits for files
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
129
            self._file_mode = self._dir_mode & ~0o7111
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
130
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
131
    def leave_in_place(self):
132
        """Set this LockableFiles to not clear the physical lock on unlock."""
133
        self._lock.leave_in_place()
134
135
    def dont_leave_in_place(self):
136
        """Set this LockableFiles to clear the physical lock on unlock."""
137
        self._lock.dont_leave_in_place()
138
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
139
    def lock_write(self, token=None):
140
        """Lock this group of files for writing.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
141
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
142
        :param token: if this is already locked, then lock_write will fail
143
            unless the token matches the existing lock.
144
        :returns: a token if this instance supports tokens, otherwise None.
145
        :raises TokenLockingNotSupported: when a token is given but this
146
            instance doesn't support using token locks.
147
        :raises MismatchedToken: if the specified token doesn't match the token
148
            of the existing lock.
2018.5.145 by Andrew Bennetts
Add a brief explanation of what tokens are used for to lock_write docstrings.
149
150
        A token should be passed in if you know that you have locked the object
151
        some other way, and need to synchronise this object's state with that
152
        fact.
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
153
        """
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
154
        if self._lock_mode:
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
155
            if (self._lock_mode != 'w'
156
                or not self.get_transaction().writeable()):
1694.2.6 by Martin Pool
[merge] bzr.dev
157
                raise errors.ReadOnlyError(self)
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
158
            self._lock.validate_token(token)
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
159
            self._lock_count += 1
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
160
            return self._token_from_lock
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
161
        else:
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
162
            token_from_lock = self._lock.lock_write(token=token)
1185.80.2 by John Arbash Meinel
Traced double locking code to WorkingTree creating its own control files.
163
            #traceback.print_stack()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
164
            self._lock_mode = 'w'
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
165
            self._lock_count = 1
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
166
            self._set_write_transaction()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
167
            self._token_from_lock = token_from_lock
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
168
            return token_from_lock
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
169
170
    def lock_read(self):
171
        if self._lock_mode:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
172
            if self._lock_mode not in ('r', 'w'):
173
                raise ValueError("invalid lock mode %r" % (self._lock_mode,))
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
174
            self._lock_count += 1
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
175
        else:
1553.5.47 by Martin Pool
cleanup LockableFiles
176
            self._lock.lock_read()
1185.80.2 by John Arbash Meinel
Traced double locking code to WorkingTree creating its own control files.
177
            #traceback.print_stack()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
178
            self._lock_mode = 'r'
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
179
            self._lock_count = 1
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
180
            self._set_read_transaction()
181
182
    def _set_read_transaction(self):
183
        """Setup a read transaction."""
184
        self._set_transaction(transactions.ReadOnlyTransaction())
185
        # 5K may be excessive, but hey, its a knob.
186
        self.get_transaction().set_cache_size(5000)
187
188
    def _set_write_transaction(self):
189
        """Setup a write transaction."""
190
        self._set_transaction(transactions.WriteTransaction())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
191
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
192
    @only_raises(errors.LockNotHeld, errors.LockBroken)
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
193
    def unlock(self):
194
        if not self._lock_mode:
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
195
            return lock.cant_unlock_not_held(self)
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
196
        if self._lock_count > 1:
197
            self._lock_count -= 1
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
198
        else:
1185.80.2 by John Arbash Meinel
Traced double locking code to WorkingTree creating its own control files.
199
            #traceback.print_stack()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
200
            self._finish_transaction()
1687.1.6 by Robert Collins
Extend LockableFiles to support break_lock() calls.
201
            try:
202
                self._lock.unlock()
203
            finally:
6677.1.1 by Martin
Go back to native str for urls and many other py3 changes
204
                self._lock_count = 0
205
                self._lock_mode = None
4104.4.1 by Robert Collins
Cherrypick bugfixes from bzr.dev for 1.13:
206
1553.5.35 by Martin Pool
Start break-lock --show
207
    def is_locked(self):
208
        """Return true if this LockableFiles group is locked"""
5967.8.1 by Martin Pool
Also remove LockWarner and its del method (see bug 721166)
209
        return self._lock_count >= 1
1553.5.35 by Martin Pool
Start break-lock --show
210
1694.2.6 by Martin Pool
[merge] bzr.dev
211
    def get_physical_lock_status(self):
212
        """Return physical lock status.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
213
1694.2.6 by Martin Pool
[merge] bzr.dev
214
        Returns true if a lock is held on the transport. If no lock is held, or
215
        the underlying locking mechanism does not support querying lock
216
        status, false is returned.
217
        """
218
        try:
219
            return self._lock.peek() is not None
220
        except NotImplementedError:
221
            return False
222
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
223
    def get_transaction(self):
224
        """Return the current active transaction.
225
226
        If no transaction is active, this returns a passthrough object
227
        for which all data is immediately flushed and no caching happens.
228
        """
229
        if self._transaction is None:
230
            return transactions.PassThroughTransaction()
231
        else:
232
            return self._transaction
233
234
    def _set_transaction(self, new_transaction):
235
        """Set a new active transaction."""
236
        if self._transaction is not None:
237
            raise errors.LockError('Branch %s is in a transaction already.' %
238
                                   self)
239
        self._transaction = new_transaction
240
241
    def _finish_transaction(self):
242
        """Exit the current transaction."""
243
        if self._transaction is None:
244
            raise errors.LockError('Branch %s is not in a transaction' %
245
                                   self)
246
        transaction = self._transaction
247
        self._transaction = None
248
        transaction.finish()
1553.5.40 by Martin Pool
Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats.
249
250
1553.5.45 by Martin Pool
Clean up Transport-based locks for old branches
251
class TransportLock(object):
252
    """Locking method which uses transport-dependent locks.
253
254
    On the local filesystem these transform into OS-managed locks.
255
256
    These do not guard against concurrent access via different
257
    transports.
258
259
    This is suitable for use only in WorkingTrees (which are at present
260
    always local).
1553.5.40 by Martin Pool
Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats.
261
    """
1553.5.59 by Martin Pool
Pass file/mode bits through to creation of lock files/dirs
262
    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.
263
        self._transport = transport
264
        self._escaped_name = escaped_name
1553.5.59 by Martin Pool
Pass file/mode bits through to creation of lock files/dirs
265
        self._file_modebits = file_modebits
266
        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.
267
1687.1.6 by Robert Collins
Extend LockableFiles to support break_lock() calls.
268
    def break_lock(self):
269
        raise NotImplementedError(self.break_lock)
270
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
271
    def leave_in_place(self):
272
        raise NotImplementedError(self.leave_in_place)
273
2018.5.76 by Andrew Bennetts
Testing that repository.{dont_,}leave_lock_in_place raises NotImplementedError if lock_write returns None.
274
    def dont_leave_in_place(self):
275
        raise NotImplementedError(self.dont_leave_in_place)
276
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
277
    def lock_write(self, token=None):
278
        if token is not None:
279
            raise errors.TokenLockingNotSupported(self)
1553.5.40 by Martin Pool
Factor locking strategy out of LockableFiles so that we can use LockDirs in new formats.
280
        self._lock = self._transport.lock_write(self._escaped_name)
281
282
    def lock_read(self):
283
        self._lock = self._transport.lock_read(self._escaped_name)
284
285
    def unlock(self):
286
        self._lock.unlock()
287
        self._lock = None
288
1694.2.6 by Martin Pool
[merge] bzr.dev
289
    def peek(self):
290
        raise NotImplementedError()
291
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
292
    def create(self, mode=None):
1553.5.59 by Martin Pool
Pass file/mode bits through to creation of lock files/dirs
293
        """Create lock mechanism"""
294
        # for old-style locks, create the file now
1955.3.8 by John Arbash Meinel
avoid some deprecation warnings in other parts of the code
295
        self._transport.put_bytes(self._escaped_name, '',
1553.5.60 by Martin Pool
New LockableFiles.create_lock() method
296
                            mode=self._file_modebits)
2279.7.1 by Andrew Bennetts
``LockableFiles.lock_write()`` now accepts a ``token`` keyword argument, so that
297
298
    def validate_token(self, token):
299
        if token is not None:
300
            raise errors.TokenLockingNotSupported(self)