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
71
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, entry_factory
72
import bzrlib.mutabletree
56
73
from bzrlib.mutabletree import needs_tree_write_lock
57
74
from bzrlib.osutils import (
64
from bzrlib.trace import mutter
84
from bzrlib.trace import mutter, note
65
85
from bzrlib.transport.local import LocalTransport
66
86
from bzrlib.tree import InterTree
87
from bzrlib.progress import DummyProgress, ProgressPhase
88
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
89
from bzrlib.rio import RioReader, rio_file, Stanza
90
from bzrlib.symbol_versioning import (deprecated_passed,
67
95
from bzrlib.tree import Tree
68
96
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
71
class DirStateWorkingTree(WorkingTree3):
99
class WorkingTree4(WorkingTree3):
100
"""This is the Format 4 working tree.
102
This differs from WorkingTree3 by:
103
- Having a consolidated internal dirstate, stored in a
104
randomly-accessible sorted file on disk.
105
- Not having a regular inventory attribute. One can be synthesized
106
on demand but this is expensive and should be avoided.
108
This is new in bzr 0.15.
72
111
def __init__(self, basedir,
74
113
_control_files=None,
217
256
return self._dirstate
218
257
local_path = self.bzrdir.get_workingtree_transport(None
219
258
).local_abspath('dirstate')
220
self._dirstate = dirstate.DirState.on_file(local_path,
221
self._sha1_provider())
259
self._dirstate = dirstate.DirState.on_file(local_path)
222
260
return self._dirstate
224
def _sha1_provider(self):
225
"""A function that returns a SHA1Provider suitable for this tree.
227
:return: None if content filtering is not supported by this tree.
228
Otherwise, a SHA1Provider is returned that sha's the canonical
229
form of files, i.e. after read filters are applied.
231
if self.supports_content_filtering():
232
return ContentFilterAwareSHA1Provider(self)
236
262
def filter_unversioned_files(self, paths):
237
263
"""Filter out paths that are versioned.
1266
1284
if self._dirty:
1267
1285
raise AssertionError("attempting to write an inventory when the "
1268
1286
"dirstate is dirty will lose pending changes")
1269
had_inventory = self._inventory is not None
1270
# Setting self._inventory = None forces the dirstate to regenerate the
1271
# working inventory. We do this because self.inventory may be inv, or
1272
# may have been modified, and either case would prevent a clean delta
1274
self._inventory = None
1276
delta = inv._make_delta(self.inventory)
1278
self.apply_inventory_delta(delta)
1287
self.current_dirstate().set_state_from_inventory(inv)
1288
self._make_dirty(reset_inventory=False)
1289
if self._inventory is not None:
1280
1290
self._inventory = inv
1284
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1286
def __init__(self, tree):
1289
def sha1(self, abspath):
1290
"""See dirstate.SHA1Provider.sha1()."""
1291
filters = self.tree._content_filter_stack(
1292
self.tree.relpath(osutils.safe_unicode(abspath)))
1293
return internal_size_sha_file_byname(abspath, filters)[1]
1295
def stat_and_sha1(self, abspath):
1296
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1297
filters = self.tree._content_filter_stack(
1298
self.tree.relpath(osutils.safe_unicode(abspath)))
1299
file_obj = file(abspath, 'rb', 65000)
1301
statvalue = os.fstat(file_obj.fileno())
1303
file_obj = filtered_input_file(file_obj, filters)
1304
sha1 = osutils.size_sha_file(file_obj)[1]
1307
return statvalue, sha1
1310
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1311
"""Dirstate working tree that supports content filtering.
1313
The dirstate holds the hash and size of the canonical form of the file,
1314
and most methods must return that.
1317
def _file_content_summary(self, path, stat_result):
1318
# This is to support the somewhat obsolete path_content_summary method
1319
# with content filtering: see
1320
# <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
1322
# If the dirstate cache is up to date and knows the hash and size,
1324
# Otherwise if there are no content filters, return the on-disk size
1325
# and leave the hash blank.
1326
# Otherwise, read and filter the on-disk file and use its size and
1329
# The dirstate doesn't store the size of the canonical form so we
1330
# can't trust it for content-filtered trees. We just return None.
1331
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1332
executable = self._is_executable_from_path_and_stat(path, stat_result)
1333
return ('file', None, executable, dirstate_sha1)
1336
class WorkingTree4(DirStateWorkingTree):
1337
"""This is the Format 4 working tree.
1339
This differs from WorkingTree3 by:
1340
- Having a consolidated internal dirstate, stored in a
1341
randomly-accessible sorted file on disk.
1342
- Not having a regular inventory attribute. One can be synthesized
1343
on demand but this is expensive and should be avoided.
1345
This is new in bzr 0.15.
1349
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1350
"""This is the Format 5 working tree.
1352
This differs from WorkingTree4 by:
1353
- Supporting content filtering.
1355
This is new in bzr 1.11.
1359
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1360
"""This is the Format 6 working tree.
1362
This differs from WorkingTree5 by:
1363
- Supporting a current view that may mask the set of files in a tree
1364
impacted by most user operations.
1366
This is new in bzr 1.14.
1369
def _make_views(self):
1370
return views.PathBasedViews(self)
1373
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1294
class WorkingTreeFormat4(WorkingTreeFormat3):
1295
"""The first consolidated dirstate working tree format.
1298
- exists within a metadir controlling .bzr
1299
- includes an explicit version marker for the workingtree control
1300
files, separate from the BzrDir format
1301
- modifies the hash cache format
1302
- is new in bzr 0.15
1303
- uses a LockDir to guard access to it.
1306
upgrade_recommended = False
1308
_tree_class = WorkingTree4
1310
def get_format_string(self):
1311
"""See WorkingTreeFormat.get_format_string()."""
1312
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1314
def get_format_description(self):
1315
"""See WorkingTreeFormat.get_format_description()."""
1316
return "Working tree format 4"
1375
1318
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1376
1319
accelerator_tree=None, hardlink=False):
1500
1431
_matchingbzrdir = property(__get_matchingbzrdir)
1503
class WorkingTreeFormat4(DirStateWorkingTreeFormat):
1504
"""The first consolidated dirstate working tree format.
1507
- exists within a metadir controlling .bzr
1508
- includes an explicit version marker for the workingtree control
1509
files, separate from the BzrDir format
1510
- modifies the hash cache format
1511
- is new in bzr 0.15
1512
- uses a LockDir to guard access to it.
1515
upgrade_recommended = False
1517
_tree_class = WorkingTree4
1519
def get_format_string(self):
1520
"""See WorkingTreeFormat.get_format_string()."""
1521
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1523
def get_format_description(self):
1524
"""See WorkingTreeFormat.get_format_description()."""
1525
return "Working tree format 4"
1528
class WorkingTreeFormat5(DirStateWorkingTreeFormat):
1529
"""WorkingTree format supporting content filtering.
1532
upgrade_recommended = False
1534
_tree_class = WorkingTree5
1536
def get_format_string(self):
1537
"""See WorkingTreeFormat.get_format_string()."""
1538
return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1540
def get_format_description(self):
1541
"""See WorkingTreeFormat.get_format_description()."""
1542
return "Working tree format 5"
1544
def supports_content_filtering(self):
1548
class WorkingTreeFormat6(DirStateWorkingTreeFormat):
1549
"""WorkingTree format supporting views.
1552
upgrade_recommended = False
1554
_tree_class = WorkingTree6
1556
def get_format_string(self):
1557
"""See WorkingTreeFormat.get_format_string()."""
1558
return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1560
def get_format_description(self):
1561
"""See WorkingTreeFormat.get_format_description()."""
1562
return "Working tree format 6"
1564
def _init_custom_control_files(self, wt):
1565
"""Subclasses with custom control files should override this method."""
1566
wt._transport.put_bytes('views', '', mode=wt.bzrdir._get_file_mode())
1568
def supports_content_filtering(self):
1571
def supports_views(self):
1575
1434
class DirStateRevisionTree(Tree):
1576
"""A revision tree pulling the inventory from a dirstate.
1578
Note that this is one of the historical (ie revision) trees cached in the
1579
dirstate for easy access, not the workingtree.
1435
"""A revision tree pulling the inventory from a dirstate."""
1582
1437
def __init__(self, dirstate, revision_id, repository):
1583
1438
self._dirstate = dirstate
1860
1710
return ie.executable
1862
def list_files(self, include_root=False, from_dir=None, recursive=True):
1712
def list_files(self, include_root=False):
1863
1713
# We use a standard implementation, because DirStateRevisionTree is
1864
1714
# dealing with one of the parents of the current state
1865
1715
inv = self._get_inventory()
1866
if from_dir is None:
1869
from_dir_id = inv.path2id(from_dir)
1870
if from_dir_id is None:
1871
# Directory not versioned
1873
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
1874
if inv.root is not None and not include_root and from_dir is None:
1716
entries = inv.iter_entries()
1717
if self.inventory.root is not None and not include_root:
1876
1719
for path, entry in entries:
1877
1720
yield path, 'V', entry.kind, entry.file_id, entry
1982
def make_source_parent_tree_compiled_dirstate(klass, test_case, source,
1825
def make_source_parent_tree_compiled_dirstate(klass, test_case, source, target):
1984
1826
from bzrlib.tests.test__dirstate_helpers import \
1985
compiled_dirstate_helpers_feature
1986
test_case.requireFeature(compiled_dirstate_helpers_feature)
1987
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
1827
CompiledDirstateHelpersFeature
1828
if not CompiledDirstateHelpersFeature.available():
1829
from bzrlib.tests import UnavailableFeature
1830
raise UnavailableFeature(CompiledDirstateHelpersFeature)
1831
from bzrlib._dirstate_helpers_c import ProcessEntryC
1988
1832
result = klass.make_source_parent_tree(source, target)
1989
1833
result[1]._iter_changes = ProcessEntryC
2080
1926
if not found_versioned:
2081
1927
# none of the indexes was not 'absent' at all ids for this
2083
not_versioned.append(path)
2084
if len(not_versioned) > 0:
2085
raise errors.PathsNotVersionedError(not_versioned)
1929
all_versioned = False
1931
if not all_versioned:
1932
raise errors.PathsNotVersionedError(specific_files)
2086
1933
# -- remove redundancy in supplied specific_files to prevent over-scanning --
2087
search_specific_files = osutils.minimum_path_selection(specific_files)
1934
for path in specific_files:
1935
other_specific_files = specific_files.difference(set([path]))
1936
if not osutils.is_inside_any(other_specific_files, path):
1937
# this is a top level path, we must check it.
1938
search_specific_files.add(path)
2089
1940
use_filesystem_for_exec = (sys.platform != 'win32')
2090
1941
iter_changes = self.target._iter_changes(include_unchanged,
2096
1947
def is_compatible(source, target):
2097
1948
# the target must be a dirstate working tree
2098
if not isinstance(target, DirStateWorkingTree):
1949
if not isinstance(target, WorkingTree4):
2100
# the source must be a revtree or dirstate rev tree.
1951
# the source must be a revtreee or dirstate rev tree.
2101
1952
if not isinstance(source,
2102
1953
(revisiontree.RevisionTree, DirStateRevisionTree)):
2104
1955
# the source revid must be in the target dirstate
2105
if not (source._revision_id == _mod_revision.NULL_REVISION or
1956
if not (source._revision_id == NULL_REVISION or
2106
1957
source._revision_id in target.get_parent_ids()):
2107
# TODO: what about ghosts? it may well need to
1958
# TODO: what about ghosts? it may well need to
2108
1959
# check for them explicitly.
2155
2006
tree._transport.put_bytes('format',
2156
2007
self.target_format.get_format_string(),
2157
2008
mode=tree.bzrdir._get_file_mode())
2160
class Converter4to5(object):
2161
"""Perform an in-place upgrade of format 4 to format 5 trees."""
2164
self.target_format = WorkingTreeFormat5()
2166
def convert(self, tree):
2167
# lock the control files not the tree, so that we don't get tree
2168
# on-unlock behaviours, and so that no-one else diddles with the
2169
# tree during upgrade.
2170
tree._control_files.lock_write()
2172
self.update_format(tree)
2174
tree._control_files.unlock()
2176
def update_format(self, tree):
2177
"""Change the format marker."""
2178
tree._transport.put_bytes('format',
2179
self.target_format.get_format_string(),
2180
mode=tree.bzrdir._get_file_mode())
2183
class Converter4or5to6(object):
2184
"""Perform an in-place upgrade of format 4 or 5 to format 6 trees."""
2187
self.target_format = WorkingTreeFormat6()
2189
def convert(self, tree):
2190
# lock the control files not the tree, so that we don't get tree
2191
# on-unlock behaviours, and so that no-one else diddles with the
2192
# tree during upgrade.
2193
tree._control_files.lock_write()
2195
self.init_custom_control_files(tree)
2196
self.update_format(tree)
2198
tree._control_files.unlock()
2200
def init_custom_control_files(self, tree):
2201
"""Initialize custom control files."""
2202
tree._transport.put_bytes('views', '',
2203
mode=tree.bzrdir._get_file_mode())
2205
def update_format(self, tree):
2206
"""Change the format marker."""
2207
tree._transport.put_bytes('format',
2208
self.target_format.get_format_string(),
2209
mode=tree.bzrdir._get_file_mode())