125
128
raise errors.UnstackableRepositoryFormat(self.repository._format,
126
129
self.repository.base)
131
def _extend_partial_history(self, stop_index=None, stop_revision=None):
132
"""Extend the partial history to include a given index
134
If a stop_index is supplied, stop when that index has been reached.
135
If a stop_revision is supplied, stop when that revision is
136
encountered. Otherwise, stop when the beginning of history is
139
:param stop_index: The index which should be present. When it is
140
present, history extension will stop.
141
:param stop_revision: The revision id which should be present. When
142
it is encountered, history extension will stop.
144
if len(self._partial_revision_history_cache) == 0:
145
self._partial_revision_history_cache = [self.last_revision()]
146
repository._iter_for_revno(
147
self.repository, self._partial_revision_history_cache,
148
stop_index=stop_index, stop_revision=stop_revision)
149
if self._partial_revision_history_cache[-1] == _mod_revision.NULL_REVISION:
150
self._partial_revision_history_cache.pop()
129
153
def open(base, _unsupported=False, possible_transports=None):
130
154
"""Open the branch rooted at base.
499
523
raise errors.UpgradeRequired(self.base)
525
def set_append_revisions_only(self, enabled):
526
if not self._format.supports_set_append_revisions_only():
527
raise errors.UpgradeRequired(self.base)
532
self.get_config().set_user_option('append_revisions_only', value,
501
535
def set_reference_info(self, file_id, tree_path, branch_location):
502
536
"""Set the branch location to use for a tree reference."""
503
537
raise errors.UnsupportedOperation(self.set_reference_info, self)
636
673
except (errors.NotStacked, errors.UnstackableBranchFormat,
637
674
errors.UnstackableRepositoryFormat):
640
# XXX: Lock correctness - should unlock our old repo if we were
642
# repositories don't offer an interface to remove fallback
643
# repositories today; take the conceptually simpler option and just
645
self.repository = self.bzrdir.find_repository()
646
self.repository.lock_write()
647
# for every revision reference the branch has, ensure it is pulled
649
source_repository = self._get_fallback_repository(old_url)
650
for revision_id in chain([self.last_revision()],
651
self.tags.get_reverse_tag_dict()):
652
self.repository.fetch(source_repository, revision_id,
655
678
self._activate_fallback_location(url)
656
679
# write this out after the repository is stacked to avoid setting a
657
680
# stacked config that doesn't work.
658
681
self._set_config_location('stacked_on_location', url)
684
"""Change a branch to be unstacked, copying data as needed.
686
Don't call this directly, use set_stacked_on_url(None).
688
pb = ui.ui_factory.nested_progress_bar()
690
pb.update("Unstacking")
691
# The basic approach here is to fetch the tip of the branch,
692
# including all available ghosts, from the existing stacked
693
# repository into a new repository object without the fallbacks.
695
# XXX: See <https://launchpad.net/bugs/397286> - this may not be
696
# correct for CHKMap repostiories
697
old_repository = self.repository
698
if len(old_repository._fallback_repositories) != 1:
699
raise AssertionError("can't cope with fallback repositories "
700
"of %r" % (self.repository,))
701
# unlock it, including unlocking the fallback
702
old_repository.unlock()
703
old_repository.lock_read()
705
# Repositories don't offer an interface to remove fallback
706
# repositories today; take the conceptually simpler option and just
707
# reopen it. We reopen it starting from the URL so that we
708
# get a separate connection for RemoteRepositories and can
709
# stream from one of them to the other. This does mean doing
710
# separate SSH connection setup, but unstacking is not a
711
# common operation so it's tolerable.
712
new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
713
new_repository = new_bzrdir.find_repository()
714
self.repository = new_repository
715
if self.repository._fallback_repositories:
716
raise AssertionError("didn't expect %r to have "
717
"fallback_repositories"
718
% (self.repository,))
719
# this is not paired with an unlock because it's just restoring
720
# the previous state; the lock's released when set_stacked_on_url
722
self.repository.lock_write()
723
# XXX: If you unstack a branch while it has a working tree
724
# with a pending merge, the pending-merged revisions will no
725
# longer be present. You can (probably) revert and remerge.
727
# XXX: This only fetches up to the tip of the repository; it
728
# doesn't bring across any tags. That's fairly consistent
729
# with how branch works, but perhaps not ideal.
730
self.repository.fetch(old_repository,
731
revision_id=self.last_revision(),
734
old_repository.unlock()
661
738
def _set_tags_bytes(self, bytes):
662
739
"""Mirror method for _get_tags_bytes.
831
906
except ValueError:
832
907
raise errors.NoSuchRevision(self, revision_id)
834
910
def get_rev_id(self, revno, history=None):
835
911
"""Find the revision id of the specified revno."""
837
913
return _mod_revision.NULL_REVISION
839
history = self.revision_history()
840
if revno <= 0 or revno > len(history):
914
last_revno, last_revid = self.last_revision_info()
915
if revno == last_revno:
917
if revno <= 0 or revno > last_revno:
841
918
raise errors.NoSuchRevision(self, revno)
842
return history[revno - 1]
919
distance_from_last = last_revno - revno
920
if len(self._partial_revision_history_cache) <= distance_from_last:
921
self._extend_partial_history(distance_from_last)
922
return self._partial_revision_history_cache[distance_from_last]
844
924
@needs_write_lock
845
925
def pull(self, source, overwrite=False, stop_revision=None,
2376
2470
self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)
2377
2471
super(BzrBranch8, self).__init__(*args, **kwargs)
2378
2472
self._last_revision_info_cache = None
2379
self._partial_revision_history_cache = []
2380
2473
self._reference_info = None
2382
2475
def _clear_cached_state(self):
2383
2476
super(BzrBranch8, self)._clear_cached_state()
2384
2477
self._last_revision_info_cache = None
2385
self._partial_revision_history_cache = []
2386
2478
self._reference_info = None
2388
2480
def _last_revision_info(self):
2444
2536
self._extend_partial_history(stop_index=last_revno-1)
2445
2537
return list(reversed(self._partial_revision_history_cache))
2447
def _extend_partial_history(self, stop_index=None, stop_revision=None):
2448
"""Extend the partial history to include a given index
2450
If a stop_index is supplied, stop when that index has been reached.
2451
If a stop_revision is supplied, stop when that revision is
2452
encountered. Otherwise, stop when the beginning of history is
2455
:param stop_index: The index which should be present. When it is
2456
present, history extension will stop.
2457
:param revision_id: The revision id which should be present. When
2458
it is encountered, history extension will stop.
2460
repo = self.repository
2461
if len(self._partial_revision_history_cache) == 0:
2462
iterator = repo.iter_reverse_revision_history(self.last_revision())
2464
start_revision = self._partial_revision_history_cache[-1]
2465
iterator = repo.iter_reverse_revision_history(start_revision)
2466
#skip the last revision in the list
2467
next_revision = iterator.next()
2468
for revision_id in iterator:
2469
self._partial_revision_history_cache.append(revision_id)
2470
if (stop_index is not None and
2471
len(self._partial_revision_history_cache) > stop_index):
2473
if revision_id == stop_revision:
2476
2539
def _write_revision_history(self, history):
2477
2540
"""Factored out of set_revision_history.