1
# Copyright (C) 2007-2012 Canonical Ltd
1
# Copyright (C) 2007-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
58
57
from bzrlib.lock import LogicalLockResult
59
58
from bzrlib.lockable_files import LockableFiles
60
59
from bzrlib.lockdir import LockDir
61
from bzrlib.mutabletree import (
63
needs_tree_write_lock,
60
from bzrlib.mutabletree import needs_tree_write_lock
65
61
from bzrlib.osutils import (
261
253
:return: an integer. -1 means never save.
263
conf = self.get_config_stack()
255
# FIXME: We want a WorkingTreeStack here -- vila 20110812
256
conf = config.BranchStack(self.branch)
264
257
return conf.get('bzr.workingtree.worth_saving_limit')
266
259
def filter_unversioned_files(self, paths):
430
423
self._generate_inventory()
431
424
return self._inventory
433
@deprecated_method(deprecated_in((2, 5, 0)))
434
def _get_inventory(self):
435
return self.root_inventory
437
426
inventory = property(_get_inventory,
438
427
doc="Inventory of this Tree")
440
root_inventory = property(_get_root_inventory,
441
"Root inventory of this tree")
444
430
def get_parent_ids(self):
445
431
"""See Tree.get_parent_ids.
895
881
def path2id(self, path):
896
882
"""Return the id for path in this tree."""
897
if isinstance(path, list):
900
path = osutils.pathjoin(*path)
901
883
path = path.strip('/')
902
884
entry = self._get_entry(path=path)
903
885
if entry == (None, None):
1165
1147
# _make_delta if we can't get the RevisionTree
1168
delta = rev_tree.root_inventory._make_delta(
1169
basis_tree.root_inventory)
1150
delta = rev_tree.inventory._make_delta(basis_tree.inventory)
1170
1151
dirstate.update_basis_by_delta(delta, rev_id)
1172
1153
if not updated:
1369
1350
base_tree = trees[0][1]
1370
1351
state = self.current_dirstate()
1371
1352
# We don't support ghosts yet
1372
state.set_state_from_scratch(base_tree.root_inventory, trees, [])
1353
state.set_state_from_scratch(base_tree.inventory, trees, [])
1375
1356
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1563
1544
transform.build_tree(basis, wt, accelerator_tree,
1564
1545
hardlink=hardlink,
1565
1546
delta_from_tree=delta_from_tree)
1566
for hook in MutableTree.hooks['post_build_tree']:
1613
1592
def _get_matchingbzrdir(self):
1614
1593
"""Overrideable method to get a bzrdir for testing."""
1615
1594
# please test against something that will let us do tree references
1616
return controldir.format_registry.make_bzrdir(
1617
'development-subtree')
1595
return bzrdir.format_registry.make_bzrdir(
1596
'dirstate-with-subtree')
1619
1598
_matchingbzrdir = property(__get_matchingbzrdir)
1693
1672
def supports_views(self):
1696
def _get_matchingbzrdir(self):
1697
"""Overrideable method to get a bzrdir for testing."""
1698
# We use 'development-subtree' instead of '2a', because we have a
1699
# few tests that want to test tree references
1700
return bzrdir.format_registry.make_bzrdir('development-subtree')
1703
1676
class DirStateRevisionTree(InventoryTree):
1704
1677
"""A revision tree pulling the inventory from a dirstate.
1787
1760
if path is not None:
1788
1761
path = path.encode('utf8')
1789
1762
parent_index = self._get_parent_index()
1790
return self._dirstate._get_entry(parent_index, fileid_utf8=file_id,
1763
return self._dirstate._get_entry(parent_index, fileid_utf8=file_id, path_utf8=path)
1793
1765
def _generate_inventory(self):
1794
1766
"""Create and set self.inventory from the dirstate object.
1896
1868
@needs_read_lock
1897
1869
def get_file_revision(self, file_id):
1898
inv, inv_file_id = self._unpack_file_id(file_id)
1899
return inv[inv_file_id].revision
1870
return self.inventory[file_id].revision
1901
1872
def get_file(self, file_id, path=None):
1902
1873
return StringIO(self.get_file_text(file_id))
1904
1875
def get_file_size(self, file_id):
1905
1876
"""See Tree.get_file_size"""
1906
inv, inv_file_id = self._unpack_file_id(file_id)
1907
return inv[inv_file_id].text_size
1877
return self.inventory[file_id].text_size
1909
1879
def get_file_text(self, file_id, path=None):
1911
for _, content_iter in self.iter_files_bytes([(file_id, None)]):
1912
if content is not None:
1913
raise AssertionError('iter_files_bytes returned'
1914
' too many entries')
1915
# For each entry returned by iter_files_bytes, we must consume the
1916
# content_iter before we step the files iterator.
1917
content = ''.join(content_iter)
1919
raise AssertionError('iter_files_bytes did not return'
1920
' the requested data')
1880
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1881
return ''.join(content)
1923
1883
def get_reference_revision(self, file_id, path=None):
1924
inv, inv_file_id = self._unpack_file_id(file_id)
1925
return inv[inv_file_id].reference_revision
1884
return self.inventory[file_id].reference_revision
1927
1886
def iter_files_bytes(self, desired_files):
1928
1887
"""See Tree.iter_files_bytes.
1952
1911
"""Return the revision id for this tree."""
1953
1912
return self._revision_id
1955
def _get_root_inventory(self):
1914
def _get_inventory(self):
1956
1915
if self._inventory is not None:
1957
1916
return self._inventory
1958
1917
self._must_be_locked()
1959
1918
self._generate_inventory()
1960
1919
return self._inventory
1962
root_inventory = property(_get_root_inventory,
1963
doc="Inventory of this Tree")
1965
@deprecated_method(deprecated_in((2, 5, 0)))
1966
def _get_inventory(self):
1967
return self.root_inventory
1969
1921
inventory = property(_get_inventory,
1970
1922
doc="Inventory of this Tree")
1990
1942
def path_content_summary(self, path):
1991
1943
"""See Tree.path_content_summary."""
1992
inv, inv_file_id = self._path2inv_file_id(path)
1993
if inv_file_id is None:
1944
id = self.inventory.path2id(path)
1994
1946
return ('missing', None, None, None)
1995
entry = inv[inv_file_id]
1947
entry = self._inventory[id]
1996
1948
kind = entry.kind
1997
1949
if kind == 'file':
1998
1950
return (kind, entry.text_size, entry.executable, entry.text_sha1)
2002
1954
return (kind, None, None, None)
2004
1956
def is_executable(self, file_id, path=None):
2005
inv, inv_file_id = self._unpack_file_id(file_id)
2006
ie = inv[inv_file_id]
1957
ie = self.inventory[file_id]
2007
1958
if ie.kind != "file":
2009
1960
return ie.executable
2014
1965
def list_files(self, include_root=False, from_dir=None, recursive=True):
2015
1966
# We use a standard implementation, because DirStateRevisionTree is
2016
1967
# dealing with one of the parents of the current state
1968
inv = self._get_inventory()
2017
1969
if from_dir is None:
2018
inv = self.root_inventory
2019
1970
from_dir_id = None
2021
inv, from_dir_id = self._path2inv_file_id(from_dir)
1972
from_dir_id = inv.path2id(from_dir)
2022
1973
if from_dir_id is None:
2023
1974
# Directory not versioned
2025
# FIXME: Support nested trees
2026
1976
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
2027
1977
if inv.root is not None and not include_root and from_dir is None:
2050
2000
def path2id(self, path):
2051
2001
"""Return the id for path in this tree."""
2052
2002
# lookup by path: faster than splitting and walking the ivnentory.
2053
if isinstance(path, list):
2056
path = osutils.pathjoin(*path)
2057
2003
entry = self._get_entry(path=path)
2058
2004
if entry == (None, None):
2082
2028
# So for now, we just build up the parent inventory, and extract
2083
2029
# it the same way RevisionTree does.
2084
2030
_directory = 'directory'
2085
inv = self._get_root_inventory()
2031
inv = self._get_inventory()
2086
2032
top_id = inv.path2id(prefix)
2087
2033
if top_id is None: