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
17
from __future__ import absolute_import
17
19
import bzrlib.bzrdir
19
21
from cStringIO import StringIO
46
48
from bzrlib.i18n import gettext, ngettext
51
# Explicitly import bzrlib.bzrdir so that the BzrProber
52
# is guaranteed to be registered.
49
55
from bzrlib import (
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.
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)
664
671
if not self._format.supports_set_append_revisions_only():
666
return self.get_config(
667
).get_user_option_as_bool('append_revisions_only')
673
return self.get_config_stack().get('append_revisions_only')
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)
676
self.get_config().set_user_option('append_revisions_only', value,
678
self.get_config_stack().set('append_revisions_only', enabled)
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."""
710
711
raise errors.UpgradeRequired(self.user_url)
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
729
config = self.get_config()
729
if config_stack is None:
730
config_stack = self.get_config_stack()
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,
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:
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)
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
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')
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
1198
return self.get_config().get_user_option('submit_branch')
1199
return self.get_config_stack().get('submit_branch')
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
1207
self.get_config().set_user_option('submit_branch', location,
1208
self.get_config_stack().set('submit_branch', location)
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)
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')
1227
"""Return None or the location to push this branch to."""
1228
return self.get_config_stack().get('push_location')
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.
1568
# For bzr native formats must_fetch is just the tip, and if_present_fetch
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',
1571
if self.get_config_stack().get('branch.fetch_tags'):
1577
1573
if_present_fetch = set(self.tags.get_reverse_tag_dict())
1578
1574
except errors.TagsNotSupported:
1999
1995
self.revision_id)
2002
class BranchFormatMetadir(bzrdir.BzrDirMetaComponentFormat, BranchFormat):
1998
class BranchFormatMetadir(bzrdir.BzrFormat, BranchFormat):
2003
1999
"""Base class for branch formats that live in meta directories.
2006
2002
def __init__(self):
2007
2003
BranchFormat.__init__(self)
2008
bzrdir.BzrDirMetaComponentFormat.__init__(self)
2004
bzrdir.BzrFormat.__init__(self)
2011
2007
def find_format(klass, controldir, name=None):
2049
2045
control_files.create_lock()
2050
2046
control_files.lock_write()
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):
2096
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
2098
BranchFormat.check_support_status(self,
2099
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
2101
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
2102
recommend_upgrade=recommend_upgrade, basedir=basedir)
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())
2720
def update_feature_flags(self, updated_flags):
2721
"""Update the feature flags for this branch.
2723
:param updated_flags: Dictionary mapping feature names to necessities
2724
A necessity can be None to indicate the feature should be removed
2726
self._format._update_feature_flags(updated_flags)
2727
self.control_transport.put_bytes('format', self._format.as_string())
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
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'):
2975
config.set_user_option('bound', 'False', warn_masked=True)
2989
conf.set('bound', 'False')
2978
2992
self._set_config_location('bound_location', location,
2980
config.set_user_option('bound', 'True', warn_masked=True)
2994
conf.set('bound', 'True')
2983
2997
def _get_bound_location(self, bound):
2984
2998
"""Return the bound location in the config file.
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:
2991
return self._get_config_location('bound_location', config=config)
3004
return self._get_config_location('bound_location', config=conf)
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)
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',
3010
3023
if stacked_url is None:
3011
3024
raise errors.NotStacked(self)
3025
return stacked_url.encode('utf-8')
3014
3027
@needs_read_lock
3015
3028
def get_rev_id(self, revno, history=None):
3220
3233
# Copying done; now update target format
3221
3234
new_branch._transport.put_bytes('format',
3222
format.get_format_string(),
3223
3236
mode=new_branch.bzrdir._get_file_mode())
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())
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())
3254
3267
class InterBranch(InterObject):