29
29
from bzrlib.lazy_import import lazy_import
30
30
lazy_import(globals(), """
31
from bisect import bisect_left
33
from copy import deepcopy
35
42
from bzrlib import (
45
conflicts as _mod_conflicts,
43
55
revision as _mod_revision,
49
64
import bzrlib.branch
65
from bzrlib.transport import get_transport
69
from bzrlib import symbol_versioning
53
70
from bzrlib.decorators import needs_read_lock, needs_write_lock
54
from bzrlib.filters import filtered_input_file, internal_size_sha_file_byname
55
from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
56
from bzrlib.lock import LogicalLockResult
71
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, entry_factory
72
from bzrlib.lockable_files import LockableFiles, TransportLock
73
from bzrlib.lockdir import LockDir
74
import bzrlib.mutabletree
57
75
from bzrlib.mutabletree import needs_tree_write_lock
58
76
from bzrlib.osutils import (
65
from bzrlib.trace import mutter
86
from bzrlib.trace import mutter, note
66
87
from bzrlib.transport.local import LocalTransport
67
88
from bzrlib.tree import InterTree
89
from bzrlib.progress import DummyProgress, ProgressPhase
90
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
91
from bzrlib.rio import RioReader, rio_file, Stanza
92
from bzrlib.symbol_versioning import (deprecated_passed,
68
97
from bzrlib.tree import Tree
69
98
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
72
class DirStateWorkingTree(WorkingTree3):
101
class WorkingTree4(WorkingTree3):
102
"""This is the Format 4 working tree.
104
This differs from WorkingTree3 by:
105
- Having a consolidated internal dirstate, stored in a
106
randomly-accessible sorted file on disk.
107
- Not having a regular inventory attribute. One can be synthesized
108
on demand but this is expensive and should be avoided.
110
This is new in bzr 0.15.
73
113
def __init__(self, basedir,
75
115
_control_files=None,
218
258
return self._dirstate
219
259
local_path = self.bzrdir.get_workingtree_transport(None
220
260
).local_abspath('dirstate')
221
self._dirstate = dirstate.DirState.on_file(local_path,
222
self._sha1_provider())
261
self._dirstate = dirstate.DirState.on_file(local_path)
223
262
return self._dirstate
225
def _sha1_provider(self):
226
"""A function that returns a SHA1Provider suitable for this tree.
228
:return: None if content filtering is not supported by this tree.
229
Otherwise, a SHA1Provider is returned that sha's the canonical
230
form of files, i.e. after read filters are applied.
232
if self.supports_content_filtering():
233
return ContentFilterAwareSHA1Provider(self)
237
264
def filter_unversioned_files(self, paths):
238
265
"""Filter out paths that are versioned.
1278
1286
if self._dirty:
1279
1287
raise AssertionError("attempting to write an inventory when the "
1280
1288
"dirstate is dirty will lose pending changes")
1281
had_inventory = self._inventory is not None
1282
# Setting self._inventory = None forces the dirstate to regenerate the
1283
# working inventory. We do this because self.inventory may be inv, or
1284
# may have been modified, and either case would prevent a clean delta
1286
self._inventory = None
1288
delta = inv._make_delta(self.inventory)
1290
self.apply_inventory_delta(delta)
1289
self.current_dirstate().set_state_from_inventory(inv)
1290
self._make_dirty(reset_inventory=False)
1291
if self._inventory is not None:
1292
1292
self._inventory = inv
1296
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1298
def __init__(self, tree):
1301
def sha1(self, abspath):
1302
"""See dirstate.SHA1Provider.sha1()."""
1303
filters = self.tree._content_filter_stack(
1304
self.tree.relpath(osutils.safe_unicode(abspath)))
1305
return internal_size_sha_file_byname(abspath, filters)[1]
1307
def stat_and_sha1(self, abspath):
1308
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1309
filters = self.tree._content_filter_stack(
1310
self.tree.relpath(osutils.safe_unicode(abspath)))
1311
file_obj = file(abspath, 'rb', 65000)
1313
statvalue = os.fstat(file_obj.fileno())
1315
file_obj = filtered_input_file(file_obj, filters)
1316
sha1 = osutils.size_sha_file(file_obj)[1]
1319
return statvalue, sha1
1322
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1323
"""Dirstate working tree that supports content filtering.
1325
The dirstate holds the hash and size of the canonical form of the file,
1326
and most methods must return that.
1329
def _file_content_summary(self, path, stat_result):
1330
# This is to support the somewhat obsolete path_content_summary method
1331
# with content filtering: see
1332
# <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
1334
# If the dirstate cache is up to date and knows the hash and size,
1336
# Otherwise if there are no content filters, return the on-disk size
1337
# and leave the hash blank.
1338
# Otherwise, read and filter the on-disk file and use its size and
1341
# The dirstate doesn't store the size of the canonical form so we
1342
# can't trust it for content-filtered trees. We just return None.
1343
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1344
executable = self._is_executable_from_path_and_stat(path, stat_result)
1345
return ('file', None, executable, dirstate_sha1)
1348
class WorkingTree4(DirStateWorkingTree):
1349
"""This is the Format 4 working tree.
1351
This differs from WorkingTree3 by:
1352
- Having a consolidated internal dirstate, stored in a
1353
randomly-accessible sorted file on disk.
1354
- Not having a regular inventory attribute. One can be synthesized
1355
on demand but this is expensive and should be avoided.
1357
This is new in bzr 0.15.
1361
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1362
"""This is the Format 5 working tree.
1364
This differs from WorkingTree4 by:
1365
- Supporting content filtering.
1367
This is new in bzr 1.11.
1371
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1372
"""This is the Format 6 working tree.
1374
This differs from WorkingTree5 by:
1375
- Supporting a current view that may mask the set of files in a tree
1376
impacted by most user operations.
1378
This is new in bzr 1.14.
1381
def _make_views(self):
1382
return views.PathBasedViews(self)
1385
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1296
class WorkingTreeFormat4(WorkingTreeFormat3):
1297
"""The first consolidated dirstate working tree format.
1300
- exists within a metadir controlling .bzr
1301
- includes an explicit version marker for the workingtree control
1302
files, separate from the BzrDir format
1303
- modifies the hash cache format
1304
- is new in bzr 0.15
1305
- uses a LockDir to guard access to it.
1308
upgrade_recommended = False
1310
_tree_class = WorkingTree4
1312
def get_format_string(self):
1313
"""See WorkingTreeFormat.get_format_string()."""
1314
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1316
def get_format_description(self):
1317
"""See WorkingTreeFormat.get_format_description()."""
1318
return "Working tree format 4"
1387
1320
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1388
1321
accelerator_tree=None, hardlink=False):
1512
1433
_matchingbzrdir = property(__get_matchingbzrdir)
1515
class WorkingTreeFormat4(DirStateWorkingTreeFormat):
1516
"""The first consolidated dirstate working tree format.
1519
- exists within a metadir controlling .bzr
1520
- includes an explicit version marker for the workingtree control
1521
files, separate from the BzrDir format
1522
- modifies the hash cache format
1523
- is new in bzr 0.15
1524
- uses a LockDir to guard access to it.
1527
upgrade_recommended = False
1529
_tree_class = WorkingTree4
1531
def get_format_string(self):
1532
"""See WorkingTreeFormat.get_format_string()."""
1533
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1535
def get_format_description(self):
1536
"""See WorkingTreeFormat.get_format_description()."""
1537
return "Working tree format 4"
1540
class WorkingTreeFormat5(DirStateWorkingTreeFormat):
1541
"""WorkingTree format supporting content filtering.
1544
upgrade_recommended = False
1546
_tree_class = WorkingTree5
1548
def get_format_string(self):
1549
"""See WorkingTreeFormat.get_format_string()."""
1550
return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1552
def get_format_description(self):
1553
"""See WorkingTreeFormat.get_format_description()."""
1554
return "Working tree format 5"
1556
def supports_content_filtering(self):
1560
class WorkingTreeFormat6(DirStateWorkingTreeFormat):
1561
"""WorkingTree format supporting views.
1564
upgrade_recommended = False
1566
_tree_class = WorkingTree6
1568
def get_format_string(self):
1569
"""See WorkingTreeFormat.get_format_string()."""
1570
return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1572
def get_format_description(self):
1573
"""See WorkingTreeFormat.get_format_description()."""
1574
return "Working tree format 6"
1576
def _init_custom_control_files(self, wt):
1577
"""Subclasses with custom control files should override this method."""
1578
wt._transport.put_bytes('views', '', mode=wt.bzrdir._get_file_mode())
1580
def supports_content_filtering(self):
1583
def supports_views(self):
1587
1436
class DirStateRevisionTree(Tree):
1588
"""A revision tree pulling the inventory from a dirstate.
1590
Note that this is one of the historical (ie revision) trees cached in the
1591
dirstate for easy access, not the workingtree.
1437
"""A revision tree pulling the inventory from a dirstate."""
1594
1439
def __init__(self, dirstate, revision_id, repository):
1595
1440
self._dirstate = dirstate
1784
1625
def get_file(self, file_id, path=None):
1785
1626
return StringIO(self.get_file_text(file_id))
1628
def get_file_lines(self, file_id):
1629
return osutils.split_lines(self.get_file_text(file_id))
1787
1631
def get_file_size(self, file_id):
1788
1632
"""See Tree.get_file_size"""
1789
1633
return self.inventory[file_id].text_size
1791
def get_file_text(self, file_id, path=None):
1792
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1793
return ''.join(content)
1635
def get_file_text(self, file_id):
1636
return list(self.iter_files_bytes([(file_id, None)]))[0][1]
1795
1638
def get_reference_revision(self, file_id, path=None):
1796
1639
return self.inventory[file_id].reference_revision
1872
1715
return ie.executable
1874
def is_locked(self):
1877
def list_files(self, include_root=False, from_dir=None, recursive=True):
1717
def list_files(self, include_root=False):
1878
1718
# We use a standard implementation, because DirStateRevisionTree is
1879
1719
# dealing with one of the parents of the current state
1880
1720
inv = self._get_inventory()
1881
if from_dir is None:
1884
from_dir_id = inv.path2id(from_dir)
1885
if from_dir_id is None:
1886
# Directory not versioned
1888
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
1889
if inv.root is not None and not include_root and from_dir is None:
1721
entries = inv.iter_entries()
1722
if self.inventory.root is not None and not include_root:
1891
1724
for path, entry in entries:
1892
1725
yield path, 'V', entry.kind, entry.file_id, entry
1894
1727
def lock_read(self):
1895
"""Lock the tree for a set of operations.
1897
:return: A bzrlib.lock.LogicalLockResult.
1728
"""Lock the tree for a set of operations."""
1899
1729
if not self._locked:
1900
1730
self._repository.lock_read()
1901
1731
if self._dirstate._lock_token is None:
1902
1732
self._dirstate.lock_read()
1903
1733
self._dirstate_locked = True
1904
1734
self._locked += 1
1905
return LogicalLockResult(self.unlock)
1907
1736
def _must_be_locked(self):
1908
1737
if not self._locked:
2001
def make_source_parent_tree_compiled_dirstate(klass, test_case, source,
1830
def make_source_parent_tree_compiled_dirstate(klass, test_case, source, target):
2003
1831
from bzrlib.tests.test__dirstate_helpers import \
2004
compiled_dirstate_helpers_feature
2005
test_case.requireFeature(compiled_dirstate_helpers_feature)
2006
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
1832
CompiledDirstateHelpersFeature
1833
if not CompiledDirstateHelpersFeature.available():
1834
from bzrlib.tests import UnavailableFeature
1835
raise UnavailableFeature(CompiledDirstateHelpersFeature)
1836
from bzrlib._dirstate_helpers_c import ProcessEntryC
2007
1837
result = klass.make_source_parent_tree(source, target)
2008
1838
result[1]._iter_changes = ProcessEntryC
2099
1931
if not found_versioned:
2100
1932
# none of the indexes was not 'absent' at all ids for this
2102
not_versioned.append(path)
2103
if len(not_versioned) > 0:
2104
raise errors.PathsNotVersionedError(not_versioned)
1934
all_versioned = False
1936
if not all_versioned:
1937
raise errors.PathsNotVersionedError(specific_files)
2105
1938
# -- remove redundancy in supplied specific_files to prevent over-scanning --
2106
search_specific_files = osutils.minimum_path_selection(specific_files)
1939
for path in specific_files:
1940
other_specific_files = specific_files.difference(set([path]))
1941
if not osutils.is_inside_any(other_specific_files, path):
1942
# this is a top level path, we must check it.
1943
search_specific_files.add(path)
2108
1945
use_filesystem_for_exec = (sys.platform != 'win32')
2109
1946
iter_changes = self.target._iter_changes(include_unchanged,
2115
1952
def is_compatible(source, target):
2116
1953
# the target must be a dirstate working tree
2117
if not isinstance(target, DirStateWorkingTree):
1954
if not isinstance(target, WorkingTree4):
2119
# the source must be a revtree or dirstate rev tree.
1956
# the source must be a revtreee or dirstate rev tree.
2120
1957
if not isinstance(source,
2121
1958
(revisiontree.RevisionTree, DirStateRevisionTree)):
2123
1960
# the source revid must be in the target dirstate
2124
if not (source._revision_id == _mod_revision.NULL_REVISION or
1961
if not (source._revision_id == NULL_REVISION or
2125
1962
source._revision_id in target.get_parent_ids()):
2126
# TODO: what about ghosts? it may well need to
1963
# TODO: what about ghosts? it may well need to
2127
1964
# check for them explicitly.
2174
2011
tree._transport.put_bytes('format',
2175
2012
self.target_format.get_format_string(),
2176
2013
mode=tree.bzrdir._get_file_mode())
2179
class Converter4to5(object):
2180
"""Perform an in-place upgrade of format 4 to format 5 trees."""
2183
self.target_format = WorkingTreeFormat5()
2185
def convert(self, tree):
2186
# lock the control files not the tree, so that we don't get tree
2187
# on-unlock behaviours, and so that no-one else diddles with the
2188
# tree during upgrade.
2189
tree._control_files.lock_write()
2191
self.update_format(tree)
2193
tree._control_files.unlock()
2195
def update_format(self, tree):
2196
"""Change the format marker."""
2197
tree._transport.put_bytes('format',
2198
self.target_format.get_format_string(),
2199
mode=tree.bzrdir._get_file_mode())
2202
class Converter4or5to6(object):
2203
"""Perform an in-place upgrade of format 4 or 5 to format 6 trees."""
2206
self.target_format = WorkingTreeFormat6()
2208
def convert(self, tree):
2209
# lock the control files not the tree, so that we don't get tree
2210
# on-unlock behaviours, and so that no-one else diddles with the
2211
# tree during upgrade.
2212
tree._control_files.lock_write()
2214
self.init_custom_control_files(tree)
2215
self.update_format(tree)
2217
tree._control_files.unlock()
2219
def init_custom_control_files(self, tree):
2220
"""Initialize custom control files."""
2221
tree._transport.put_bytes('views', '',
2222
mode=tree.bzrdir._get_file_mode())
2224
def update_format(self, tree):
2225
"""Change the format marker."""
2226
tree._transport.put_bytes('format',
2227
self.target_format.get_format_string(),
2228
mode=tree.bzrdir._get_file_mode())