253
252
raise NotImplementedError(self._get_config)
255
def store_uncommitted(self, creator):
256
"""Store uncommitted changes from a ShelfCreator.
258
:param creator: The ShelfCreator containing uncommitted changes, or
259
None to delete any stored changes.
260
:raises: ChangesAlreadyStored if the branch already has changes.
262
raise NotImplementedError(self.store_uncommitted)
264
def get_unshelver(self, tree):
265
"""Return a shelf.Unshelver for this branch and tree.
267
:param tree: The tree to use to construct the Unshelver.
268
:return: an Unshelver or None if no changes are stored.
270
raise NotImplementedError(self.get_unshelver)
272
254
def _get_fallback_repository(self, url, possible_transports):
273
255
"""Get the repository we fallback to at url."""
274
256
url = urlutils.join(self.base, url)
784
766
"""Print `file` to stdout."""
785
767
raise NotImplementedError(self.print_file)
769
@deprecated_method(deprecated_in((2, 4, 0)))
770
def set_revision_history(self, rev_history):
771
"""See Branch.set_revision_history."""
772
self._set_revision_history(rev_history)
775
def _set_revision_history(self, rev_history):
776
if len(rev_history) == 0:
777
revid = _mod_revision.NULL_REVISION
779
revid = rev_history[-1]
780
if rev_history != self._lefthand_history(revid):
781
raise errors.NotLefthandHistory(rev_history)
782
self.set_last_revision_info(len(rev_history), revid)
783
self._cache_revision_history(rev_history)
784
for hook in Branch.hooks['set_rh']:
785
hook(self, rev_history)
787
787
@needs_write_lock
788
788
def set_last_revision_info(self, revno, revision_id):
789
789
"""Set the last revision of this branch.
1052
1062
def _read_last_revision_info(self):
1053
1063
raise NotImplementedError(self._read_last_revision_info)
1065
@deprecated_method(deprecated_in((2, 4, 0)))
1066
def import_last_revision_info(self, source_repo, revno, revid):
1067
"""Set the last revision info, importing from another repo if necessary.
1069
:param source_repo: Source repository to optionally fetch from
1070
:param revno: Revision number of the new tip
1071
:param revid: Revision id of the new tip
1073
if not self.repository.has_same_location(source_repo):
1074
self.repository.fetch(source_repo, revision_id=revid)
1075
self.set_last_revision_info(revno, revid)
1055
1077
def import_last_revision_info_and_tags(self, source, revno, revid,
1057
1079
"""Set the last revision info, importing from another repo if necessary.
1435
1457
t = transport.get_transport(to_location)
1436
1458
t.ensure_base()
1437
1459
format = self._get_checkout_format(lightweight=lightweight)
1439
1461
checkout = format.initialize_on_transport(t)
1440
except errors.AlreadyControlDirError:
1441
# It's fine if the control directory already exists,
1442
# as long as there is no existing branch and working tree.
1443
checkout = controldir.ControlDir.open_from_transport(t)
1445
checkout.open_branch()
1446
except errors.NotBranchError:
1449
raise errors.AlreadyControlDirError(t.base)
1450
if checkout.control_transport.base == self.bzrdir.control_transport.base:
1451
# When checking out to the same control directory,
1452
# always create a lightweight checkout
1456
from_branch = checkout.set_branch_reference(target_branch=self)
1462
from_branch = BranchReferenceFormat().initialize(checkout,
1458
policy = checkout.determine_repository_policy()
1459
repo = policy.acquire_repository()[0]
1460
checkout_branch = checkout.create_branch()
1465
checkout_branch = controldir.ControlDir.create_branch_convenience(
1466
to_location, force_new_tree=False, format=format)
1467
checkout = checkout_branch.bzrdir
1461
1468
checkout_branch.bind(self)
1462
1469
# pull up to the specified revision_id to set the initial
1463
1470
# branch tip correctly, and seed it with history.
1464
1471
checkout_branch.pull(self, stop_revision=revision_id)
1466
1473
tree = checkout.create_workingtree(revision_id,
1467
1474
from_branch=from_branch,
1468
1475
accelerator_tree=accelerator_tree,
1595
1602
def __ne__(self, other):
1596
1603
return not (self == other)
1606
@deprecated_method(deprecated_in((2, 4, 0)))
1607
def get_default_format(klass):
1608
"""Return the current default format."""
1609
return format_registry.get_default()
1612
@deprecated_method(deprecated_in((2, 4, 0)))
1613
def get_formats(klass):
1614
"""Get all the known formats.
1616
Warning: This triggers a load of all lazy registered formats: do not
1617
use except when that is desireed.
1619
return format_registry._get_all()
1598
1621
def get_reference(self, controldir, name=None):
1599
1622
"""Get the target reference of the branch in controldir.
1689
1712
raise NotImplementedError(self.open)
1715
@deprecated_method(deprecated_in((2, 4, 0)))
1716
def register_format(klass, format):
1717
"""Register a metadir format.
1719
See MetaDirBranchFormatFactory for the ability to register a format
1720
without loading the code the format needs until it is actually used.
1722
format_registry.register(format)
1725
@deprecated_method(deprecated_in((2, 4, 0)))
1726
def set_default_format(klass, format):
1727
format_registry.set_default(format)
1691
1729
def supports_set_append_revisions_only(self):
1692
1730
"""True if this format supports set_append_revisions_only."""
2057
2102
recommend_upgrade=recommend_upgrade, basedir=basedir)
2105
class BzrBranchFormat5(BranchFormatMetadir):
2106
"""Bzr branch format 5.
2109
- a revision-history file.
2111
- a lock dir guarding the branch itself
2112
- all of this stored in a branch/ subdirectory
2113
- works with shared repositories.
2115
This format is new in bzr 0.8.
2118
def _branch_class(self):
2122
def get_format_string(cls):
2123
"""See BranchFormat.get_format_string()."""
2124
return "Bazaar-NG branch format 5\n"
2126
def get_format_description(self):
2127
"""See BranchFormat.get_format_description()."""
2128
return "Branch format 5"
2130
def initialize(self, a_bzrdir, name=None, repository=None,
2131
append_revisions_only=None):
2132
"""Create a branch of this format in a_bzrdir."""
2133
if append_revisions_only:
2134
raise errors.UpgradeRequired(a_bzrdir.user_url)
2135
utf8_files = [('revision-history', ''),
2136
('branch-name', ''),
2138
return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
2140
def supports_tags(self):
2060
2144
class BzrBranchFormat6(BranchFormatMetadir):
2061
2145
"""Branch format with last-revision and tags.
2221
2305
mutter('creating branch reference in %s', a_bzrdir.user_url)
2222
2306
if a_bzrdir._format.fixed_components:
2223
2307
raise errors.IncompatibleFormat(self, a_bzrdir._format)
2225
name = a_bzrdir._get_selected_branch()
2226
2308
branch_transport = a_bzrdir.get_branch_transport(self, name=name)
2227
2309
branch_transport.put_bytes('location',
2228
2310
target_branch.user_url)
2229
2311
branch_transport.put_bytes('format', self.as_string())
2230
branch = self.open(a_bzrdir, name, _found=True,
2313
a_bzrdir, name, _found=True,
2231
2314
possible_transports=[target_branch.bzrdir.root_transport])
2232
2315
self._run_post_branch_init_hooks(a_bzrdir, name, branch)
2404
2485
self.conf_store = _mod_config.BranchStore(self)
2405
2486
return self.conf_store
2407
def _uncommitted_branch(self):
2408
"""Return the branch that may contain uncommitted changes."""
2409
master = self.get_master_branch()
2410
if master is not None:
2415
def store_uncommitted(self, creator):
2416
"""Store uncommitted changes from a ShelfCreator.
2418
:param creator: The ShelfCreator containing uncommitted changes, or
2419
None to delete any stored changes.
2420
:raises: ChangesAlreadyStored if the branch already has changes.
2422
branch = self._uncommitted_branch()
2424
branch._transport.delete('stored-transform')
2426
if branch._transport.has('stored-transform'):
2427
raise errors.ChangesAlreadyStored
2428
transform = StringIO()
2429
creator.write_shelf(transform)
2431
branch._transport.put_file('stored-transform', transform)
2433
def get_unshelver(self, tree):
2434
"""Return a shelf.Unshelver for this branch and tree.
2436
:param tree: The tree to use to construct the Unshelver.
2437
:return: an Unshelver or None if no changes are stored.
2439
branch = self._uncommitted_branch()
2441
transform = branch._transport.get('stored-transform')
2442
except errors.NoSuchFile:
2444
return shelf.Unshelver.from_tree_and_shelf(tree, transform)
2446
2488
def is_locked(self):
2447
2489
return self.control_files.is_locked()
2680
2732
self.control_transport.put_bytes('format', self._format.as_string())
2735
class FullHistoryBzrBranch(BzrBranch):
2736
"""Bzr branch which contains the full revision history."""
2739
def set_last_revision_info(self, revno, revision_id):
2740
if not revision_id or not isinstance(revision_id, basestring):
2741
raise errors.InvalidRevisionId(revision_id=revision_id, branch=self)
2742
revision_id = _mod_revision.ensure_null(revision_id)
2743
# this old format stores the full history, but this api doesn't
2744
# provide it, so we must generate, and might as well check it's
2746
history = self._lefthand_history(revision_id)
2747
if len(history) != revno:
2748
raise AssertionError('%d != %d' % (len(history), revno))
2749
self._set_revision_history(history)
2751
def _read_last_revision_info(self):
2752
rh = self._revision_history()
2755
return (revno, rh[-1])
2757
return (0, _mod_revision.NULL_REVISION)
2759
@deprecated_method(deprecated_in((2, 4, 0)))
2761
def set_revision_history(self, rev_history):
2762
"""See Branch.set_revision_history."""
2763
self._set_revision_history(rev_history)
2765
def _set_revision_history(self, rev_history):
2766
if 'evil' in debug.debug_flags:
2767
mutter_callsite(3, "set_revision_history scales with history.")
2768
check_not_reserved_id = _mod_revision.check_not_reserved_id
2769
for rev_id in rev_history:
2770
check_not_reserved_id(rev_id)
2771
if Branch.hooks['post_change_branch_tip']:
2772
# Don't calculate the last_revision_info() if there are no hooks
2774
old_revno, old_revid = self.last_revision_info()
2775
if len(rev_history) == 0:
2776
revid = _mod_revision.NULL_REVISION
2778
revid = rev_history[-1]
2779
self._run_pre_change_branch_tip_hooks(len(rev_history), revid)
2780
self._write_revision_history(rev_history)
2781
self._clear_cached_state()
2782
self._cache_revision_history(rev_history)
2783
for hook in Branch.hooks['set_rh']:
2784
hook(self, rev_history)
2785
if Branch.hooks['post_change_branch_tip']:
2786
self._run_post_change_branch_tip_hooks(old_revno, old_revid)
2788
def _write_revision_history(self, history):
2789
"""Factored out of set_revision_history.
2791
This performs the actual writing to disk.
2792
It is intended to be called by set_revision_history."""
2793
self._transport.put_bytes(
2794
'revision-history', '\n'.join(history),
2795
mode=self.bzrdir._get_file_mode())
2797
def _gen_revision_history(self):
2798
history = self._transport.get_bytes('revision-history').split('\n')
2799
if history[-1:] == ['']:
2800
# There shouldn't be a trailing newline, but just in case.
2804
def _synchronize_history(self, destination, revision_id):
2805
if not isinstance(destination, FullHistoryBzrBranch):
2806
super(BzrBranch, self)._synchronize_history(
2807
destination, revision_id)
2809
if revision_id == _mod_revision.NULL_REVISION:
2812
new_history = self._revision_history()
2813
if revision_id is not None and new_history != []:
2815
new_history = new_history[:new_history.index(revision_id) + 1]
2817
rev = self.repository.get_revision(revision_id)
2818
new_history = rev.get_history(self.repository)[1:]
2819
destination._set_revision_history(new_history)
2822
def generate_revision_history(self, revision_id, last_rev=None,
2824
"""Create a new revision history that will finish with revision_id.
2826
:param revision_id: the new tip to use.
2827
:param last_rev: The previous last_revision. If not None, then this
2828
must be a ancestory of revision_id, or DivergedBranches is raised.
2829
:param other_branch: The other branch that DivergedBranches should
2830
raise with respect to.
2832
self._set_revision_history(self._lefthand_history(revision_id,
2833
last_rev, other_branch))
2836
class BzrBranch5(FullHistoryBzrBranch):
2837
"""A format 5 branch. This supports new features over plain branches.
2839
It has support for a master_branch which is the data for bound branches.
2683
2843
class BzrBranch8(BzrBranch):
2684
2844
"""A branch that stores tree-reference locations."""
3340
3507
result.target_branch = self.target
3341
3508
result.old_revno, result.old_revid = self.target.last_revision_info()
3342
3509
self.source.update_references(self.target)
3343
overwrite = _fix_overwrite_type(overwrite)
3344
3510
if result.old_revid != stop_revision:
3345
3511
# We assume that during 'push' this repository is closer than
3347
3513
graph = self.source.repository.get_graph(self.target.repository)
3348
self._update_revisions(stop_revision,
3349
overwrite=("history" in overwrite),
3514
self._update_revisions(stop_revision, overwrite=overwrite,
3351
3516
if self.source._push_should_merge_tags():
3352
3517
result.tag_updates, result.tag_conflicts = (
3353
self.source.tags.merge_to(
3354
self.target.tags, "tags" in overwrite))
3518
self.source.tags.merge_to(self.target.tags, overwrite))
3355
3519
result.new_revno, result.new_revid = self.target.last_revision_info()
3435
3599
# -- JRV20090506
3436
3600
result.old_revno, result.old_revid = \
3437
3601
self.target.last_revision_info()
3438
overwrite = _fix_overwrite_type(overwrite)
3439
self._update_revisions(stop_revision,
3440
overwrite=("history" in overwrite),
3602
self._update_revisions(stop_revision, overwrite=overwrite,
3442
3604
# TODO: The old revid should be specified when merging tags,
3443
3605
# so a tags implementation that versions tags can only
3444
3606
# pull in the most recent changes. -- JRV20090506
3445
3607
result.tag_updates, result.tag_conflicts = (
3446
self.source.tags.merge_to(self.target.tags,
3447
"tags" in overwrite,
3608
self.source.tags.merge_to(self.target.tags, overwrite,
3448
3609
ignore_master=not merge_tags_to_master))
3449
3610
result.new_revno, result.new_revid = self.target.last_revision_info()
3450
3611
if _hook_master: