~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-04-15 08:20:33 UTC
  • mfrom: (4288.1.12 push.roundtrips)
  • Revision ID: pqm@pqm.ubuntu.com-20090415082033-tds4zs962x6kwc2c
(robertc) Add a Branch.set_parent_location verb and reduce lock
        churning to reduce network round trips. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
99
99
    def _open_hook(self):
100
100
        """Called by init to allow simpler extension of the base class."""
101
101
 
102
 
    def _activate_fallback_location(self, url):
 
102
    def _activate_fallback_location(self, url, lock_style):
103
103
        """Activate the branch/repository from url as a fallback repository."""
104
 
        self.repository.add_fallback_repository(
105
 
            self._get_fallback_repository(url))
 
104
        repo = self._get_fallback_repository(url)
 
105
        if lock_style == 'write':
 
106
            repo.lock_write()
 
107
        elif lock_style == 'read':
 
108
            repo.lock_read()
 
109
        self.repository.add_fallback_repository(repo)
106
110
 
107
111
    def break_lock(self):
108
112
        """Break a lock if one is present from another instance.
608
612
            url = urlutils.relative_url(self.base, url)
609
613
        self._set_parent_location(url)
610
614
 
 
615
    @needs_write_lock
611
616
    def set_stacked_on_url(self, url):
612
617
        """Set the URL this branch is stacked against.
613
618
 
626
631
                errors.UnstackableRepositoryFormat):
627
632
                return
628
633
            url = ''
 
634
            # XXX: Lock correctness - should unlock our old repo if we were
 
635
            # locked.
629
636
            # repositories don't offer an interface to remove fallback
630
637
            # repositories today; take the conceptually simpler option and just
631
638
            # reopen it.
632
639
            self.repository = self.bzrdir.find_repository()
 
640
            self.repository.lock_write()
633
641
            # for every revision reference the branch has, ensure it is pulled
634
642
            # in.
635
643
            source_repository = self._get_fallback_repository(old_url)
638
646
                self.repository.fetch(source_repository, revision_id,
639
647
                    find_ghosts=True)
640
648
        else:
641
 
            self._activate_fallback_location(url)
 
649
            self._activate_fallback_location(url, 'write')
642
650
        # write this out after the repository is stacked to avoid setting a
643
651
        # stacked config that doesn't work.
644
652
        self._set_config_location('stacked_on_location', url)
997
1005
                     be truncated to end with revision_id.
998
1006
        """
999
1007
        result = to_bzrdir.create_branch()
1000
 
        if repository_policy is not None:
1001
 
            repository_policy.configure_branch(result)
1002
 
        self.copy_content_into(result, revision_id=revision_id)
1003
 
        return  result
 
1008
        result.lock_write()
 
1009
        try:
 
1010
            if repository_policy is not None:
 
1011
                repository_policy.configure_branch(result)
 
1012
            self.copy_content_into(result, revision_id=revision_id)
 
1013
        finally:
 
1014
            result.unlock()
 
1015
        return result
1004
1016
 
1005
1017
    @needs_read_lock
1006
1018
    def sprout(self, to_bzrdir, revision_id=None, repository_policy=None):
1012
1024
                     be truncated to end with revision_id.
1013
1025
        """
1014
1026
        result = to_bzrdir.create_branch()
1015
 
        if repository_policy is not None:
1016
 
            repository_policy.configure_branch(result)
1017
 
        self.copy_content_into(result, revision_id=revision_id)
1018
 
        result.set_parent(self.bzrdir.root_transport.base)
 
1027
        result.lock_write()
 
1028
        try:
 
1029
            if repository_policy is not None:
 
1030
                repository_policy.configure_branch(result)
 
1031
            self.copy_content_into(result, revision_id=revision_id)
 
1032
            result.set_parent(self.bzrdir.root_transport.base)
 
1033
        finally:
 
1034
            result.unlock()
1019
1035
        return result
1020
1036
 
1021
1037
    def _synchronize_history(self, destination, revision_id):
1914
1930
        return self.control_files.is_locked()
1915
1931
 
1916
1932
    def lock_write(self, token=None):
1917
 
        repo_token = self.repository.lock_write()
 
1933
        # All-in-one needs to always unlock/lock.
 
1934
        repo_control = getattr(self.repository, 'control_files', None)
 
1935
        if self.control_files == repo_control or not self.is_locked():
 
1936
            self.repository.lock_write()
 
1937
            took_lock = True
 
1938
        else:
 
1939
            took_lock = False
1918
1940
        try:
1919
 
            token = self.control_files.lock_write(token=token)
 
1941
            return self.control_files.lock_write(token=token)
1920
1942
        except:
1921
 
            self.repository.unlock()
 
1943
            if took_lock:
 
1944
                self.repository.unlock()
1922
1945
            raise
1923
 
        return token
1924
1946
 
1925
1947
    def lock_read(self):
1926
 
        self.repository.lock_read()
 
1948
        # All-in-one needs to always unlock/lock.
 
1949
        repo_control = getattr(self.repository, 'control_files', None)
 
1950
        if self.control_files == repo_control or not self.is_locked():
 
1951
            self.repository.lock_read()
 
1952
            took_lock = True
 
1953
        else:
 
1954
            took_lock = False
1927
1955
        try:
1928
1956
            self.control_files.lock_read()
1929
1957
        except:
1930
 
            self.repository.unlock()
 
1958
            if took_lock:
 
1959
                self.repository.unlock()
1931
1960
            raise
1932
1961
 
1933
1962
    def unlock(self):
1934
 
        # TODO: test for failed two phase locks. This is known broken.
1935
1963
        try:
1936
1964
            self.control_files.unlock()
1937
1965
        finally:
1938
 
            self.repository.unlock()
1939
 
        if not self.control_files.is_locked():
1940
 
            # we just released the lock
1941
 
            self._clear_cached_state()
 
1966
            # All-in-one needs to always unlock/lock.
 
1967
            repo_control = getattr(self.repository, 'control_files', None)
 
1968
            if (self.control_files == repo_control or
 
1969
                not self.control_files.is_locked()):
 
1970
                self.repository.unlock()
 
1971
            if not self.control_files.is_locked():
 
1972
                # we just released the lock
 
1973
                self._clear_cached_state()
1942
1974
 
1943
1975
    def peek_lock_mode(self):
1944
1976
        if self.control_files._lock_count == 0:
2363
2395
                    raise AssertionError(
2364
2396
                        "'transform_fallback_location' hook %s returned "
2365
2397
                        "None, not a URL." % hook_name)
2366
 
            self._activate_fallback_location(url)
 
2398
            self._activate_fallback_location(url, None)
2367
2399
 
2368
2400
    def __init__(self, *args, **kwargs):
2369
2401
        self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)