~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

Merge with stored_kind

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
        self.tags = self._make_tags()
86
86
        self._revision_history_cache = None
87
87
        self._revision_id_to_revno_cache = None
 
88
        self._last_revision_info_cache = None
88
89
 
89
90
    def break_lock(self):
90
91
        """Break a lock if one is present from another instance.
361
362
        """
362
363
        self._revision_history_cache = None
363
364
        self._revision_id_to_revno_cache = None
 
365
        self._last_revision_info_cache = None
364
366
 
365
367
    def _gen_revision_history(self):
366
368
        """Return sequence of revision hashes on to this branch.
413
415
        """Return last revision id, or NULL_REVISION."""
414
416
        return self.last_revision_info()[1]
415
417
 
 
418
    @needs_read_lock
416
419
    def last_revision_info(self):
417
420
        """Return information about the last revision.
418
421
 
419
 
        :return: A tuple (revno, last_revision_id).
 
422
        :return: A tuple (revno, revision_id).
420
423
        """
 
424
        if self._last_revision_info_cache is None:
 
425
            self._last_revision_info_cache = self._last_revision_info()
 
426
        return self._last_revision_info_cache
 
427
 
 
428
    def _last_revision_info(self):
421
429
        rh = self.revision_history()
422
430
        revno = len(rh)
423
431
        if revno:
484
492
            if not overwrite:
485
493
                if graph is None:
486
494
                    graph = self.repository.get_graph()
487
 
                heads = graph.heads([stop_revision, last_rev])
488
 
                if heads == set([last_rev]):
489
 
                    # The current revision is a decendent of the target,
490
 
                    # nothing to do
 
495
                if self._check_if_descendant_or_diverged(
 
496
                        stop_revision, last_rev, graph, other):
 
497
                    # stop_revision is a descendant of last_rev, but we aren't
 
498
                    # overwriting, so we're done.
491
499
                    return
492
 
                elif heads == set([stop_revision, last_rev]):
493
 
                    # These branches have diverged
494
 
                    raise errors.DivergedBranches(self, other)
495
 
                elif heads != set([stop_revision]):
496
 
                    raise AssertionError("invalid heads: %r" % heads)
497
500
            if stop_revno is None:
498
501
                if graph is None:
499
502
                    graph = self.repository.get_graph()
854
857
    def supports_tags(self):
855
858
        return self._format.supports_tags()
856
859
 
 
860
    def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
 
861
                                         other_branch):
 
862
        """Ensure that revision_b is a descendant of revision_a.
 
863
 
 
864
        This is a helper function for update_revisions.
 
865
        
 
866
        :raises: DivergedBranches if revision_b has diverged from revision_a.
 
867
        :returns: True if revision_b is a descendant of revision_a.
 
868
        """
 
869
        relation = self._revision_relations(revision_a, revision_b, graph)
 
870
        if relation == 'b_descends_from_a':
 
871
            return True
 
872
        elif relation == 'diverged':
 
873
            raise errors.DivergedBranches(self, other_branch)
 
874
        elif relation == 'a_descends_from_b':
 
875
            return False
 
876
        else:
 
877
            raise AssertionError("invalid heads: %r" % heads)
 
878
 
 
879
    def _revision_relations(self, revision_a, revision_b, graph):
 
880
        """Determine the relationship between two revisions.
 
881
        
 
882
        :returns: One of: 'a_descends_from_b', 'b_descends_from_a', 'diverged'
 
883
        """
 
884
        heads = graph.heads([revision_a, revision_b])
 
885
        if heads == set([revision_b]):
 
886
            return 'b_descends_from_a'
 
887
        elif heads == set([revision_a, revision_b]):
 
888
            # These branches have diverged
 
889
            return 'diverged'
 
890
        elif heads == set([revision_a]):
 
891
            return 'a_descends_from_b'
 
892
        else:
 
893
            raise AssertionError("invalid heads: %r" % heads)
 
894
 
857
895
 
858
896
class BranchFormat(object):
859
897
    """An encapsulation of the initialization and open routines for a format.
1465
1503
        """See Branch.set_revision_history."""
1466
1504
        if 'evil' in debug.debug_flags:
1467
1505
            mutter_callsite(3, "set_revision_history scales with history.")
 
1506
        check_not_reserved_id = _mod_revision.check_not_reserved_id
 
1507
        for rev_id in rev_history:
 
1508
            check_not_reserved_id(rev_id)
1468
1509
        self._write_revision_history(rev_history)
1469
1510
        self._clear_cached_state()
1470
1511
        self._cache_revision_history(rev_history)
1528
1569
            raise errors.NoSuchRevision(self, revision_id)
1529
1570
        current_rev_id = revision_id
1530
1571
        new_history = []
 
1572
        check_not_reserved_id = _mod_revision.check_not_reserved_id
1531
1573
        # Do not include ghosts or graph origin in revision_history
1532
1574
        while (current_rev_id in parents_map and
1533
1575
               len(parents_map[current_rev_id]) > 0):
 
1576
            check_not_reserved_id(current_rev_id)
1534
1577
            new_history.append(current_rev_id)
1535
1578
            current_rev_id = parents_map[current_rev_id][0]
1536
1579
            parents_map = graph.get_parent_map([current_rev_id])
1882
1925
 
1883
1926
    def __init__(self, *args, **kwargs):
1884
1927
        super(BzrBranch6, self).__init__(*args, **kwargs)
1885
 
        self._last_revision_info_cache = None
1886
1928
        self._partial_revision_history_cache = []
1887
1929
 
1888
1930
    def _clear_cached_state(self):
1889
1931
        super(BzrBranch6, self)._clear_cached_state()
1890
 
        self._last_revision_info_cache = None
1891
1932
        self._partial_revision_history_cache = []
1892
1933
 
1893
 
    @needs_read_lock
1894
 
    def last_revision_info(self):
1895
 
        """Return information about the last revision.
1896
 
 
1897
 
        :return: A tuple (revno, revision_id).
1898
 
        """
1899
 
        if self._last_revision_info_cache is None:
1900
 
            self._last_revision_info_cache = self._last_revision_info()
1901
 
        return self._last_revision_info_cache
1902
 
 
1903
1934
    def _last_revision_info(self):
1904
1935
        revision_string = self._transport.get_bytes('last-revision')
1905
1936
        revno, revision_id = revision_string.rstrip('\n').split(' ', 1)