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
57
from bzrlib.lockdir import LockDir
71
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, entry_factory
72
import bzrlib.mutabletree
58
73
from bzrlib.mutabletree import needs_tree_write_lock
59
74
from bzrlib.osutils import (
84
from bzrlib.trace import mutter, note
66
85
from bzrlib.transport.local import LocalTransport
67
from bzrlib.tree import (
71
from bzrlib.workingtree import (
78
class DirStateWorkingTree(InventoryWorkingTree):
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,
95
from bzrlib.tree import Tree
96
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
99
class DirStateWorkingTree(WorkingTree3):
80
100
def __init__(self, basedir,
82
102
_control_files=None,
229
245
return self._dirstate
230
246
local_path = self.bzrdir.get_workingtree_transport(None
231
247
).local_abspath('dirstate')
232
self._dirstate = dirstate.DirState.on_file(local_path,
233
self._sha1_provider(), self._worth_saving_limit())
248
self._dirstate = dirstate.DirState.on_file(local_path)
234
249
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
251
def filter_unversioned_files(self, paths):
258
252
"""Filter out paths that are versioned.
1133
1112
_mod_revision.NULL_REVISION)))
1134
1113
ghosts.append(rev_id)
1135
1114
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)
1115
dirstate.set_parent_trees(real_trees, ghosts=ghosts)
1159
1116
self._make_dirty(reset_inventory=False)
1161
1118
def _set_root_id(self, file_id):
1321
1274
if self._dirty:
1322
1275
raise AssertionError("attempting to write an inventory when the "
1323
1276
"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)
1277
self.current_dirstate().set_state_from_inventory(inv)
1278
self._make_dirty(reset_inventory=False)
1279
if self._inventory is not None:
1335
1280
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
1284
class WorkingTree4(DirStateWorkingTree):
1413
1285
"""This is the Format 4 working tree.
1415
This differs from WorkingTree by:
1287
This differs from WorkingTree3 by:
1416
1288
- Having a consolidated internal dirstate, stored in a
1417
1289
randomly-accessible sorted file on disk.
1418
- Not having a regular inventory attribute. One can be synthesized
1290
- Not having a regular inventory attribute. One can be synthesized
1419
1291
on demand but this is expensive and should be avoided.
1421
1293
This is new in bzr 0.15.
1425
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1297
class WorkingTree5(DirStateWorkingTree):
1426
1298
"""This is the Format 5 working tree.
1428
1300
This differs from WorkingTree4 by:
1429
1301
- 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
1302
- Supporting a current view that may mask the set of files in a tree
1440
1303
impacted by most user operations.
1442
This is new in bzr 1.14.
1305
This is new in bzr 1.11.
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,
1309
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1463
1310
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1464
1311
accelerator_tree=None, hardlink=False):
1465
1312
"""See WorkingTreeFormat.initialize().
1467
1314
:param revision_id: allows creating a working tree at a different
1468
revision than the branch is at.
1315
revision than the branch is at.
1469
1316
:param accelerator_tree: A tree which can be used for retrieving file
1470
1317
contents more quickly than the revision tree, i.e. a workingtree.
1471
1318
The revision tree will be used for cases where accelerator_tree's
1957
1750
def is_executable(self, file_id, path=None):
1958
1751
ie = self.inventory[file_id]
1959
1752
if ie.kind != "file":
1961
1754
return ie.executable
1963
def is_locked(self):
1966
def list_files(self, include_root=False, from_dir=None, recursive=True):
1756
def list_files(self, include_root=False):
1967
1757
# We use a standard implementation, because DirStateRevisionTree is
1968
1758
# dealing with one of the parents of the current state
1969
1759
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:
1760
entries = inv.iter_entries()
1761
if self.inventory.root is not None and not include_root:
1980
1763
for path, entry in entries:
1981
1764
yield path, 'V', entry.kind, entry.file_id, entry
1983
1766
def lock_read(self):
1984
"""Lock the tree for a set of operations.
1986
:return: A bzrlib.lock.LogicalLockResult.
1767
"""Lock the tree for a set of operations."""
1988
1768
if not self._locked:
1989
1769
self._repository.lock_read()
1990
1770
if self._dirstate._lock_token is None:
1991
1771
self._dirstate.lock_read()
1992
1772
self._dirstate_locked = True
1993
1773
self._locked += 1
1994
return LogicalLockResult(self.unlock)
1996
1775
def _must_be_locked(self):
1997
1776
if not self._locked:
2274
2061
def convert(self, tree):
2275
2062
# 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
2063
# on-unlock behaviours, and so that no-one else diddles with the
2300
2064
# tree during upgrade.
2301
2065
tree._control_files.lock_write()