751
751
"""Print `file` to stdout."""
752
752
raise NotImplementedError(self.print_file)
754
@deprecated_method(deprecated_in((2, 4, 0)))
754
756
def set_revision_history(self, rev_history):
755
raise NotImplementedError(self.set_revision_history)
757
"""See Branch.set_revision_history."""
758
if len(rev_history) == 0:
759
revid = _mod_revision.NULL_REVISION
761
revid = rev_history[-1]
762
self.set_last_revision_info(len(rev_history), revid)
763
self._cache_revision_history(rev_history)
766
def set_last_revision_info(self, revno, revision_id):
767
revision_id = _mod_revision.ensure_null(revision_id)
768
old_revno, old_revid = self.last_revision_info()
769
if self._get_append_revisions_only():
770
self._check_history_violation(revision_id)
771
self._run_pre_change_branch_tip_hooks(revno, revision_id)
772
self._write_last_revision_info(revno, revision_id)
773
self._clear_cached_state()
774
self._last_revision_info_cache = revno, revision_id
775
self._run_post_change_branch_tip_hooks(old_revno, old_revid)
757
777
@needs_write_lock
758
778
def set_parent(self, url):
988
1008
:return: A tuple (revno, revision_id).
990
1010
if self._last_revision_info_cache is None:
991
self._last_revision_info_cache = self._last_revision_info()
1011
self._last_revision_info_cache = self._read_last_revision_info()
992
1012
return self._last_revision_info_cache
994
def _last_revision_info(self):
995
rh = self.revision_history()
998
return (revno, rh[-1])
1000
return (0, _mod_revision.NULL_REVISION)
1014
def _read_last_revision_info(self):
1015
raise NotImplementedError(self._last_revision_info)
1002
1017
def update_revisions(self, other, stop_revision=None, overwrite=False,
1003
1018
graph=None, fetch_tags=True):
2502
2517
"""See Branch.print_file."""
2503
2518
return self.repository.print_file(file, revision_id)
2505
@deprecated_method(deprecated_in((2, 4, 0)))
2507
def set_revision_history(self, rev_history):
2508
"""See Branch.set_revision_history."""
2509
self._set_revision_history(rev_history)
2511
def _set_revision_history(self, rev_history):
2512
if 'evil' in debug.debug_flags:
2513
mutter_callsite(3, "set_revision_history scales with history.")
2514
check_not_reserved_id = _mod_revision.check_not_reserved_id
2515
for rev_id in rev_history:
2516
check_not_reserved_id(rev_id)
2517
if Branch.hooks['post_change_branch_tip']:
2518
# Don't calculate the last_revision_info() if there are no hooks
2520
old_revno, old_revid = self.last_revision_info()
2521
if len(rev_history) == 0:
2522
revid = _mod_revision.NULL_REVISION
2524
revid = rev_history[-1]
2525
self._run_pre_change_branch_tip_hooks(len(rev_history), revid)
2526
self._write_revision_history(rev_history)
2527
self._clear_cached_state()
2528
self._cache_revision_history(rev_history)
2529
for hook in Branch.hooks['set_rh']:
2530
hook(self, rev_history)
2531
if Branch.hooks['post_change_branch_tip']:
2532
self._run_post_change_branch_tip_hooks(old_revno, old_revid)
2534
def _synchronize_history(self, destination, revision_id):
2535
"""Synchronize last revision and revision history between branches.
2537
This version is most efficient when the destination is also a
2538
BzrBranch5, but works for BzrBranch6 as long as the revision
2539
history is the true lefthand parent history, and all of the revisions
2540
are in the destination's repository. If not, set_revision_history
2543
:param destination: The branch to copy the history into
2544
:param revision_id: The revision-id to truncate history at. May
2545
be None to copy complete history.
2547
if not isinstance(destination._format, BzrBranchFormat5):
2548
super(BzrBranch, self)._synchronize_history(
2549
destination, revision_id)
2551
if revision_id == _mod_revision.NULL_REVISION:
2554
new_history = self.revision_history()
2555
if revision_id is not None and new_history != []:
2557
new_history = new_history[:new_history.index(revision_id) + 1]
2559
rev = self.repository.get_revision(revision_id)
2560
new_history = rev.get_history(self.repository)[1:]
2561
destination._set_revision_history(new_history)
2563
2520
@needs_write_lock
2564
2521
def set_last_revision_info(self, revno, revision_id):
2565
2522
"""Set the last revision of this branch.
2645
2595
self._transport.put_bytes('parent', url + '\n',
2646
2596
mode=self.bzrdir._get_file_mode())
2649
class FullHistoryBzrBranch(BzrBranch):
2651
def _write_revision_history(self, history):
2652
"""Factored out of set_revision_history.
2654
This performs the actual writing to disk.
2655
It is intended to be called by BzrBranch5.set_revision_history."""
2656
self._transport.put_bytes(
2657
'revision-history', '\n'.join(history),
2658
mode=self.bzrdir._get_file_mode())
2660
def _gen_revision_history(self):
2661
history = self._transport.get_bytes('revision-history').split('\n')
2662
if history[-1:] == ['']:
2663
# There shouldn't be a trailing newline, but just in case.
2668
class BzrBranch5(FullHistoryBzrBranch):
2669
"""A format 5 branch. This supports new features over plain branches.
2671
It has support for a master_branch which is the data for bound branches.
2600
"""If bound, unbind"""
2601
return self.set_bound_location(None)
2604
def bind(self, other):
2605
"""Bind this branch to the branch other.
2607
This does not push or pull data between the branches, though it does
2608
check for divergence to raise an error when the branches are not
2609
either the same, or one a prefix of the other. That behaviour may not
2610
be useful, so that check may be removed in future.
2612
:param other: The branch to bind to
2615
# TODO: jam 20051230 Consider checking if the target is bound
2616
# It is debatable whether you should be able to bind to
2617
# a branch which is itself bound.
2618
# Committing is obviously forbidden,
2619
# but binding itself may not be.
2620
# Since we *have* to check at commit time, we don't
2621
# *need* to check here
2623
# we want to raise diverged if:
2624
# last_rev is not in the other_last_rev history, AND
2625
# other_last_rev is not in our history, and do it without pulling
2627
self.set_bound_location(other.base)
2674
2629
def get_bound_location(self):
2719
2674
@needs_write_lock
2720
def bind(self, other):
2721
"""Bind this branch to the branch other.
2723
This does not push or pull data between the branches, though it does
2724
check for divergence to raise an error when the branches are not
2725
either the same, or one a prefix of the other. That behaviour may not
2726
be useful, so that check may be removed in future.
2728
:param other: The branch to bind to
2731
# TODO: jam 20051230 Consider checking if the target is bound
2732
# It is debatable whether you should be able to bind to
2733
# a branch which is itself bound.
2734
# Committing is obviously forbidden,
2735
# but binding itself may not be.
2736
# Since we *have* to check at commit time, we don't
2737
# *need* to check here
2739
# we want to raise diverged if:
2740
# last_rev is not in the other_last_rev history, AND
2741
# other_last_rev is not in our history, and do it without pulling
2743
self.set_bound_location(other.base)
2747
"""If bound, unbind"""
2748
return self.set_bound_location(None)
2751
2675
def update(self, possible_transports=None):
2752
2676
"""Synchronise this branch with the master branch if any.
2768
class BzrBranch8(BzrBranch5):
2691
def _read_last_revision_info(self):
2692
revision_string = self._transport.get_bytes('last-revision')
2693
revno, revision_id = revision_string.rstrip('\n').split(' ', 1)
2694
revision_id = cache_utf8.get_cached_utf8(revision_id)
2696
return revno, revision_id
2698
def _write_last_revision_info(self, revno, revision_id):
2699
"""Simply write out the revision id, with no checks.
2701
Use set_last_revision_info to perform this safely.
2703
Does not update the revision_history cache.
2705
revision_id = _mod_revision.ensure_null(revision_id)
2706
out_string = '%d %s\n' % (revno, revision_id)
2707
self._transport.put_bytes('last-revision', out_string,
2708
mode=self.bzrdir._get_file_mode())
2711
class FullHistoryBzrBranch(BzrBranch):
2712
"""Bzr branch which contains the full revision history."""
2715
def set_last_revision_info(self, revno, revision_id):
2716
revision_id = _mod_revision.ensure_null(revision_id)
2717
# this old format stores the full history, but this api doesn't
2718
# provide it, so we must generate, and might as well check it's
2720
history = self._lefthand_history(revision_id)
2721
if len(history) != revno:
2722
raise AssertionError('%d != %d' % (len(history), revno))
2723
self._set_revision_history(history)
2725
def _read_last_revision_info(self):
2726
rh = self.revision_history()
2729
return (revno, rh[-1])
2731
return (0, _mod_revision.NULL_REVISION)
2733
@deprecated_method(deprecated_in((2, 4, 0)))
2735
def set_revision_history(self, rev_history):
2736
"""See Branch.set_revision_history."""
2737
self._set_revision_history(rev_history)
2739
def _set_revision_history(self, rev_history):
2740
if 'evil' in debug.debug_flags:
2741
mutter_callsite(3, "set_revision_history scales with history.")
2742
check_not_reserved_id = _mod_revision.check_not_reserved_id
2743
for rev_id in rev_history:
2744
check_not_reserved_id(rev_id)
2745
if Branch.hooks['post_change_branch_tip']:
2746
# Don't calculate the last_revision_info() if there are no hooks
2748
old_revno, old_revid = self.last_revision_info()
2749
if len(rev_history) == 0:
2750
revid = _mod_revision.NULL_REVISION
2752
revid = rev_history[-1]
2753
self._run_pre_change_branch_tip_hooks(len(rev_history), revid)
2754
self._write_revision_history(rev_history)
2755
self._clear_cached_state()
2756
self._cache_revision_history(rev_history)
2757
for hook in Branch.hooks['set_rh']:
2758
hook(self, rev_history)
2759
if Branch.hooks['post_change_branch_tip']:
2760
self._run_post_change_branch_tip_hooks(old_revno, old_revid)
2762
def _write_revision_history(self, history):
2763
"""Factored out of set_revision_history.
2765
This performs the actual writing to disk.
2766
It is intended to be called by set_revision_history."""
2767
self._transport.put_bytes(
2768
'revision-history', '\n'.join(history),
2769
mode=self.bzrdir._get_file_mode())
2771
def _gen_revision_history(self):
2772
history = self._transport.get_bytes('revision-history').split('\n')
2773
if history[-1:] == ['']:
2774
# There shouldn't be a trailing newline, but just in case.
2778
def _synchronize_history(self, destination, revision_id):
2779
if not isinstance(destination._format, FullHistoryBzrBranch):
2780
super(BzrBranch, self)._synchronize_history(
2781
destination, revision_id)
2783
if revision_id == _mod_revision.NULL_REVISION:
2786
new_history = self.revision_history()
2787
if revision_id is not None and new_history != []:
2789
new_history = new_history[:new_history.index(revision_id) + 1]
2791
rev = self.repository.get_revision(revision_id)
2792
new_history = rev.get_history(self.repository)[1:]
2793
destination._set_revision_history(new_history)
2796
class BzrBranch5(FullHistoryBzrBranch):
2797
"""A format 5 branch. This supports new features over plain branches.
2799
It has support for a master_branch which is the data for bound branches.
2803
class BzrBranch8(BzrBranch):
2769
2804
"""A branch that stores tree-reference locations."""
2771
2806
def _open_hook(self):
2797
2832
self._last_revision_info_cache = None
2798
2833
self._reference_info = None
2800
def _last_revision_info(self):
2801
revision_string = self._transport.get_bytes('last-revision')
2802
revno, revision_id = revision_string.rstrip('\n').split(' ', 1)
2803
revision_id = cache_utf8.get_cached_utf8(revision_id)
2805
return revno, revision_id
2807
def _write_last_revision_info(self, revno, revision_id):
2808
"""Simply write out the revision id, with no checks.
2810
Use set_last_revision_info to perform this safely.
2812
Does not update the revision_history cache.
2813
Intended to be called by set_last_revision_info and
2814
_write_revision_history.
2816
revision_id = _mod_revision.ensure_null(revision_id)
2817
out_string = '%d %s\n' % (revno, revision_id)
2818
self._transport.put_bytes('last-revision', out_string,
2819
mode=self.bzrdir._get_file_mode())
2822
def set_last_revision_info(self, revno, revision_id):
2823
revision_id = _mod_revision.ensure_null(revision_id)
2824
old_revno, old_revid = self.last_revision_info()
2825
if self._get_append_revisions_only():
2826
self._check_history_violation(revision_id)
2827
self._run_pre_change_branch_tip_hooks(revno, revision_id)
2828
self._write_last_revision_info(revno, revision_id)
2829
self._clear_cached_state()
2830
self._last_revision_info_cache = revno, revision_id
2831
self._run_post_change_branch_tip_hooks(old_revno, old_revid)
2833
def _synchronize_history(self, destination, revision_id):
2834
"""Synchronize last revision and revision history between branches.
2836
:see: Branch._synchronize_history
2838
# XXX: The base Branch has a fast implementation of this method based
2839
# on set_last_revision_info, but BzrBranch/BzrBranch5 have a slower one
2840
# that uses set_revision_history. This class inherits from BzrBranch5,
2841
# but wants the fast implementation, so it calls
2842
# Branch._synchronize_history directly.
2843
Branch._synchronize_history(self, destination, revision_id)
2845
2835
def _check_history_violation(self, revision_id):
2846
2836
last_revision = _mod_revision.ensure_null(self.last_revision())
2847
2837
if _mod_revision.is_null(last_revision):