~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Aaron Bentley
  • Date: 2007-08-15 11:24:06 UTC
  • mfrom: (2702 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2703.
  • Revision ID: aaron.bentley@utoronto.ca-20070815112406-lyv23omlm0wgsu42
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
82
82
        r'.*revision="(?P<revision_id>[^"]+)"'
83
83
        )
84
84
 
 
85
    def abort_write_group(self):
 
86
        """Commit the contents accrued within the current write group.
 
87
 
 
88
        :seealso: start_write_group.
 
89
        """
 
90
        if self._write_group is not self.get_transaction():
 
91
            # has an unlock or relock occured ?
 
92
            raise errors.BzrError('mismatched lock context and write group.')
 
93
        self._abort_write_group()
 
94
        self._write_group = None
 
95
 
 
96
    def _abort_write_group(self):
 
97
        """Template method for per-repository write group cleanup.
 
98
        
 
99
        This is called during abort before the write group is considered to be 
 
100
        finished and should cleanup any internal state accrued during the write
 
101
        group. There is no requirement that data handed to the repository be
 
102
        *not* made available - this is not a rollback - but neither should any
 
103
        attempt be made to ensure that data added is fully commited. Abort is
 
104
        invoked when an error has occured so futher disk or network operations
 
105
        may not be possible or may error and if possible should not be
 
106
        attempted.
 
107
        """
 
108
 
85
109
    @needs_write_lock
86
110
    def add_inventory(self, revision_id, inv, parents):
87
111
        """Add the inventory inv to the repository as revision_id.
230
254
        # TODO: make sure to construct the right store classes, etc, depending
231
255
        # on whether escaping is required.
232
256
        self._warn_if_deprecated()
 
257
        self._write_group = None
233
258
 
234
259
    def __repr__(self):
235
260
        return '%s(%r)' % (self.__class__.__name__, 
247
272
        return (self.control_files._transport.base ==
248
273
                other.control_files._transport.base)
249
274
 
 
275
    def is_in_write_group(self):
 
276
        """Return True if there is an open write group.
 
277
 
 
278
        :seealso: start_write_group.
 
279
        """
 
280
        return self._write_group is not None
 
281
 
250
282
    def is_locked(self):
251
283
        return self.control_files.is_locked()
252
284
 
253
285
    def lock_write(self, token=None):
254
286
        """Lock this repository for writing.
 
287
 
 
288
        This causes caching within the repository obejct to start accumlating
 
289
        data during reads, and allows a 'write_group' to be obtained. Write
 
290
        groups must be used for actual data insertion.
255
291
        
256
292
        :param token: if this is already locked, then lock_write will fail
257
293
            unless the token matches the existing lock.
260
296
            instance doesn't support using token locks.
261
297
        :raises MismatchedToken: if the specified token doesn't match the token
262
298
            of the existing lock.
 
299
        :seealso: start_write_group.
263
300
 
264
301
        A token should be passed in if you know that you have locked the object
265
302
        some other way, and need to synchronise this object's state with that
267
304
 
268
305
        XXX: this docstring is duplicated in many places, e.g. lockable_files.py
269
306
        """
270
 
        return self.control_files.lock_write(token=token)
 
307
        result = self.control_files.lock_write(token=token)
 
308
        self._refresh_data()
 
309
        return result
271
310
 
272
311
    def lock_read(self):
273
312
        self.control_files.lock_read()
 
313
        self._refresh_data()
274
314
 
275
315
    def get_physical_lock_status(self):
276
316
        return self.control_files.get_physical_lock_status()
371
411
        revision_id = osutils.safe_revision_id(revision_id)
372
412
        return InterRepository.get(self, destination).copy_content(revision_id)
373
413
 
 
414
    def commit_write_group(self):
 
415
        """Commit the contents accrued within the current write group.
 
416
 
 
417
        :seealso: start_write_group.
 
418
        """
 
419
        if self._write_group is not self.get_transaction():
 
420
            # has an unlock or relock occured ?
 
421
            raise errors.BzrError('mismatched lock context and write group.')
 
422
        self._commit_write_group()
 
423
        self._write_group = None
 
424
 
 
425
    def _commit_write_group(self):
 
426
        """Template method for per-repository write group cleanup.
 
427
        
 
428
        This is called before the write group is considered to be 
 
429
        finished and should ensure that all data handed to the repository
 
430
        for writing during the write group is safely committed (to the 
 
431
        extent possible considering file system caching etc).
 
432
        """
 
433
 
374
434
    def fetch(self, source, revision_id=None, pb=None):
375
435
        """Fetch the content required to construct revision_id from source.
376
436
 
401
461
        :param revision_id: Optional revision id.
402
462
        """
403
463
        revision_id = osutils.safe_revision_id(revision_id)
404
 
        return _CommitBuilder(self, parents, config, timestamp, timezone,
 
464
        result =_CommitBuilder(self, parents, config, timestamp, timezone,
405
465
                              committer, revprops, revision_id)
 
466
        self.start_write_group()
 
467
        return result
406
468
 
407
469
    def unlock(self):
 
470
        if (self.control_files._lock_count == 1 and
 
471
            self.control_files._lock_mode == 'w'):
 
472
            if self._write_group is not None:
 
473
                raise errors.BzrError(
 
474
                    'Must end write groups before releasing write locks.')
408
475
        self.control_files.unlock()
409
476
 
410
477
    @needs_read_lock
422
489
        self.copy_content_into(dest_repo, revision_id)
423
490
        return dest_repo
424
491
 
 
492
    def start_write_group(self):
 
493
        """Start a write group in the repository.
 
494
 
 
495
        Write groups are used by repositories which do not have a 1:1 mapping
 
496
        between file ids and backend store to manage the insertion of data from
 
497
        both fetch and commit operations.
 
498
 
 
499
        A write lock is required around the start_write_group/commit_write_group
 
500
        for the support of lock-requiring repository formats.
 
501
 
 
502
        One can only insert data into a repository inside a write group.
 
503
 
 
504
        :return: None.
 
505
        """
 
506
        if not self.is_locked() or self.control_files._lock_mode != 'w':
 
507
            raise errors.NotWriteLocked(self)
 
508
        if self._write_group:
 
509
            raise errors.BzrError('already in a write group')
 
510
        self._start_write_group()
 
511
        # so we can detect unlock/relock - the write group is now entered.
 
512
        self._write_group = self.get_transaction()
 
513
 
 
514
    def _start_write_group(self):
 
515
        """Template method for per-repository write group startup.
 
516
        
 
517
        This is called before the write group is considered to be 
 
518
        entered.
 
519
        """
 
520
 
425
521
    @needs_read_lock
426
522
    def sprout(self, to_bzrdir, revision_id=None):
427
523
        """Create a descendent repository for new development.
813
909
        reconciler.reconcile()
814
910
        return reconciler
815
911
 
 
912
    def _refresh_data(self):
 
913
        """Helper called from lock_* to ensure coherency with disk.
 
914
 
 
915
        The default implementation does nothing; it is however possible
 
916
        for repositories to maintain loaded indices across multiple locks
 
917
        by checking inside their implementation of this method to see
 
918
        whether their indices are still valid. This depends of course on
 
919
        the disk format being validatable in this manner.
 
920
        """
 
921
 
816
922
    @needs_read_lock
817
923
    def revision_tree(self, revision_id):
818
924
        """Return Tree for a revision on this branch.
1059
1165
 
1060
1166
    inv = revision_tree.inventory
1061
1167
    entries = inv.iter_entries()
1062
 
    # backwards compatability hack: skip the root id.
 
1168
    # backwards compatibility hack: skip the root id.
1063
1169
    if not repository.supports_rich_root():
1064
1170
        path, root = entries.next()
1065
1171
        if root.revision != rev.revision_id:
1938
2044
                       revision_id=self._new_revision_id,
1939
2045
                       properties=self._revprops)
1940
2046
        rev.parent_ids = self.parents
1941
 
        self.repository.add_revision(self._new_revision_id, rev, 
 
2047
        self.repository.add_revision(self._new_revision_id, rev,
1942
2048
            self.new_inventory, self._config)
 
2049
        self.repository.commit_write_group()
1943
2050
        return self._new_revision_id
1944
2051
 
1945
2052
    def revision_tree(self):