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
42
35
from bzrlib import (
45
conflicts as _mod_conflicts,
55
43
revision as _mod_revision,
64
49
import bzrlib.branch
65
from bzrlib.transport import get_transport
69
from bzrlib import symbol_versioning
70
53
from bzrlib.decorators import needs_read_lock, needs_write_lock
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
54
from bzrlib.filters import filtered_input_file, internal_size_sha_file_byname
55
from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
74
56
import bzrlib.mutabletree
75
57
from bzrlib.mutabletree import needs_tree_write_lock
76
58
from bzrlib.osutils import (
86
from bzrlib.trace import mutter, note
65
from bzrlib.trace import mutter
87
66
from bzrlib.transport.local import LocalTransport
88
67
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,
97
68
from bzrlib.tree import Tree
98
69
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
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.
72
class DirStateWorkingTree(WorkingTree3):
113
73
def __init__(self, basedir,
115
75
_control_files=None,
258
218
return self._dirstate
259
219
local_path = self.bzrdir.get_workingtree_transport(None
260
220
).local_abspath('dirstate')
261
self._dirstate = dirstate.DirState.on_file(local_path)
221
self._dirstate = dirstate.DirState.on_file(local_path,
222
self._sha1_provider())
262
223
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)
264
237
def filter_unversioned_files(self, paths):
265
238
"""Filter out paths that are versioned.
1286
1267
if self._dirty:
1287
1268
raise AssertionError("attempting to write an inventory when the "
1288
1269
"dirstate is dirty will lose pending changes")
1289
self.current_dirstate().set_state_from_inventory(inv)
1290
self._make_dirty(reset_inventory=False)
1291
if self._inventory is not None:
1270
had_inventory = self._inventory is not None
1271
# Setting self._inventory = None forces the dirstate to regenerate the
1272
# working inventory. We do this because self.inventory may be inv, or
1273
# may have been modified, and either case would prevent a clean delta
1275
self._inventory = None
1277
delta = inv._make_delta(self.inventory)
1279
self.apply_inventory_delta(delta)
1292
1281
self._inventory = inv
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"
1285
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1287
def __init__(self, tree):
1290
def sha1(self, abspath):
1291
"""See dirstate.SHA1Provider.sha1()."""
1292
filters = self.tree._content_filter_stack(
1293
self.tree.relpath(osutils.safe_unicode(abspath)))
1294
return internal_size_sha_file_byname(abspath, filters)[1]
1296
def stat_and_sha1(self, abspath):
1297
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1298
filters = self.tree._content_filter_stack(
1299
self.tree.relpath(osutils.safe_unicode(abspath)))
1300
file_obj = file(abspath, 'rb', 65000)
1302
statvalue = os.fstat(file_obj.fileno())
1304
file_obj = filtered_input_file(file_obj, filters)
1305
sha1 = osutils.size_sha_file(file_obj)[1]
1308
return statvalue, sha1
1311
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1312
"""Dirstate working tree that supports content filtering.
1314
The dirstate holds the hash and size of the canonical form of the file,
1315
and most methods must return that.
1318
def _file_content_summary(self, path, stat_result):
1319
# This is to support the somewhat obsolete path_content_summary method
1320
# with content filtering: see
1321
# <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
1323
# If the dirstate cache is up to date and knows the hash and size,
1325
# Otherwise if there are no content filters, return the on-disk size
1326
# and leave the hash blank.
1327
# Otherwise, read and filter the on-disk file and use its size and
1330
# The dirstate doesn't store the size of the canonical form so we
1331
# can't trust it for content-filtered trees. We just return None.
1332
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1333
executable = self._is_executable_from_path_and_stat(path, stat_result)
1334
return ('file', None, executable, dirstate_sha1)
1337
class WorkingTree4(DirStateWorkingTree):
1338
"""This is the Format 4 working tree.
1340
This differs from WorkingTree3 by:
1341
- Having a consolidated internal dirstate, stored in a
1342
randomly-accessible sorted file on disk.
1343
- Not having a regular inventory attribute. One can be synthesized
1344
on demand but this is expensive and should be avoided.
1346
This is new in bzr 0.15.
1350
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1351
"""This is the Format 5 working tree.
1353
This differs from WorkingTree4 by:
1354
- Supporting content filtering.
1356
This is new in bzr 1.11.
1360
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1361
"""This is the Format 6 working tree.
1363
This differs from WorkingTree5 by:
1364
- Supporting a current view that may mask the set of files in a tree
1365
impacted by most user operations.
1367
This is new in bzr 1.14.
1370
def _make_views(self):
1371
return views.PathBasedViews(self)
1374
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1320
1376
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1321
1377
accelerator_tree=None, hardlink=False):
1433
1501
_matchingbzrdir = property(__get_matchingbzrdir)
1504
class WorkingTreeFormat4(DirStateWorkingTreeFormat):
1505
"""The first consolidated dirstate working tree format.
1508
- exists within a metadir controlling .bzr
1509
- includes an explicit version marker for the workingtree control
1510
files, separate from the BzrDir format
1511
- modifies the hash cache format
1512
- is new in bzr 0.15
1513
- uses a LockDir to guard access to it.
1516
upgrade_recommended = False
1518
_tree_class = WorkingTree4
1520
def get_format_string(self):
1521
"""See WorkingTreeFormat.get_format_string()."""
1522
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1524
def get_format_description(self):
1525
"""See WorkingTreeFormat.get_format_description()."""
1526
return "Working tree format 4"
1529
class WorkingTreeFormat5(DirStateWorkingTreeFormat):
1530
"""WorkingTree format supporting content filtering.
1533
upgrade_recommended = False
1535
_tree_class = WorkingTree5
1537
def get_format_string(self):
1538
"""See WorkingTreeFormat.get_format_string()."""
1539
return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1541
def get_format_description(self):
1542
"""See WorkingTreeFormat.get_format_description()."""
1543
return "Working tree format 5"
1545
def supports_content_filtering(self):
1549
class WorkingTreeFormat6(DirStateWorkingTreeFormat):
1550
"""WorkingTree format supporting views.
1553
upgrade_recommended = False
1555
_tree_class = WorkingTree6
1557
def get_format_string(self):
1558
"""See WorkingTreeFormat.get_format_string()."""
1559
return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1561
def get_format_description(self):
1562
"""See WorkingTreeFormat.get_format_description()."""
1563
return "Working tree format 6"
1565
def _init_custom_control_files(self, wt):
1566
"""Subclasses with custom control files should override this method."""
1567
wt._transport.put_bytes('views', '', mode=wt.bzrdir._get_file_mode())
1569
def supports_content_filtering(self):
1572
def supports_views(self):
1436
1576
class DirStateRevisionTree(Tree):
1437
"""A revision tree pulling the inventory from a dirstate."""
1577
"""A revision tree pulling the inventory from a dirstate.
1579
Note that this is one of the historical (ie revision) trees cached in the
1580
dirstate for easy access, not the workingtree.
1439
1583
def __init__(self, dirstate, revision_id, repository):
1440
1584
self._dirstate = dirstate
1625
1773
def get_file(self, file_id, path=None):
1626
1774
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))
1631
1776
def get_file_size(self, file_id):
1632
1777
"""See Tree.get_file_size"""
1633
1778
return self.inventory[file_id].text_size
1635
def get_file_text(self, file_id):
1636
return list(self.iter_files_bytes([(file_id, None)]))[0][1]
1780
def get_file_text(self, file_id, path=None):
1781
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1782
return ''.join(content)
1638
1784
def get_reference_revision(self, file_id, path=None):
1639
1785
return self.inventory[file_id].reference_revision
1715
1861
return ie.executable
1717
def list_files(self, include_root=False):
1863
def list_files(self, include_root=False, from_dir=None, recursive=True):
1718
1864
# We use a standard implementation, because DirStateRevisionTree is
1719
1865
# dealing with one of the parents of the current state
1720
1866
inv = self._get_inventory()
1721
entries = inv.iter_entries()
1722
if self.inventory.root is not None and not include_root:
1867
if from_dir is None:
1870
from_dir_id = inv.path2id(from_dir)
1871
if from_dir_id is None:
1872
# Directory not versioned
1874
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
1875
if inv.root is not None and not include_root and from_dir is None:
1724
1877
for path, entry in entries:
1725
1878
yield path, 'V', entry.kind, entry.file_id, entry
1830
def make_source_parent_tree_compiled_dirstate(klass, test_case, source, target):
1983
def make_source_parent_tree_compiled_dirstate(klass, test_case, source,
1831
1985
from bzrlib.tests.test__dirstate_helpers import \
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
1986
compiled_dirstate_helpers_feature
1987
test_case.requireFeature(compiled_dirstate_helpers_feature)
1988
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
1837
1989
result = klass.make_source_parent_tree(source, target)
1838
1990
result[1]._iter_changes = ProcessEntryC
1931
2081
if not found_versioned:
1932
2082
# none of the indexes was not 'absent' at all ids for this
1934
all_versioned = False
1936
if not all_versioned:
1937
raise errors.PathsNotVersionedError(specific_files)
2084
not_versioned.append(path)
2085
if len(not_versioned) > 0:
2086
raise errors.PathsNotVersionedError(not_versioned)
1938
2087
# -- remove redundancy in supplied specific_files to prevent over-scanning --
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)
2088
search_specific_files = osutils.minimum_path_selection(specific_files)
1945
2090
use_filesystem_for_exec = (sys.platform != 'win32')
1946
2091
iter_changes = self.target._iter_changes(include_unchanged,
1952
2097
def is_compatible(source, target):
1953
2098
# the target must be a dirstate working tree
1954
if not isinstance(target, WorkingTree4):
2099
if not isinstance(target, DirStateWorkingTree):
1956
# the source must be a revtreee or dirstate rev tree.
2101
# the source must be a revtree or dirstate rev tree.
1957
2102
if not isinstance(source,
1958
2103
(revisiontree.RevisionTree, DirStateRevisionTree)):
1960
2105
# the source revid must be in the target dirstate
1961
if not (source._revision_id == NULL_REVISION or
2106
if not (source._revision_id == _mod_revision.NULL_REVISION or
1962
2107
source._revision_id in target.get_parent_ids()):
1963
# TODO: what about ghosts? it may well need to
2108
# TODO: what about ghosts? it may well need to
1964
2109
# check for them explicitly.
2011
2156
tree._transport.put_bytes('format',
2012
2157
self.target_format.get_format_string(),
2013
2158
mode=tree.bzrdir._get_file_mode())
2161
class Converter4to5(object):
2162
"""Perform an in-place upgrade of format 4 to format 5 trees."""
2165
self.target_format = WorkingTreeFormat5()
2167
def convert(self, tree):
2168
# lock the control files not the tree, so that we don't get tree
2169
# on-unlock behaviours, and so that no-one else diddles with the
2170
# tree during upgrade.
2171
tree._control_files.lock_write()
2173
self.update_format(tree)
2175
tree._control_files.unlock()
2177
def update_format(self, tree):
2178
"""Change the format marker."""
2179
tree._transport.put_bytes('format',
2180
self.target_format.get_format_string(),
2181
mode=tree.bzrdir._get_file_mode())
2184
class Converter4or5to6(object):
2185
"""Perform an in-place upgrade of format 4 or 5 to format 6 trees."""
2188
self.target_format = WorkingTreeFormat6()
2190
def convert(self, tree):
2191
# lock the control files not the tree, so that we don't get tree
2192
# on-unlock behaviours, and so that no-one else diddles with the
2193
# tree during upgrade.
2194
tree._control_files.lock_write()
2196
self.init_custom_control_files(tree)
2197
self.update_format(tree)
2199
tree._control_files.unlock()
2201
def init_custom_control_files(self, tree):
2202
"""Initialize custom control files."""
2203
tree._transport.put_bytes('views', '',
2204
mode=tree.bzrdir._get_file_mode())
2206
def update_format(self, tree):
2207
"""Change the format marker."""
2208
tree._transport.put_bytes('format',
2209
self.target_format.get_format_string(),
2210
mode=tree.bzrdir._get_file_mode())