~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Robert J. Tanner
  • Date: 2009-04-20 08:37:32 UTC
  • mfrom: (4299 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4300.
  • Revision ID: tanner@real-time.com-20090420083732-bzx919oo7wpmqc2u
[merge] 1.14rc2 back into bzr.dev (Bob Tanner)

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.
590
594
    def set_revision_history(self, rev_history):
591
595
        raise NotImplementedError(self.set_revision_history)
592
596
 
 
597
    @needs_write_lock
 
598
    def set_parent(self, url):
 
599
        """See Branch.set_parent."""
 
600
        # TODO: Maybe delete old location files?
 
601
        # URLs should never be unicode, even on the local fs,
 
602
        # FIXUP this and get_parent in a future branch format bump:
 
603
        # read and rewrite the file. RBC 20060125
 
604
        if url is not None:
 
605
            if isinstance(url, unicode):
 
606
                try:
 
607
                    url = url.encode('ascii')
 
608
                except UnicodeEncodeError:
 
609
                    raise errors.InvalidURL(url,
 
610
                        "Urls must be 7-bit ascii, "
 
611
                        "use bzrlib.urlutils.escape")
 
612
            url = urlutils.relative_url(self.base, url)
 
613
        self._set_parent_location(url)
 
614
 
 
615
    @needs_write_lock
593
616
    def set_stacked_on_url(self, url):
594
617
        """Set the URL this branch is stacked against.
595
618
 
608
631
                errors.UnstackableRepositoryFormat):
609
632
                return
610
633
            url = ''
 
634
            # XXX: Lock correctness - should unlock our old repo if we were
 
635
            # locked.
611
636
            # repositories don't offer an interface to remove fallback
612
637
            # repositories today; take the conceptually simpler option and just
613
638
            # reopen it.
614
639
            self.repository = self.bzrdir.find_repository()
 
640
            self.repository.lock_write()
615
641
            # for every revision reference the branch has, ensure it is pulled
616
642
            # in.
617
643
            source_repository = self._get_fallback_repository(old_url)
620
646
                self.repository.fetch(source_repository, revision_id,
621
647
                    find_ghosts=True)
622
648
        else:
623
 
            self._activate_fallback_location(url)
 
649
            self._activate_fallback_location(url, 'write')
624
650
        # write this out after the repository is stacked to avoid setting a
625
651
        # stacked config that doesn't work.
626
652
        self._set_config_location('stacked_on_location', url)
944
970
                raise errors.HookFailed(
945
971
                    'pre_change_branch_tip', hook_name, exc_info)
946
972
 
947
 
    def set_parent(self, url):
948
 
        raise NotImplementedError(self.set_parent)
949
 
 
950
973
    @needs_write_lock
951
974
    def update(self):
952
975
        """Synchronise this branch with the master branch if any.
982
1005
                     be truncated to end with revision_id.
983
1006
        """
984
1007
        result = to_bzrdir.create_branch()
985
 
        if repository_policy is not None:
986
 
            repository_policy.configure_branch(result)
987
 
        self.copy_content_into(result, revision_id=revision_id)
988
 
        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
989
1016
 
990
1017
    @needs_read_lock
991
1018
    def sprout(self, to_bzrdir, revision_id=None, repository_policy=None):
997
1024
                     be truncated to end with revision_id.
998
1025
        """
999
1026
        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
 
        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()
1004
1035
        return result
1005
1036
 
1006
1037
    def _synchronize_history(self, destination, revision_id):
1899
1930
        return self.control_files.is_locked()
1900
1931
 
1901
1932
    def lock_write(self, token=None):
1902
 
        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
1903
1940
        try:
1904
 
            token = self.control_files.lock_write(token=token)
 
1941
            return self.control_files.lock_write(token=token)
1905
1942
        except:
1906
 
            self.repository.unlock()
 
1943
            if took_lock:
 
1944
                self.repository.unlock()
1907
1945
            raise
1908
 
        return token
1909
1946
 
1910
1947
    def lock_read(self):
1911
 
        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
1912
1955
        try:
1913
1956
            self.control_files.lock_read()
1914
1957
        except:
1915
 
            self.repository.unlock()
 
1958
            if took_lock:
 
1959
                self.repository.unlock()
1916
1960
            raise
1917
1961
 
1918
1962
    def unlock(self):
1919
 
        # TODO: test for failed two phase locks. This is known broken.
1920
1963
        try:
1921
1964
            self.control_files.unlock()
1922
1965
        finally:
1923
 
            self.repository.unlock()
1924
 
        if not self.control_files.is_locked():
1925
 
            # we just released the lock
1926
 
            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()
1927
1974
 
1928
1975
    def peek_lock_mode(self):
1929
1976
        if self.control_files._lock_count == 0:
2194
2241
            'push_location', location,
2195
2242
            store=_mod_config.STORE_LOCATION_NORECURSE)
2196
2243
 
2197
 
    @needs_write_lock
2198
 
    def set_parent(self, url):
2199
 
        """See Branch.set_parent."""
2200
 
        # TODO: Maybe delete old location files?
2201
 
        # URLs should never be unicode, even on the local fs,
2202
 
        # FIXUP this and get_parent in a future branch format bump:
2203
 
        # read and rewrite the file. RBC 20060125
2204
 
        if url is not None:
2205
 
            if isinstance(url, unicode):
2206
 
                try:
2207
 
                    url = url.encode('ascii')
2208
 
                except UnicodeEncodeError:
2209
 
                    raise errors.InvalidURL(url,
2210
 
                        "Urls must be 7-bit ascii, "
2211
 
                        "use bzrlib.urlutils.escape")
2212
 
            url = urlutils.relative_url(self.base, url)
2213
 
        self._set_parent_location(url)
2214
 
 
2215
2244
    def _set_parent_location(self, url):
2216
2245
        if url is None:
2217
2246
            self._transport.delete('parent')
2366
2395
                    raise AssertionError(
2367
2396
                        "'transform_fallback_location' hook %s returned "
2368
2397
                        "None, not a URL." % hook_name)
2369
 
            self._activate_fallback_location(url)
 
2398
            self._activate_fallback_location(url, None)
2370
2399
 
2371
2400
    def __init__(self, *args, **kwargs):
2372
2401
        self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)