49
41
from bzrlib.decorators import needs_read_lock, needs_write_lock
50
from bzrlib.errors import (BzrError, BzrCheckError, DivergedBranches,
51
HistoryMissing, InvalidRevisionId,
52
InvalidRevisionNumber, LockError, NoSuchFile,
53
NoSuchRevision, NotVersionedError,
54
NotBranchError, UninitializableFormat,
55
UnlistableStore, UnlistableBranch,
57
42
from bzrlib.hooks import Hooks
58
from bzrlib.symbol_versioning import (deprecated_function,
62
zero_eight, zero_nine, zero_sixteen,
43
from bzrlib.symbol_versioning import (deprecated_method,
65
from bzrlib.trace import mutter, mutter_callsite, note
46
from bzrlib.trace import mutter, mutter_callsite, note, is_quiet
68
49
BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
1429
1410
if 'evil' in debug.debug_flags:
1430
1411
mutter_callsite(4, "_lefthand_history scales with history.")
1431
1412
# stop_revision must be a descendant of last_revision
1432
stop_graph = self.repository.get_revision_graph(revision_id)
1433
if (last_rev is not None and last_rev != _mod_revision.NULL_REVISION
1434
and last_rev not in stop_graph):
1435
# our previous tip is not merged into stop_revision
1436
raise errors.DivergedBranches(self, other_branch)
1413
graph = self.repository.get_graph()
1414
if last_rev is not None:
1415
if not graph.is_ancestor(last_rev, revision_id):
1416
# our previous tip is not merged into stop_revision
1417
raise errors.DivergedBranches(self, other_branch)
1437
1418
# make a new revision history from the graph
1419
parents_map = graph.get_parent_map([revision_id])
1420
if revision_id not in parents_map:
1421
raise errors.NoSuchRevision(self, revision_id)
1438
1422
current_rev_id = revision_id
1439
1423
new_history = []
1440
while current_rev_id not in (None, _mod_revision.NULL_REVISION):
1424
# Do not include ghosts or graph origin in revision_history
1425
while (current_rev_id in parents_map and
1426
len(parents_map[current_rev_id]) > 0):
1441
1427
new_history.append(current_rev_id)
1442
current_rev_id_parents = stop_graph[current_rev_id]
1444
current_rev_id = current_rev_id_parents[0]
1446
current_rev_id = None
1428
current_rev_id = parents_map[current_rev_id][0]
1429
parents_map = graph.get_parent_map([current_rev_id])
1447
1430
new_history.reverse()
1448
1431
return new_history
1827
class BzrBranchExperimental(BzrBranch5):
1828
"""Bzr experimental branch format
1831
- a revision-history file.
1833
- a lock dir guarding the branch itself
1834
- all of this stored in a branch/ subdirectory
1835
- works with shared repositories.
1836
- a tag dictionary in the branch
1838
This format is new in bzr 0.15, but shouldn't be used for real data,
1841
This class acts as it's own BranchFormat.
1844
_matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1847
def get_format_string(cls):
1848
"""See BranchFormat.get_format_string()."""
1849
return "Bazaar-NG branch format experimental\n"
1852
def get_format_description(cls):
1853
"""See BranchFormat.get_format_description()."""
1854
return "Experimental branch format"
1857
def get_reference(cls, a_bzrdir):
1858
"""Get the target reference of the branch in a_bzrdir.
1860
format probing must have been completed before calling
1861
this method - it is assumed that the format of the branch
1862
in a_bzrdir is correct.
1864
:param a_bzrdir: The bzrdir to get the branch data from.
1865
:return: None if the branch is not a reference branch.
1870
def set_reference(self, a_bzrdir, to_branch):
1871
"""Set the target reference of the branch in a_bzrdir.
1873
format probing must have been completed before calling
1874
this method - it is assumed that the format of the branch
1875
in a_bzrdir is correct.
1877
:param a_bzrdir: The bzrdir to set the branch reference for.
1878
:param to_branch: branch that the checkout is to reference
1880
raise NotImplementedError(self.set_reference)
1883
def _initialize_control_files(cls, a_bzrdir, utf8_files, lock_filename,
1885
branch_transport = a_bzrdir.get_branch_transport(cls)
1886
control_files = lockable_files.LockableFiles(branch_transport,
1887
lock_filename, lock_class)
1888
control_files.create_lock()
1889
control_files.lock_write()
1891
for filename, content in utf8_files:
1892
control_files.put_utf8(filename, content)
1894
control_files.unlock()
1897
def initialize(cls, a_bzrdir):
1898
"""Create a branch of this format in a_bzrdir."""
1899
utf8_files = [('format', cls.get_format_string()),
1900
('revision-history', ''),
1901
('branch-name', ''),
1904
cls._initialize_control_files(a_bzrdir, utf8_files,
1905
'lock', lockdir.LockDir)
1906
return cls.open(a_bzrdir, _found=True)
1909
def open(cls, a_bzrdir, _found=False):
1910
"""Return the branch object for a_bzrdir
1912
_found is a private parameter, do not use it. It is used to indicate
1913
if format probing has already be done.
1916
format = BranchFormat.find_format(a_bzrdir)
1917
assert format.__class__ == cls
1918
transport = a_bzrdir.get_branch_transport(None)
1919
control_files = lockable_files.LockableFiles(transport, 'lock',
1921
return cls(_format=cls,
1922
_control_files=control_files,
1924
_repository=a_bzrdir.find_repository())
1927
def is_supported(cls):
1930
def _make_tags(self):
1931
return BasicTags(self)
1934
def supports_tags(cls):
1938
BranchFormat.register_format(BzrBranchExperimental)
1941
1810
class BzrBranch6(BzrBranch5):
1943
1812
@needs_read_lock
1962
1826
Intended to be called by set_last_revision_info and
1963
1827
_write_revision_history.
1965
if revision_id is None:
1966
revision_id = 'null:'
1829
assert revision_id is not None, "Use NULL_REVISION, not None"
1967
1830
out_string = '%d %s\n' % (revno, revision_id)
1968
1831
self.control_files.put_bytes('last-revision', out_string)
1970
1833
@needs_write_lock
1971
1834
def set_last_revision_info(self, revno, revision_id):
1835
revision_id = _mod_revision.ensure_null(revision_id)
1972
1836
if self._get_append_revisions_only():
1973
1837
self._check_history_violation(revision_id)
1974
1838
self._write_last_revision_info(revno, revision_id)