/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Andrew Bennetts
  • Date: 2008-10-27 06:14:45 UTC
  • mfrom: (3793 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3795.
  • Revision ID: andrew.bennetts@canonical.com-20081027061445-eqt9lz6uw1mbvq4g
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
        urlutils,
37
37
        )
38
38
from bzrlib.config import BranchConfig
39
 
from bzrlib.repofmt.pack_repo import RepositoryFormatPackDevelopment1Subtree
 
39
from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5RichRoot
40
40
from bzrlib.tag import (
41
41
    BasicTags,
42
42
    DisabledTags,
91
91
        self._revision_id_to_revno_cache = None
92
92
        self._last_revision_info_cache = None
93
93
        self._open_hook()
 
94
        hooks = Branch.hooks['open']
 
95
        for hook in hooks:
 
96
            hook(self)
94
97
 
95
98
    def _open_hook(self):
96
99
        """Called by init to allow simpler extension of the base class."""
1068
1071
        # (branch, revision_history), and the branch will
1069
1072
        # be write-locked.
1070
1073
        self['set_rh'] = []
 
1074
        # Invoked after a branch is opened. The api signature is (branch).
 
1075
        self['open'] = []
1071
1076
        # invoked after a push operation completes.
1072
1077
        # the api signature is
1073
1078
        # (push_result)
1121
1126
        # (params) where params is a ChangeBranchTipParams with the members
1122
1127
        # (branch, old_revno, new_revno, old_revid, new_revid)
1123
1128
        self['post_change_branch_tip'] = []
 
1129
        # Introduced in 1.9
 
1130
        # Invoked when a stacked branch activates its fallback locations and
 
1131
        # allows the transformation of the url of said location.
 
1132
        # the api signature is
 
1133
        # (branch, url) where branch is the branch having its fallback
 
1134
        # location activated and url is the url for the fallback location.
 
1135
        # The hook should return a url.
 
1136
        self['transform_fallback_location'] = []
1124
1137
 
1125
1138
 
1126
1139
# install the default hooks into the Branch class.
1341
1354
    def __init__(self):
1342
1355
        super(BzrBranchFormat7, self).__init__()
1343
1356
        self._matchingbzrdir.repository_format = \
1344
 
            RepositoryFormatPackDevelopment1Subtree()
 
1357
            RepositoryFormatKnitPack5RichRoot()
1345
1358
 
1346
1359
    def supports_stacking(self):
1347
1360
        return True
1738
1751
        """
1739
1752
        # TODO: Public option to disable running hooks - should be trivial but
1740
1753
        # needs tests.
1741
 
        target.lock_write()
1742
 
        try:
1743
 
            result = self._push_with_bound_branches(target, overwrite,
1744
 
                    stop_revision,
1745
 
                    _override_hook_source_branch=_override_hook_source_branch)
1746
 
            return result
1747
 
        finally:
1748
 
            target.unlock()
 
1754
        return _run_with_write_locked_target(
 
1755
            target, self._push_with_bound_branches, target, overwrite,
 
1756
            stop_revision,
 
1757
            _override_hook_source_branch=_override_hook_source_branch)
1749
1758
 
1750
1759
    def _push_with_bound_branches(self, target, overwrite,
1751
1760
            stop_revision,
1802
1811
        result.source_branch = self
1803
1812
        result.target_branch = target
1804
1813
        result.old_revno, result.old_revid = target.last_revision_info()
1805
 
 
1806
 
        # We assume that during 'push' this repository is closer than
1807
 
        # the target.
1808
 
        graph = self.repository.get_graph(target.repository)
1809
 
        target.update_revisions(self, stop_revision, overwrite=overwrite,
1810
 
                                graph=graph)
1811
 
        result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
 
1814
        if result.old_revid != self.last_revision():
 
1815
            # We assume that during 'push' this repository is closer than
 
1816
            # the target.
 
1817
            graph = self.repository.get_graph(target.repository)
 
1818
            target.update_revisions(self, stop_revision, overwrite=overwrite,
 
1819
                                    graph=graph)
 
1820
        if self._push_should_merge_tags():
 
1821
            result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
1812
1822
        result.new_revno, result.new_revid = target.last_revision_info()
1813
1823
        return result
1814
1824
 
 
1825
    def _push_should_merge_tags(self):
 
1826
        """Should _basic_push merge this branch's tags into the target?
 
1827
        
 
1828
        The default implementation returns False if this branch has no tags,
 
1829
        and True the rest of the time.  Subclasses may override this.
 
1830
        """
 
1831
        return self.tags.supports_tags() and self.tags.get_tag_dict()
 
1832
 
1815
1833
    def get_parent(self):
1816
1834
        """See Branch.get_parent."""
1817
1835
        parent = self._get_parent_location()
2011
2029
            errors.UnstackableBranchFormat):
2012
2030
            pass
2013
2031
        else:
 
2032
            for hook in Branch.hooks['transform_fallback_location']:
 
2033
                url = hook(self, url)
 
2034
                if url is None:
 
2035
                    hook_name = Branch.hooks.get_hook_name(hook)
 
2036
                    raise AssertionError(
 
2037
                        "'transform_fallback_location' hook %s returned "
 
2038
                        "None, not a URL." % hook_name)
2014
2039
            self._activate_fallback_location(url)
2015
2040
 
2016
2041
    def _check_stackable_repo(self):
2431
2456
        branch._set_config_location('stacked_on_location', '')
2432
2457
        # update target format
2433
2458
        branch._transport.put_bytes('format', format.get_format_string())
 
2459
 
 
2460
 
 
2461
 
 
2462
def _run_with_write_locked_target(target, callable, *args, **kwargs):
 
2463
    """Run ``callable(*args, **kwargs)``, write-locking target for the
 
2464
    duration.
 
2465
 
 
2466
    _run_with_write_locked_target will attempt to release the lock it acquires.
 
2467
 
 
2468
    If an exception is raised by callable, then that exception *will* be
 
2469
    propagated, even if the unlock attempt raises its own error.  Thus
 
2470
    _run_with_write_locked_target should be preferred to simply doing::
 
2471
 
 
2472
        target.lock_write()
 
2473
        try:
 
2474
            return callable(*args, **kwargs)
 
2475
        finally:
 
2476
            target.unlock()
 
2477
    
 
2478
    """
 
2479
    # This is very similar to bzrlib.decorators.needs_write_lock.  Perhaps they
 
2480
    # should share code?
 
2481
    target.lock_write()
 
2482
    try:
 
2483
        result = callable(*args, **kwargs)
 
2484
    except:
 
2485
        exc_info = sys.exc_info()
 
2486
        try:
 
2487
            target.unlock()
 
2488
        finally:
 
2489
            raise exc_info[0], exc_info[1], exc_info[2]
 
2490
    else:
 
2491
        target.unlock()
 
2492
        return result