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
34
42
from bzrlib import (
38
45
conflicts as _mod_conflicts,
42
filters as _mod_filters,
45
55
revision as _mod_revision,
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.inventory import Inventory, ROOT_ID, entry_factory
55
from bzrlib.lock import LogicalLockResult
56
from bzrlib.lockable_files import LockableFiles
71
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, entry_factory
72
from bzrlib.lockable_files import LockableFiles, TransportLock
57
73
from bzrlib.lockdir import LockDir
74
import bzrlib.mutabletree
58
75
from bzrlib.mutabletree import needs_tree_write_lock
59
76
from bzrlib.osutils import (
86
from bzrlib.trace import mutter, note
66
87
from bzrlib.transport.local import LocalTransport
67
from bzrlib.tree import (
71
from bzrlib.workingtree import (
78
class DirStateWorkingTree(InventoryWorkingTree):
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,
97
from bzrlib.tree import Tree
98
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.
80
113
def __init__(self, basedir,
229
258
return self._dirstate
230
259
local_path = self.bzrdir.get_workingtree_transport(None
231
260
).local_abspath('dirstate')
232
self._dirstate = dirstate.DirState.on_file(local_path,
233
self._sha1_provider(), self._worth_saving_limit())
261
self._dirstate = dirstate.DirState.on_file(local_path)
234
262
return self._dirstate
236
def _sha1_provider(self):
237
"""A function that returns a SHA1Provider suitable for this tree.
239
:return: None if content filtering is not supported by this tree.
240
Otherwise, a SHA1Provider is returned that sha's the canonical
241
form of files, i.e. after read filters are applied.
243
if self.supports_content_filtering():
244
return ContentFilterAwareSHA1Provider(self)
248
def _worth_saving_limit(self):
249
"""How many hash changes are ok before we must save the dirstate.
251
:return: an integer. -1 means never save.
253
# FIXME: We want a WorkingTreeStack here -- vila 20110812
254
conf = config.BranchStack(self.branch)
255
return conf.get('bzr.workingtree.worth_saving_limit')
257
264
def filter_unversioned_files(self, paths):
258
265
"""Filter out paths that are versioned.
1133
1124
_mod_revision.NULL_REVISION)))
1134
1125
ghosts.append(rev_id)
1135
1126
accepted_revisions.add(rev_id)
1137
if (len(real_trees) == 1
1139
and self.branch.repository._format.fast_deltas
1140
and isinstance(real_trees[0][1],
1141
revisiontree.InventoryRevisionTree)
1142
and self.get_parent_ids()):
1143
rev_id, rev_tree = real_trees[0]
1144
basis_id = self.get_parent_ids()[0]
1145
# There are times when basis_tree won't be in
1146
# self.branch.repository, (switch, for example)
1148
basis_tree = self.branch.repository.revision_tree(basis_id)
1149
except errors.NoSuchRevision:
1150
# Fall back to the set_parent_trees(), since we can't use
1151
# _make_delta if we can't get the RevisionTree
1154
delta = rev_tree.inventory._make_delta(basis_tree.inventory)
1155
dirstate.update_basis_by_delta(delta, rev_id)
1158
dirstate.set_parent_trees(real_trees, ghosts=ghosts)
1127
dirstate.set_parent_trees(real_trees, ghosts=ghosts)
1159
1128
self._make_dirty(reset_inventory=False)
1161
1130
def _set_root_id(self, file_id):
1321
1286
if self._dirty:
1322
1287
raise AssertionError("attempting to write an inventory when the "
1323
1288
"dirstate is dirty will lose pending changes")
1324
had_inventory = self._inventory is not None
1325
# Setting self._inventory = None forces the dirstate to regenerate the
1326
# working inventory. We do this because self.inventory may be inv, or
1327
# may have been modified, and either case would prevent a clean delta
1329
self._inventory = None
1331
delta = inv._make_delta(self.inventory)
1333
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:
1335
1292
self._inventory = inv
1338
@needs_tree_write_lock
1339
def reset_state(self, revision_ids=None):
1340
"""Reset the state of the working tree.
1342
This does a hard-reset to a last-known-good state. This is a way to
1343
fix if something got corrupted (like the .bzr/checkout/dirstate file)
1345
if revision_ids is None:
1346
revision_ids = self.get_parent_ids()
1347
if not revision_ids:
1348
base_tree = self.branch.repository.revision_tree(
1349
_mod_revision.NULL_REVISION)
1352
trees = zip(revision_ids,
1353
self.branch.repository.revision_trees(revision_ids))
1354
base_tree = trees[0][1]
1355
state = self.current_dirstate()
1356
# We don't support ghosts yet
1357
state.set_state_from_scratch(base_tree.inventory, trees, [])
1360
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1362
def __init__(self, tree):
1365
def sha1(self, abspath):
1366
"""See dirstate.SHA1Provider.sha1()."""
1367
filters = self.tree._content_filter_stack(
1368
self.tree.relpath(osutils.safe_unicode(abspath)))
1369
return _mod_filters.internal_size_sha_file_byname(abspath, filters)[1]
1371
def stat_and_sha1(self, abspath):
1372
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1373
filters = self.tree._content_filter_stack(
1374
self.tree.relpath(osutils.safe_unicode(abspath)))
1375
file_obj = file(abspath, 'rb', 65000)
1377
statvalue = os.fstat(file_obj.fileno())
1379
file_obj = _mod_filters.filtered_input_file(file_obj, filters)
1380
sha1 = osutils.size_sha_file(file_obj)[1]
1383
return statvalue, sha1
1386
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1387
"""Dirstate working tree that supports content filtering.
1389
The dirstate holds the hash and size of the canonical form of the file,
1390
and most methods must return that.
1393
def _file_content_summary(self, path, stat_result):
1394
# This is to support the somewhat obsolete path_content_summary method
1395
# with content filtering: see
1396
# <https://bugs.launchpad.net/bzr/+bug/415508>.
1398
# If the dirstate cache is up to date and knows the hash and size,
1400
# Otherwise if there are no content filters, return the on-disk size
1401
# and leave the hash blank.
1402
# Otherwise, read and filter the on-disk file and use its size and
1405
# The dirstate doesn't store the size of the canonical form so we
1406
# can't trust it for content-filtered trees. We just return None.
1407
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1408
executable = self._is_executable_from_path_and_stat(path, stat_result)
1409
return ('file', None, executable, dirstate_sha1)
1412
class WorkingTree4(DirStateWorkingTree):
1413
"""This is the Format 4 working tree.
1415
This differs from WorkingTree by:
1416
- Having a consolidated internal dirstate, stored in a
1417
randomly-accessible sorted file on disk.
1418
- Not having a regular inventory attribute. One can be synthesized
1419
on demand but this is expensive and should be avoided.
1421
This is new in bzr 0.15.
1425
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1426
"""This is the Format 5 working tree.
1428
This differs from WorkingTree4 by:
1429
- Supporting content filtering.
1431
This is new in bzr 1.11.
1435
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1436
"""This is the Format 6 working tree.
1438
This differs from WorkingTree5 by:
1439
- Supporting a current view that may mask the set of files in a tree
1440
impacted by most user operations.
1442
This is new in bzr 1.14.
1445
def _make_views(self):
1446
return views.PathBasedViews(self)
1449
class DirStateWorkingTreeFormat(WorkingTreeFormat):
1451
missing_parent_conflicts = True
1453
supports_versioned_directories = True
1455
_lock_class = LockDir
1456
_lock_file_name = 'lock'
1458
def _open_control_files(self, a_bzrdir):
1459
transport = a_bzrdir.get_workingtree_transport(None)
1460
return LockableFiles(transport, self._lock_file_name,
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"
1463
1320
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1464
1321
accelerator_tree=None, hardlink=False):
1465
1322
"""See WorkingTreeFormat.initialize().
1467
1324
:param revision_id: allows creating a working tree at a different
1468
revision than the branch is at.
1325
revision than the branch is at.
1469
1326
:param accelerator_tree: A tree which can be used for retrieving file
1470
1327
contents more quickly than the revision tree, i.e. a workingtree.
1471
1328
The revision tree will be used for cases where accelerator_tree's
1602
1433
_matchingbzrdir = property(__get_matchingbzrdir)
1605
class WorkingTreeFormat4(DirStateWorkingTreeFormat):
1606
"""The first consolidated dirstate working tree format.
1609
- exists within a metadir controlling .bzr
1610
- includes an explicit version marker for the workingtree control
1611
files, separate from the BzrDir format
1612
- modifies the hash cache format
1613
- is new in bzr 0.15
1614
- uses a LockDir to guard access to it.
1617
upgrade_recommended = False
1619
_tree_class = WorkingTree4
1621
def get_format_string(self):
1622
"""See WorkingTreeFormat.get_format_string()."""
1623
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1625
def get_format_description(self):
1626
"""See WorkingTreeFormat.get_format_description()."""
1627
return "Working tree format 4"
1630
class WorkingTreeFormat5(DirStateWorkingTreeFormat):
1631
"""WorkingTree format supporting content filtering.
1634
upgrade_recommended = False
1636
_tree_class = WorkingTree5
1638
def get_format_string(self):
1639
"""See WorkingTreeFormat.get_format_string()."""
1640
return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1642
def get_format_description(self):
1643
"""See WorkingTreeFormat.get_format_description()."""
1644
return "Working tree format 5"
1646
def supports_content_filtering(self):
1650
class WorkingTreeFormat6(DirStateWorkingTreeFormat):
1651
"""WorkingTree format supporting views.
1654
upgrade_recommended = False
1656
_tree_class = WorkingTree6
1658
def get_format_string(self):
1659
"""See WorkingTreeFormat.get_format_string()."""
1660
return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1662
def get_format_description(self):
1663
"""See WorkingTreeFormat.get_format_description()."""
1664
return "Working tree format 6"
1666
def _init_custom_control_files(self, wt):
1667
"""Subclasses with custom control files should override this method."""
1668
wt._transport.put_bytes('views', '', mode=wt.bzrdir._get_file_mode())
1670
def supports_content_filtering(self):
1673
def supports_views(self):
1677
class DirStateRevisionTree(InventoryTree):
1678
"""A revision tree pulling the inventory from a dirstate.
1680
Note that this is one of the historical (ie revision) trees cached in the
1681
dirstate for easy access, not the workingtree.
1436
class DirStateRevisionTree(Tree):
1437
"""A revision tree pulling the inventory from a dirstate."""
1684
1439
def __init__(self, dirstate, revision_id, repository):
1685
1440
self._dirstate = dirstate
1866
1622
return parent_details[1]
1870
def get_file_revision(self, file_id):
1871
return self.inventory[file_id].revision
1873
1625
def get_file(self, file_id, path=None):
1874
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))
1876
1631
def get_file_size(self, file_id):
1877
1632
"""See Tree.get_file_size"""
1878
1633
return self.inventory[file_id].text_size
1880
def get_file_text(self, file_id, path=None):
1881
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1882
return ''.join(content)
1635
def get_file_text(self, file_id):
1636
return list(self.iter_files_bytes([(file_id, None)]))[0][1]
1884
1638
def get_reference_revision(self, file_id, path=None):
1885
1639
return self.inventory[file_id].reference_revision
1957
1711
def is_executable(self, file_id, path=None):
1958
1712
ie = self.inventory[file_id]
1959
1713
if ie.kind != "file":
1961
1715
return ie.executable
1963
def is_locked(self):
1966
def list_files(self, include_root=False, from_dir=None, recursive=True):
1717
def list_files(self, include_root=False):
1967
1718
# We use a standard implementation, because DirStateRevisionTree is
1968
1719
# dealing with one of the parents of the current state
1969
1720
inv = self._get_inventory()
1970
if from_dir is None:
1973
from_dir_id = inv.path2id(from_dir)
1974
if from_dir_id is None:
1975
# Directory not versioned
1977
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
1978
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:
1980
1724
for path, entry in entries:
1981
1725
yield path, 'V', entry.kind, entry.file_id, entry
1983
1727
def lock_read(self):
1984
"""Lock the tree for a set of operations.
1986
:return: A bzrlib.lock.LogicalLockResult.
1728
"""Lock the tree for a set of operations."""
1988
1729
if not self._locked:
1989
1730
self._repository.lock_read()
1990
1731
if self._dirstate._lock_token is None:
1991
1732
self._dirstate.lock_read()
1992
1733
self._dirstate_locked = True
1993
1734
self._locked += 1
1994
return LogicalLockResult(self.unlock)
1996
1736
def _must_be_locked(self):
1997
1737
if not self._locked:
2263
2011
tree._transport.put_bytes('format',
2264
2012
self.target_format.get_format_string(),
2265
2013
mode=tree.bzrdir._get_file_mode())
2268
class Converter4to5(object):
2269
"""Perform an in-place upgrade of format 4 to format 5 trees."""
2272
self.target_format = WorkingTreeFormat5()
2274
def convert(self, tree):
2275
# lock the control files not the tree, so that we don't get tree
2276
# on-unlock behaviours, and so that no-one else diddles with the
2277
# tree during upgrade.
2278
tree._control_files.lock_write()
2280
self.update_format(tree)
2282
tree._control_files.unlock()
2284
def update_format(self, tree):
2285
"""Change the format marker."""
2286
tree._transport.put_bytes('format',
2287
self.target_format.get_format_string(),
2288
mode=tree.bzrdir._get_file_mode())
2291
class Converter4or5to6(object):
2292
"""Perform an in-place upgrade of format 4 or 5 to format 6 trees."""
2295
self.target_format = WorkingTreeFormat6()
2297
def convert(self, tree):
2298
# lock the control files not the tree, so that we don't get tree
2299
# on-unlock behaviours, and so that no-one else diddles with the
2300
# tree during upgrade.
2301
tree._control_files.lock_write()
2303
self.init_custom_control_files(tree)
2304
self.update_format(tree)
2306
tree._control_files.unlock()
2308
def init_custom_control_files(self, tree):
2309
"""Initialize custom control files."""
2310
tree._transport.put_bytes('views', '',
2311
mode=tree.bzrdir._get_file_mode())
2313
def update_format(self, tree):
2314
"""Change the format marker."""
2315
tree._transport.put_bytes('format',
2316
self.target_format.get_format_string(),
2317
mode=tree.bzrdir._get_file_mode())