~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-06 22:44:57 UTC
  • mfrom: (6436 +trunk)
  • mto: (6437.3.11 2.5)
  • mto: This revision was merged to the branch mainline in revision 6444.
  • Revision ID: jelmer@samba.org-20120106224457-re0pcy0fz31xob77
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
import bzrlib.bzrdir
18
20
 
19
21
from cStringIO import StringIO
46
48
from bzrlib.i18n import gettext, ngettext
47
49
""")
48
50
 
 
51
# Explicitly import bzrlib.bzrdir so that the BzrProber
 
52
# is guaranteed to be registered.
 
53
import bzrlib.bzrdir
 
54
 
49
55
from bzrlib import (
 
56
    bzrdir,
50
57
    controldir,
51
58
    )
52
59
from bzrlib.decorators import (
174
181
        For instance, if the branch is at URL/.bzr/branch,
175
182
        Branch.open(URL) -> a Branch instance.
176
183
        """
177
 
        control = controldir.ControlDir.open(base, _unsupported,
178
 
                                     possible_transports=possible_transports)
 
184
        control = controldir.ControlDir.open(base,
 
185
            possible_transports=possible_transports, _unsupported=_unsupported)
179
186
        return control.open_branch(unsupported=_unsupported,
180
187
            possible_transports=possible_transports)
181
188
 
663
670
        """
664
671
        if not self._format.supports_set_append_revisions_only():
665
672
            return False
666
 
        return self.get_config(
667
 
            ).get_user_option_as_bool('append_revisions_only')
 
673
        return self.get_config_stack().get('append_revisions_only')
668
674
 
669
675
    def set_append_revisions_only(self, enabled):
670
676
        if not self._format.supports_set_append_revisions_only():
671
677
            raise errors.UpgradeRequired(self.user_url)
672
 
        if enabled:
673
 
            value = 'True'
674
 
        else:
675
 
            value = 'False'
676
 
        self.get_config().set_user_option('append_revisions_only', value,
677
 
            warn_masked=True)
 
678
        self.get_config_stack().set('append_revisions_only', enabled)
678
679
 
679
680
    def set_reference_info(self, file_id, tree_path, branch_location):
680
681
        """Set the branch location to use for a tree reference."""
709
710
        """
710
711
        raise errors.UpgradeRequired(self.user_url)
711
712
 
712
 
    def get_commit_builder(self, parents, config=None, timestamp=None,
 
713
    def get_commit_builder(self, parents, config_stack=None, timestamp=None,
713
714
                           timezone=None, committer=None, revprops=None,
714
715
                           revision_id=None, lossy=False):
715
716
        """Obtain a CommitBuilder for this branch.
725
726
            represented, when pushing to a foreign VCS 
726
727
        """
727
728
 
728
 
        if config is None:
729
 
            config = self.get_config()
 
729
        if config_stack is None:
 
730
            config_stack = self.get_config_stack()
730
731
 
731
 
        return self.repository.get_commit_builder(self, parents, config,
 
732
        return self.repository.get_commit_builder(self, parents, config_stack,
732
733
            timestamp, timezone, committer, revprops, revision_id,
733
734
            lossy)
734
735
 
1169
1170
    def _set_config_location(self, name, url, config=None,
1170
1171
                             make_relative=False):
1171
1172
        if config is None:
1172
 
            config = self.get_config()
 
1173
            config = self.get_config_stack()
1173
1174
        if url is None:
1174
1175
            url = ''
1175
1176
        elif make_relative:
1176
1177
            url = urlutils.relative_url(self.base, url)
1177
 
        config.set_user_option(name, url, warn_masked=True)
 
1178
        config.set(name, url)
1178
1179
 
1179
1180
    def _get_config_location(self, name, config=None):
1180
1181
        if config is None:
1181
 
            config = self.get_config()
1182
 
        location = config.get_user_option(name)
 
1182
            config = self.get_config_stack()
 
1183
        location = config.get(name)
1183
1184
        if location == '':
1184
1185
            location = None
1185
1186
        return location
1186
1187
 
1187
1188
    def get_child_submit_format(self):
1188
1189
        """Return the preferred format of submissions to this branch."""
1189
 
        return self.get_config().get_user_option("child_submit_format")
 
1190
        return self.get_config_stack().get('child_submit_format')
1190
1191
 
1191
1192
    def get_submit_branch(self):
1192
1193
        """Return the submit location of the branch.
1195
1196
        pattern is that the user can override it by specifying a
1196
1197
        location.
1197
1198
        """
1198
 
        return self.get_config().get_user_option('submit_branch')
 
1199
        return self.get_config_stack().get('submit_branch')
1199
1200
 
1200
1201
    def set_submit_branch(self, location):
1201
1202
        """Return the submit location of the branch.
1204
1205
        pattern is that the user can override it by specifying a
1205
1206
        location.
1206
1207
        """
1207
 
        self.get_config().set_user_option('submit_branch', location,
1208
 
            warn_masked=True)
 
1208
        self.get_config_stack().set('submit_branch', location)
1209
1209
 
1210
1210
    def get_public_branch(self):
1211
1211
        """Return the public location of the branch.
1224
1224
        self._set_config_location('public_branch', location)
1225
1225
 
1226
1226
    def get_push_location(self):
1227
 
        """Return the None or the location to push this branch to."""
1228
 
        push_loc = self.get_config().get_user_option('push_location')
1229
 
        return push_loc
 
1227
        """Return None or the location to push this branch to."""
 
1228
        return self.get_config_stack().get('push_location')
1230
1229
 
1231
1230
    def set_push_location(self, location):
1232
1231
        """Set a new push location for this branch."""
1565
1564
            heads that must be fetched if present, but no error is necessary if
1566
1565
            they are not present.
1567
1566
        """
1568
 
        # For bzr native formats must_fetch is just the tip, and if_present_fetch
1569
 
        # are the tags.
 
1567
        # For bzr native formats must_fetch is just the tip, and
 
1568
        # if_present_fetch are the tags.
1570
1569
        must_fetch = set([self.last_revision()])
1571
1570
        if_present_fetch = set()
1572
 
        c = self.get_config()
1573
 
        include_tags = c.get_user_option_as_bool('branch.fetch_tags',
1574
 
                                                 default=False)
1575
 
        if include_tags:
 
1571
        if self.get_config_stack().get('branch.fetch_tags'):
1576
1572
            try:
1577
1573
                if_present_fetch = set(self.tags.get_reverse_tag_dict())
1578
1574
            except errors.TagsNotSupported:
1587
1583
 
1588
1584
    Formats provide three things:
1589
1585
     * An initialization routine,
1590
 
     * a format string,
 
1586
     * a format description
1591
1587
     * an open routine.
1592
1588
 
1593
1589
    Formats are placed in an dict by their format string for reference
1999
1995
            self.revision_id)
2000
1996
 
2001
1997
 
2002
 
class BranchFormatMetadir(bzrdir.BzrDirMetaComponentFormat, BranchFormat):
 
1998
class BranchFormatMetadir(bzrdir.BzrFormat, BranchFormat):
2003
1999
    """Base class for branch formats that live in meta directories.
2004
2000
    """
2005
2001
 
2006
2002
    def __init__(self):
2007
2003
        BranchFormat.__init__(self)
2008
 
        bzrdir.BzrDirMetaComponentFormat.__init__(self)
 
2004
        bzrdir.BzrFormat.__init__(self)
2009
2005
 
2010
2006
    @classmethod
2011
2007
    def find_format(klass, controldir, name=None):
2049
2045
        control_files.create_lock()
2050
2046
        control_files.lock_write()
2051
2047
        try:
2052
 
            utf8_files += [('format', self.get_format_string())]
 
2048
            utf8_files += [('format', self.as_string())]
2053
2049
            for (filename, content) in utf8_files:
2054
2050
                branch_transport.put_bytes(
2055
2051
                    filename, content,
2097
2093
    def supports_leaving_lock(self):
2098
2094
        return True
2099
2095
 
 
2096
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
 
2097
            basedir=None):
 
2098
        BranchFormat.check_support_status(self,
 
2099
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
 
2100
            basedir=basedir)
 
2101
        bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
 
2102
            recommend_upgrade=recommend_upgrade, basedir=basedir)
 
2103
 
2100
2104
 
2101
2105
class BzrBranchFormat5(BranchFormatMetadir):
2102
2106
    """Bzr branch format 5.
2304
2308
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2305
2309
        branch_transport.put_bytes('location',
2306
2310
            target_branch.user_url)
2307
 
        branch_transport.put_bytes('format', self.get_format_string())
 
2311
        branch_transport.put_bytes('format', self.as_string())
2308
2312
        branch = self.open(
2309
2313
            a_bzrdir, name, _found=True,
2310
2314
            possible_transports=[target_branch.bzrdir.root_transport])
2712
2716
        self._transport.put_bytes('last-revision', out_string,
2713
2717
            mode=self.bzrdir._get_file_mode())
2714
2718
 
 
2719
    @needs_write_lock
 
2720
    def update_feature_flags(self, updated_flags):
 
2721
        """Update the feature flags for this branch.
 
2722
 
 
2723
        :param updated_flags: Dictionary mapping feature names to necessities
 
2724
            A necessity can be None to indicate the feature should be removed
 
2725
        """
 
2726
        self._format._update_feature_flags(updated_flags)
 
2727
        self.control_transport.put_bytes('format', self._format.as_string())
 
2728
 
2715
2729
 
2716
2730
class FullHistoryBzrBranch(BzrBranch):
2717
2731
    """Bzr branch which contains the full revision history."""
2967
2981
        """See Branch.set_push_location."""
2968
2982
        self._master_branch_cache = None
2969
2983
        result = None
2970
 
        config = self.get_config()
 
2984
        conf = self.get_config_stack()
2971
2985
        if location is None:
2972
 
            if config.get_user_option('bound') != 'True':
 
2986
            if not conf.get('bound'):
2973
2987
                return False
2974
2988
            else:
2975
 
                config.set_user_option('bound', 'False', warn_masked=True)
 
2989
                conf.set('bound', 'False')
2976
2990
                return True
2977
2991
        else:
2978
2992
            self._set_config_location('bound_location', location,
2979
 
                                      config=config)
2980
 
            config.set_user_option('bound', 'True', warn_masked=True)
 
2993
                                      config=conf)
 
2994
            conf.set('bound', 'True')
2981
2995
        return True
2982
2996
 
2983
2997
    def _get_bound_location(self, bound):
2984
2998
        """Return the bound location in the config file.
2985
2999
 
2986
3000
        Return None if the bound parameter does not match"""
2987
 
        config = self.get_config()
2988
 
        config_bound = (config.get_user_option('bound') == 'True')
2989
 
        if config_bound != bound:
 
3001
        conf = self.get_config_stack()
 
3002
        if conf.get('bound') != bound:
2990
3003
            return None
2991
 
        return self._get_config_location('bound_location', config=config)
 
3004
        return self._get_config_location('bound_location', config=conf)
2992
3005
 
2993
3006
    def get_bound_location(self):
2994
 
        """See Branch.set_push_location."""
 
3007
        """See Branch.get_bound_location."""
2995
3008
        return self._get_bound_location(True)
2996
3009
 
2997
3010
    def get_old_bound_location(self):
3004
3017
        ## self._check_stackable_repo()
3005
3018
        # stacked_on_location is only ever defined in branch.conf, so don't
3006
3019
        # waste effort reading the whole stack of config files.
3007
 
        config = self.get_config()._get_branch_data_config()
 
3020
        conf = _mod_config.BranchOnlyStack(self)
3008
3021
        stacked_url = self._get_config_location('stacked_on_location',
3009
 
            config=config)
 
3022
                                                config=conf)
3010
3023
        if stacked_url is None:
3011
3024
            raise errors.NotStacked(self)
3012
 
        return stacked_url
 
3025
        return stacked_url.encode('utf-8')
3013
3026
 
3014
3027
    @needs_read_lock
3015
3028
    def get_rev_id(self, revno, history=None):
3219
3232
 
3220
3233
        # Copying done; now update target format
3221
3234
        new_branch._transport.put_bytes('format',
3222
 
            format.get_format_string(),
 
3235
            format.as_string(),
3223
3236
            mode=new_branch.bzrdir._get_file_mode())
3224
3237
 
3225
3238
        # Clean up old files
3238
3251
        format = BzrBranchFormat7()
3239
3252
        branch._set_config_location('stacked_on_location', '')
3240
3253
        # update target format
3241
 
        branch._transport.put_bytes('format', format.get_format_string())
 
3254
        branch._transport.put_bytes('format', format.as_string())
3242
3255
 
3243
3256
 
3244
3257
class Converter7to8(object):
3248
3261
        format = BzrBranchFormat8()
3249
3262
        branch._transport.put_bytes('references', '')
3250
3263
        # update target format
3251
 
        branch._transport.put_bytes('format', format.get_format_string())
 
3264
        branch._transport.put_bytes('format', format.as_string())
3252
3265
 
3253
3266
 
3254
3267
class InterBranch(InterObject):