~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Martin Pool
  • Date: 2006-03-09 07:59:36 UTC
  • mfrom: (1601 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1602.
  • Revision ID: mbp@sourcefrog.net-20060309075936-c13ae6445966956e
[merge] from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
299
299
        This determines the set of revisions which are involved, and then
300
300
        finds all file ids affected by those revisions.
301
301
        """
302
 
        # TODO: jam 20060119 This code assumes that w.inclusions will
303
 
        #       always be correct. But because of the presence of ghosts
304
 
        #       it is possible to be wrong.
305
 
        #       One specific example from Robert Collins:
306
 
        #       Two branches, with revisions ABC, and AD
307
 
        #       C is a ghost merge of D.
308
 
        #       Inclusions doesn't recognize D as an ancestor.
309
 
        #       If D is ever merged in the future, the weave
310
 
        #       won't be fixed, because AD never saw revision C
311
 
        #       to cause a conflict which would force a reweave.
312
302
        w = self.get_inventory_weave()
313
303
        from_set = set(w.get_ancestry(from_revid))
314
304
        to_set = set(w.get_ancestry(to_revid))
360
350
        w = self.get_inventory_weave()
361
351
        file_ids = set()
362
352
 
363
 
        for lineno, insert, deletes, line in w.walk(changes):
 
353
        # this code needs to read every line in every inventory for the
 
354
        # inventories [changes]. Seeing a line twice is ok. Seeing a line
 
355
        # not pesent in one of those inventories is unnecessary and not 
 
356
        # harmful because we are filtering by the revision id marker in the
 
357
        # inventory lines to only select file ids altered in one of those  
 
358
        # revisions. We dont need to see all lines in the inventory because
 
359
        # only those added in an inventory in rev X can contain a revision=X
 
360
        # line.
 
361
        for line in w.iter_lines_added_or_present_in_versions(changes):
364
362
            start = line.find('file_id="')+9
365
363
            if start < 9: continue
366
364
            end = line.find('"', start)
464
462
                    # no, queue it.
465
463
                    pending.add(parent_id)
466
464
            result.add_node(revision_id, rev.parent_ids)
467
 
            done.add(result)
 
465
            done.add(revision_id)
468
466
        return result
469
467
 
470
468
    @needs_read_lock
489
487
        # FIXME format 4-6 cannot be shared, this is technically faulty.
490
488
        return self.control_files._transport.has('shared-storage')
491
489
 
 
490
    @needs_write_lock
 
491
    def reconcile(self):
 
492
        """Reconcile this repository."""
 
493
        from bzrlib.reconcile import RepoReconciler
 
494
        reconciler = RepoReconciler(self)
 
495
        reconciler.reconcile()
 
496
        return reconciler
 
497
    
492
498
    @needs_read_lock
493
499
    def revision_tree(self, revision_id):
494
500
        """Return Tree for a revision on this branch.
514
520
        if not self.has_revision(revision_id):
515
521
            raise errors.NoSuchRevision(self, revision_id)
516
522
        w = self.get_inventory_weave()
517
 
        return [None] + w.get_ancestry(revision_id)
 
523
        candidates = w.get_ancestry(revision_id)
 
524
        return [None] + candidates # self._eliminate_revisions_not_present(candidates)
518
525
 
519
526
    @needs_read_lock
520
527
    def print_file(self, file, revision_id):
682
689
        """See Repository.all_revision_ids()."""
683
690
        return self._revision_store.all_revision_ids(self.get_transaction())
684
691
 
 
692
    @needs_read_lock
 
693
    def get_ancestry(self, revision_id):
 
694
        """Return a list of revision-ids integrated by a revision.
 
695
        
 
696
        This is topologically sorted.
 
697
        """
 
698
        if revision_id is None:
 
699
            return [None]
 
700
        vf = self._revision_store.get_revision_file(self.get_transaction())
 
701
        try:
 
702
            return [None] + vf.get_ancestry(revision_id)
 
703
        except errors.RevisionNotPresent:
 
704
            raise errors.NoSuchRevision(self, revision_id)
 
705
 
 
706
    @needs_read_lock
 
707
    def get_revision(self, revision_id):
 
708
        """Return the Revision object for a named revision"""
 
709
        return self.get_revision_reconcile(revision_id)
 
710
 
 
711
    @needs_read_lock
 
712
    def get_revision_graph_with_ghosts(self, revision_ids=None):
 
713
        """Return a graph of the revisions with ghosts marked as applicable.
 
714
 
 
715
        :param revision_ids: an iterable of revisions to graph or None for all.
 
716
        :return: a Graph object with the graph reachable from revision_ids.
 
717
        """
 
718
        result = Graph()
 
719
        vf = self._revision_store.get_revision_file(self.get_transaction())
 
720
        versions = vf.versions()
 
721
        if not revision_ids:
 
722
            pending = set(self.all_revision_ids())
 
723
            required = set([])
 
724
        else:
 
725
            pending = set(revision_ids)
 
726
            required = set(revision_ids)
 
727
        done = set([])
 
728
        while len(pending):
 
729
            revision_id = pending.pop()
 
730
            if not revision_id in versions:
 
731
                if revision_id in required:
 
732
                    raise errors.NoSuchRevision(self, revision_id)
 
733
                # a ghost
 
734
                result.add_ghost(revision_id)
 
735
                continue
 
736
            parent_ids = vf.get_parents_with_ghosts(revision_id)
 
737
            for parent_id in parent_ids:
 
738
                # is this queued or done ?
 
739
                if (parent_id not in pending and
 
740
                    parent_id not in done):
 
741
                    # no, queue it.
 
742
                    pending.add(parent_id)
 
743
            result.add_node(revision_id, parent_ids)
 
744
            done.add(result)
 
745
        return result
 
746
 
 
747
    @needs_write_lock
 
748
    def reconcile(self):
 
749
        """Reconcile this repository."""
 
750
        from bzrlib.reconcile import KnitReconciler
 
751
        reconciler = KnitReconciler(self)
 
752
        reconciler.reconcile()
 
753
        return reconciler
 
754
    
685
755
 
686
756
class RepositoryFormat(object):
687
757
    """A repository format.
1186
1256
        repo_transport = a_bzrdir.get_repository_transport(None)
1187
1257
        control_files = LockableFiles(repo_transport, 'lock', LockDir)
1188
1258
        control_store = self._get_control_store(repo_transport, control_files)
1189
 
        transaction = bzrlib.transactions.PassThroughTransaction()
 
1259
        transaction = bzrlib.transactions.WriteTransaction()
1190
1260
        # trigger a write of the inventory store.
1191
1261
        control_store.get_weave_or_empty('inventory', transaction)
1192
1262
        _revision_store = self._get_revision_store(repo_transport, control_files)