347
347
raise NotImplementedError(self.set_revision_history)
349
349
def set_stacked_on(self, url):
350
"""set the URL this branch is stacked against.
350
"""Set the URL this branch is stacked against.
352
352
:raises UnstackableBranchFormat: If the branch does not support
473
473
raise errors.NoSuchRevision(self, stop_revision)
474
474
return other_history[self_len:stop_revision]
476
477
def update_revisions(self, other, stop_revision=None, overwrite=False,
478
479
"""Pull in new perfect-fit revisions.
485
486
information. This can be None.
488
raise NotImplementedError(self.update_revisions)
491
other_revno, other_last_revision = other.last_revision_info()
492
stop_revno = None # unknown
493
if stop_revision is None:
494
stop_revision = other_last_revision
495
if _mod_revision.is_null(stop_revision):
496
# if there are no commits, we're done.
498
stop_revno = other_revno
500
# what's the current last revision, before we fetch [and change it
502
last_rev = _mod_revision.ensure_null(self.last_revision())
503
# we fetch here so that we don't process data twice in the common
504
# case of having something to pull, and so that the check for
505
# already merged can operate on the just fetched graph, which will
506
# be cached in memory.
507
self.fetch(other, stop_revision)
508
# Check to see if one is an ancestor of the other
511
graph = self.repository.get_graph()
512
heads = graph.heads([stop_revision, last_rev])
513
if heads == set([last_rev]):
514
# The current revision is a decendent of the target,
517
elif heads == set([stop_revision, last_rev]):
518
# These branches have diverged
519
raise errors.DivergedBranches(self, other)
520
elif heads != set([stop_revision]):
521
raise AssertionError("invalid heads: %r" % heads)
522
if stop_revno is None:
524
graph = self.repository.get_graph()
525
this_revno, this_last_revision = self.last_revision_info()
526
stop_revno = graph.find_distance_to_null(stop_revision,
527
[(other_last_revision, other_revno),
528
(this_last_revision, this_revno)])
529
self.set_last_revision_info(stop_revno, stop_revision)
490
535
def revision_id_to_revno(self, revision_id):
491
536
"""Given a revision id, return its revno"""
944
989
for (filename, content) in utf8_files:
945
990
branch_transport.put_bytes(
946
991
filename, content,
947
mode=control_files._file_mode)
992
mode=a_bzrdir._get_file_mode())
949
994
control_files.unlock()
950
995
return self.open(a_bzrdir, _found=True)
1143
1188
raise NotImplementedError(self._branch_class)
1145
1190
def open(self, a_bzrdir, _found=False):
1146
"""Return the branch object for a_bzrdir
1191
"""Return the branch object for a_bzrdir.
1148
1193
_found is a private parameter, do not use it. It is used to indicate
1149
1194
if format probing has already be done.
1473
1517
It is intended to be called by BzrBranch5.set_revision_history."""
1474
1518
self._transport.put_bytes(
1475
1519
'revision-history', '\n'.join(history),
1476
mode=self.control_files._file_mode)
1520
mode=self.bzrdir._get_file_mode())
1478
1522
@needs_write_lock
1479
1523
def set_revision_history(self, rev_history):
1566
1610
self.set_revision_history(self._lefthand_history(revision_id,
1567
1611
last_rev, other_branch))
1570
def update_revisions(self, other, stop_revision=None, overwrite=False,
1572
"""See Branch.update_revisions."""
1575
other_revno, other_last_revision = other.last_revision_info()
1576
stop_revno = None # unknown
1577
if stop_revision is None:
1578
stop_revision = other_last_revision
1579
if _mod_revision.is_null(stop_revision):
1580
# if there are no commits, we're done.
1582
stop_revno = other_revno
1584
# what's the current last revision, before we fetch [and change it
1586
last_rev = _mod_revision.ensure_null(self.last_revision())
1587
# we fetch here so that we don't process data twice in the common
1588
# case of having something to pull, and so that the check for
1589
# already merged can operate on the just fetched graph, which will
1590
# be cached in memory.
1591
self.fetch(other, stop_revision)
1592
# Check to see if one is an ancestor of the other
1595
graph = self.repository.get_graph()
1596
heads = graph.heads([stop_revision, last_rev])
1597
if heads == set([last_rev]):
1598
# The current revision is a decendent of the target,
1601
elif heads == set([stop_revision, last_rev]):
1602
# These branches have diverged
1603
raise errors.DivergedBranches(self, other)
1604
elif heads != set([stop_revision]):
1605
raise AssertionError("invalid heads: %r" % heads)
1606
if stop_revno is None:
1608
graph = self.repository.get_graph()
1609
this_revno, this_last_revision = self.last_revision_info()
1610
stop_revno = graph.find_distance_to_null(stop_revision,
1611
[(other_last_revision, other_revno),
1612
(this_last_revision, this_revno)])
1613
self.set_last_revision_info(stop_revno, stop_revision)
1617
1613
def basis_tree(self):
1618
1614
"""See Branch.basis_tree."""
1619
1615
return self.repository.revision_tree(self.last_revision())
1798
1794
self._transport.delete('parent')
1800
1796
self._transport.put_bytes('parent', url + '\n',
1801
mode=self.control_files._file_mode)
1797
mode=self.bzrdir._get_file_mode())
1803
1799
def set_stacked_on(self, url):
1804
1800
raise errors.UnstackableBranchFormat(self._format, self.base)
1993
1989
revision_id = _mod_revision.ensure_null(revision_id)
1994
1990
out_string = '%d %s\n' % (revno, revision_id)
1995
1991
self._transport.put_bytes('last-revision', out_string,
1996
mode=self.control_files._file_mode)
1992
mode=self.bzrdir._get_file_mode())
1998
1994
@needs_write_lock
1999
1995
def set_last_revision_info(self, revno, revision_id):
2115
2111
def get_stacked_on(self):
2116
2112
self._check_stackable_repo()
2117
stacked_url_str = self._transport.get_bytes('stacked-on')
2118
stacked_url = stacked_url_str.decode('utf_8').rstrip('\n')
2113
stacked_url = self._get_config_location('stacked_on_location')
2114
if stacked_url is None:
2120
2115
raise errors.NotStacked(self)
2121
2116
return stacked_url
2146
2141
source_repository = self._get_fallback_repository(old_url)
2147
2142
for revision_id in chain([self.last_revision()],
2148
2143
self.tags.get_reverse_tag_dict()):
2149
self.repository.fetch(source_repository, revision_id, find_ghosts=True)
2144
self.repository.fetch(source_repository, revision_id,
2151
2147
self._activate_fallback_location(url)
2152
2148
# write this out after the repository is stacked to avoid setting a
2153
2149
# stacked config that doesn't work.
2154
self._transport.put_bytes('stacked-on', (url + '\n').encode('utf_8'))
2150
self._set_config_location('stacked_on_location', url)
2156
2152
def _get_append_revisions_only(self):
2157
2153
value = self.get_config().get_user_option('append_revisions_only')
2236
2232
class BzrBranch6(BzrBranch7):
2237
2233
"""See BzrBranchFormat6 for the capabilities of this branch.
2239
This subclass of BzrBranch7 disables the new features BzrBranch7 added.
2235
This subclass of BzrBranch7 disables the new features BzrBranch7 added,
2242
2239
def get_stacked_on(self):
2268
2265
:ivar old_revid: Tip revision id before pull.
2269
2266
:ivar new_revid: Tip revision id after pull.
2270
2267
:ivar source_branch: Source (local) branch object.
2271
:ivar master_branch: Master branch of the target, or None.
2268
:ivar master_branch: Master branch of the target, or the target if no
2270
:ivar local_branch: target branch if there is a Master, else None
2272
2271
:ivar target_branch: Target/destination branch object.
2272
:ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to
2275
2275
def __int__(self):
2350
2350
# Copying done; now update target format
2351
2351
new_branch._transport.put_bytes('format',
2352
2352
format.get_format_string(),
2353
mode=new_branch.control_files._file_mode)
2353
mode=new_branch.bzrdir._get_file_mode())
2355
2355
# Clean up old files
2356
2356
new_branch._transport.delete('revision-history')
2367
2367
def convert(self, branch):
2368
2368
format = BzrBranchFormat7()
2369
branch._transport.put_bytes('stacked-on', '\n')
2369
branch._set_config_location('stacked_on_location', '')
2370
2370
# update target format
2371
2371
branch._transport.put_bytes('format', format.get_format_string())