839
def merge_modified(self):
841
hashfile = self._control_files.get('merge-hashes')
842
except errors.NoSuchFile:
846
if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
847
raise errors.MergeModifiedFormatError()
848
except StopIteration:
849
raise errors.MergeModifiedFormatError()
850
for s in RioReader(hashfile):
851
file_id = s.get("file_id")
852
if file_id not in self.inventory:
855
if hash == self.get_file_sha1(file_id):
856
merge_hashes[file_id] = hash
859
848
@needs_write_lock
860
def mkdir(self, path, file_id=None):
861
"""See MutableTree.mkdir()."""
863
file_id = generate_ids.gen_file_id(os.path.basename(path))
864
os.mkdir(self.abspath(path))
865
self.add(path, file_id, 'directory')
868
def get_symlink_target(self, file_id):
869
return os.readlink(self.id2abspath(file_id))
871
def file_class(self, filename):
872
if self.path2id(filename):
874
elif self.is_ignored(filename):
849
def subsume(self, other_tree):
850
def add_children(inventory, entry):
851
for child_entry in entry.children.values():
852
inventory._byid[child_entry.file_id] = child_entry
853
if child_entry.kind == 'directory':
854
add_children(inventory, child_entry)
855
if other_tree.get_root_id() == self.get_root_id():
856
raise errors.BadSubsumeSource(self, other_tree,
857
'Trees have the same root')
859
other_tree_path = self.relpath(other_tree.basedir)
860
except errors.PathNotChild:
861
raise errors.BadSubsumeSource(self, other_tree,
862
'Tree is not contained by the other')
863
new_root_parent = self.path2id(osutils.dirname(other_tree_path))
864
if new_root_parent is None:
865
raise errors.BadSubsumeSource(self, other_tree,
866
'Parent directory is not versioned.')
867
# We need to ensure that the result of a fetch will have a
868
# versionedfile for the other_tree root, and only fetching into
869
# RepositoryKnit2 guarantees that.
870
if not self.branch.repository.supports_rich_root():
871
raise errors.SubsumeTargetNeedsUpgrade(other_tree)
872
other_tree.lock_tree_write()
874
for parent_id in other_tree.get_parent_ids():
875
self.branch.fetch(other_tree.branch, parent_id)
876
self.add_parent_tree_id(parent_id)
877
other_root = other_tree.inventory.root
878
other_root.parent_id = new_root_parent
879
other_root.name = osutils.basename(other_tree_path)
880
self.inventory.add(other_root)
881
add_children(self.inventory, other_root)
882
self._write_inventory(self.inventory)
885
other_tree.bzrdir.destroy_workingtree_metadata()
887
@needs_tree_write_lock
888
def extract(self, file_id, format=None):
889
"""Extract a subtree from this tree.
891
A new branch will be created, relative to the path for this tree.
894
segments = osutils.splitpath(path)
895
transport = self.branch.bzrdir.root_transport
896
for name in segments:
897
transport = transport.clone(name)
900
except errors.FileExists:
904
sub_path = self.id2path(file_id)
905
branch_transport = mkdirs(sub_path)
907
format = bzrdir.format_registry.make_bzrdir('experimental-knit2')
909
branch_transport.mkdir('.')
910
except errors.FileExists:
912
branch_bzrdir = format.initialize_on_transport(branch_transport)
914
repo = branch_bzrdir.find_repository()
915
except errors.NoRepositoryPresent:
916
repo = branch_bzrdir.create_repository()
917
assert repo.supports_rich_root()
919
if not repo.supports_rich_root():
920
raise errors.RootNotRich()
921
new_branch = branch_bzrdir.create_branch()
922
new_branch.pull(self.branch)
923
for parent_id in self.get_parent_ids():
924
new_branch.fetch(self.branch, parent_id)
925
tree_transport = self.bzrdir.root_transport.clone(sub_path)
926
if tree_transport.base != branch_transport.base:
927
tree_bzrdir = format.initialize_on_transport(tree_transport)
928
branch.BranchReferenceFormat().initialize(tree_bzrdir, new_branch)
930
tree_bzrdir = branch_bzrdir
931
wt = tree_bzrdir.create_workingtree(NULL_REVISION)
932
wt.set_parent_ids(self.get_parent_ids())
933
my_inv = self.inventory
934
child_inv = Inventory(root_id=None)
935
new_root = my_inv[file_id]
936
my_inv.remove_recursive_id(file_id)
937
new_root.parent_id = None
938
child_inv.add(new_root)
939
self._write_inventory(my_inv)
940
wt._write_inventory(child_inv)
943
def _serialize(self, inventory, out_file):
944
xml5.serializer_v5.write_inventory(self._inventory, out_file)
946
def _deserialize(selt, in_file):
947
return xml5.serializer_v5.read_inventory(in_file)
880
950
"""Write the in memory inventory to disk."""
2221
2291
self.branch.unlock()
2294
class WorkingTreeAB1(WorkingTree3):
2296
def _serialize(self, inventory, out_file):
2297
xml7.serializer_v7.write_inventory(self._inventory, out_file)
2299
def _deserialize(selt, in_file):
2300
return xml7.serializer_v7.read_inventory(in_file)
2302
def _comparison_data(self, entry, path):
2303
kind, executable, stat_value = \
2304
WorkingTree3._comparison_data(self, entry, path)
2305
if kind == 'directory' and entry.kind == 'tree-reference':
2306
kind = 'tree-reference'
2307
return kind, executable, stat_value
2309
def kind(self, file_id):
2310
kind = WorkingTree3.kind(self, file_id)
2311
if kind == 'directory':
2312
entry = self.inventory[file_id]
2313
if entry.kind == 'tree-reference':
2314
kind = 'tree-reference'
2317
def add_reference(self, sub_tree):
2318
return self._add_reference(sub_tree)
2320
def get_nested_tree(self, entry, path=None):
2322
path = self.id2path(entry.file_id)
2323
return WorkingTree.open(self.abspath(path))
2325
def get_reference_revision(self, entry, path=None):
2326
return self.get_nested_tree(entry, path).last_revision()
2224
2329
def get_conflicted_stem(path):
2225
2330
for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
2226
2331
if path.endswith(suffix):
2496
2618
:param a_bzrdir: the dir for the tree.
2497
2619
:param control_files: the control files for the tree.
2499
return WorkingTree3(a_bzrdir.root_transport.local_abspath('.'),
2503
_control_files=control_files)
2621
return self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
2625
_control_files=control_files)
2505
2627
def __str__(self):
2506
2628
return self.get_format_string()
2631
class WorkingTreeFormatAB1(WorkingTreeFormat3):
2632
"""Working tree format that supports unique roots and nested trees"""
2634
_tree_class = WorkingTreeAB1
2636
requires_rich_root = True
2638
supports_tree_reference = True
2641
WorkingTreeFormat3.__init__(self)
2643
def __get_matchingbzrdir(self):
2644
return bzrdir.format_registry.make_bzrdir('experimental-knit3')
2646
_matchingbzrdir = property(__get_matchingbzrdir)
2648
def get_format_string(self):
2649
"""See WorkingTreeFormat.get_format_string()."""
2650
return "Bazaar-NG Working Tree format AB1"
2652
def get_format_description(self):
2653
"""See WorkingTreeFormat.get_format_description()."""
2654
return "Working tree format 4"
2656
def _initial_inventory(self):
2657
return Inventory(root_id=generate_ids.gen_root_id())
2659
# formats which have no format string are not discoverable
2660
# and not independently creatable, so are not registered.
2509
2661
__default_format = WorkingTreeFormat3()
2510
2662
WorkingTreeFormat.register_format(__default_format)
2511
2663
WorkingTreeFormat.register_format(WorkingTreeFormat4())
2664
WorkingTreeFormat.register_format(WorkingTreeFormatAB1())
2512
2665
WorkingTreeFormat.set_default_format(__default_format)
2513
2666
# formats which have no format string are not discoverable
2514
2667
# and not independently creatable, so are not registered.