22
22
WorkingTree.open(dir).
25
from __future__ import absolute_import
25
27
from cStringIO import StringIO
29
31
from bzrlib.lazy_import import lazy_import
30
32
lazy_import(globals(), """
31
from bisect import bisect_left
33
from copy import deepcopy
42
36
from bzrlib import (
45
40
conflicts as _mod_conflicts,
44
filters as _mod_filters,
55
47
revision as _mod_revision,
65
from bzrlib.transport import get_transport
69
from bzrlib import symbol_versioning
70
55
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
56
from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
57
from bzrlib.lock import LogicalLockResult
58
from bzrlib.lockable_files import LockableFiles
73
59
from bzrlib.lockdir import LockDir
74
import bzrlib.mutabletree
75
from bzrlib.mutabletree import needs_tree_write_lock
60
from bzrlib.mutabletree import (
62
needs_tree_write_lock,
76
64
from bzrlib.osutils import (
86
from bzrlib.trace import mutter, note
71
from bzrlib.symbol_versioning import (
87
75
from bzrlib.transport.local import LocalTransport
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.
76
from bzrlib.tree import (
80
from bzrlib.workingtree import (
83
WorkingTreeFormatMetaDir,
87
class DirStateWorkingTree(InventoryWorkingTree):
113
89
def __init__(self, basedir,
258
238
return self._dirstate
259
239
local_path = self.bzrdir.get_workingtree_transport(None
260
240
).local_abspath('dirstate')
261
self._dirstate = dirstate.DirState.on_file(local_path)
241
self._dirstate = dirstate.DirState.on_file(local_path,
242
self._sha1_provider(), self._worth_saving_limit())
262
243
return self._dirstate
245
def _sha1_provider(self):
246
"""A function that returns a SHA1Provider suitable for this tree.
248
:return: None if content filtering is not supported by this tree.
249
Otherwise, a SHA1Provider is returned that sha's the canonical
250
form of files, i.e. after read filters are applied.
252
if self.supports_content_filtering():
253
return ContentFilterAwareSHA1Provider(self)
257
def _worth_saving_limit(self):
258
"""How many hash changes are ok before we must save the dirstate.
260
:return: an integer. -1 means never save.
262
# FIXME: We want a WorkingTreeStack here -- vila 20110812
263
conf = config.BranchStack(self.branch)
264
return conf.get('bzr.workingtree.worth_saving_limit')
264
266
def filter_unversioned_files(self, paths):
265
267
"""Filter out paths that are versioned.
480
492
return False # Missing entries are not executable
481
493
return entry[1][0][3] # Executable?
483
if not osutils.supports_executable():
484
def is_executable(self, file_id, path=None):
485
"""Test if a file is executable or not.
495
def is_executable(self, file_id, path=None):
496
"""Test if a file is executable or not.
487
Note: The caller is expected to take a read-lock before calling this.
498
Note: The caller is expected to take a read-lock before calling this.
500
if not self._supports_executable():
489
501
entry = self._get_entry(file_id=file_id, path=path)
490
502
if entry == (None, None):
492
504
return entry[1][0][3]
494
_is_executable_from_path_and_stat = \
495
_is_executable_from_path_and_stat_from_basis
497
def is_executable(self, file_id, path=None):
498
"""Test if a file is executable or not.
500
Note: The caller is expected to take a read-lock before calling this.
502
506
self._must_be_locked()
504
508
path = self.id2path(file_id)
505
mode = os.lstat(self.abspath(path)).st_mode
509
mode = osutils.lstat(self.abspath(path)).st_mode
506
510
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
508
512
def all_file_ids(self):
1124
1143
_mod_revision.NULL_REVISION)))
1125
1144
ghosts.append(rev_id)
1126
1145
accepted_revisions.add(rev_id)
1127
dirstate.set_parent_trees(real_trees, ghosts=ghosts)
1147
if (len(real_trees) == 1
1149
and self.branch.repository._format.fast_deltas
1150
and isinstance(real_trees[0][1],
1151
revisiontree.InventoryRevisionTree)
1152
and self.get_parent_ids()):
1153
rev_id, rev_tree = real_trees[0]
1154
basis_id = self.get_parent_ids()[0]
1155
# There are times when basis_tree won't be in
1156
# self.branch.repository, (switch, for example)
1158
basis_tree = self.branch.repository.revision_tree(basis_id)
1159
except errors.NoSuchRevision:
1160
# Fall back to the set_parent_trees(), since we can't use
1161
# _make_delta if we can't get the RevisionTree
1164
delta = rev_tree.root_inventory._make_delta(
1165
basis_tree.root_inventory)
1166
dirstate.update_basis_by_delta(delta, rev_id)
1169
dirstate.set_parent_trees(real_trees, ghosts=ghosts)
1128
1170
self._make_dirty(reset_inventory=False)
1130
1172
def _set_root_id(self, file_id):
1286
1332
if self._dirty:
1287
1333
raise AssertionError("attempting to write an inventory when the "
1288
1334
"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:
1335
had_inventory = self._inventory is not None
1336
# Setting self._inventory = None forces the dirstate to regenerate the
1337
# working inventory. We do this because self.inventory may be inv, or
1338
# may have been modified, and either case would prevent a clean delta
1340
self._inventory = None
1342
delta = inv._make_delta(self.root_inventory)
1344
self.apply_inventory_delta(delta)
1292
1346
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"
1349
@needs_tree_write_lock
1350
def reset_state(self, revision_ids=None):
1351
"""Reset the state of the working tree.
1353
This does a hard-reset to a last-known-good state. This is a way to
1354
fix if something got corrupted (like the .bzr/checkout/dirstate file)
1356
if revision_ids is None:
1357
revision_ids = self.get_parent_ids()
1358
if not revision_ids:
1359
base_tree = self.branch.repository.revision_tree(
1360
_mod_revision.NULL_REVISION)
1363
trees = zip(revision_ids,
1364
self.branch.repository.revision_trees(revision_ids))
1365
base_tree = trees[0][1]
1366
state = self.current_dirstate()
1367
# We don't support ghosts yet
1368
state.set_state_from_scratch(base_tree.root_inventory, trees, [])
1371
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1373
def __init__(self, tree):
1376
def sha1(self, abspath):
1377
"""See dirstate.SHA1Provider.sha1()."""
1378
filters = self.tree._content_filter_stack(
1379
self.tree.relpath(osutils.safe_unicode(abspath)))
1380
return _mod_filters.internal_size_sha_file_byname(abspath, filters)[1]
1382
def stat_and_sha1(self, abspath):
1383
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1384
filters = self.tree._content_filter_stack(
1385
self.tree.relpath(osutils.safe_unicode(abspath)))
1386
file_obj = file(abspath, 'rb', 65000)
1388
statvalue = os.fstat(file_obj.fileno())
1390
file_obj = _mod_filters.filtered_input_file(file_obj, filters)
1391
sha1 = osutils.size_sha_file(file_obj)[1]
1394
return statvalue, sha1
1397
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1398
"""Dirstate working tree that supports content filtering.
1400
The dirstate holds the hash and size of the canonical form of the file,
1401
and most methods must return that.
1404
def _file_content_summary(self, path, stat_result):
1405
# This is to support the somewhat obsolete path_content_summary method
1406
# with content filtering: see
1407
# <https://bugs.launchpad.net/bzr/+bug/415508>.
1409
# If the dirstate cache is up to date and knows the hash and size,
1411
# Otherwise if there are no content filters, return the on-disk size
1412
# and leave the hash blank.
1413
# Otherwise, read and filter the on-disk file and use its size and
1416
# The dirstate doesn't store the size of the canonical form so we
1417
# can't trust it for content-filtered trees. We just return None.
1418
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1419
executable = self._is_executable_from_path_and_stat(path, stat_result)
1420
return ('file', None, executable, dirstate_sha1)
1423
class WorkingTree4(DirStateWorkingTree):
1424
"""This is the Format 4 working tree.
1426
This differs from WorkingTree by:
1427
- Having a consolidated internal dirstate, stored in a
1428
randomly-accessible sorted file on disk.
1429
- Not having a regular inventory attribute. One can be synthesized
1430
on demand but this is expensive and should be avoided.
1432
This is new in bzr 0.15.
1436
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1437
"""This is the Format 5 working tree.
1439
This differs from WorkingTree4 by:
1440
- Supporting content filtering.
1442
This is new in bzr 1.11.
1446
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1447
"""This is the Format 6 working tree.
1449
This differs from WorkingTree5 by:
1450
- Supporting a current view that may mask the set of files in a tree
1451
impacted by most user operations.
1453
This is new in bzr 1.14.
1456
def _make_views(self):
1457
return views.PathBasedViews(self)
1460
class DirStateWorkingTreeFormat(WorkingTreeFormatMetaDir):
1462
missing_parent_conflicts = True
1464
supports_versioned_directories = True
1466
_lock_class = LockDir
1467
_lock_file_name = 'lock'
1469
def _open_control_files(self, a_bzrdir):
1470
transport = a_bzrdir.get_workingtree_transport(None)
1471
return LockableFiles(transport, self._lock_file_name,
1320
1474
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1321
1475
accelerator_tree=None, hardlink=False):
1322
1476
"""See WorkingTreeFormat.initialize().
1324
1478
:param revision_id: allows creating a working tree at a different
1325
revision than the branch is at.
1479
revision than the branch is at.
1326
1480
:param accelerator_tree: A tree which can be used for retrieving file
1327
1481
contents more quickly than the revision tree, i.e. a workingtree.
1328
1482
The revision tree will be used for cases where accelerator_tree's
1433
1615
_matchingbzrdir = property(__get_matchingbzrdir)
1436
class DirStateRevisionTree(Tree):
1437
"""A revision tree pulling the inventory from a dirstate."""
1618
class WorkingTreeFormat4(DirStateWorkingTreeFormat):
1619
"""The first consolidated dirstate working tree format.
1622
- exists within a metadir controlling .bzr
1623
- includes an explicit version marker for the workingtree control
1624
files, separate from the ControlDir format
1625
- modifies the hash cache format
1626
- is new in bzr 0.15
1627
- uses a LockDir to guard access to it.
1630
upgrade_recommended = False
1632
_tree_class = WorkingTree4
1635
def get_format_string(cls):
1636
"""See WorkingTreeFormat.get_format_string()."""
1637
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1639
def get_format_description(self):
1640
"""See WorkingTreeFormat.get_format_description()."""
1641
return "Working tree format 4"
1644
class WorkingTreeFormat5(DirStateWorkingTreeFormat):
1645
"""WorkingTree format supporting content filtering.
1648
upgrade_recommended = False
1650
_tree_class = WorkingTree5
1653
def get_format_string(cls):
1654
"""See WorkingTreeFormat.get_format_string()."""
1655
return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1657
def get_format_description(self):
1658
"""See WorkingTreeFormat.get_format_description()."""
1659
return "Working tree format 5"
1661
def supports_content_filtering(self):
1665
class WorkingTreeFormat6(DirStateWorkingTreeFormat):
1666
"""WorkingTree format supporting views.
1669
upgrade_recommended = False
1671
_tree_class = WorkingTree6
1674
def get_format_string(cls):
1675
"""See WorkingTreeFormat.get_format_string()."""
1676
return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1678
def get_format_description(self):
1679
"""See WorkingTreeFormat.get_format_description()."""
1680
return "Working tree format 6"
1682
def _init_custom_control_files(self, wt):
1683
"""Subclasses with custom control files should override this method."""
1684
wt._transport.put_bytes('views', '', mode=wt.bzrdir._get_file_mode())
1686
def supports_content_filtering(self):
1689
def supports_views(self):
1693
class DirStateRevisionTree(InventoryTree):
1694
"""A revision tree pulling the inventory from a dirstate.
1696
Note that this is one of the historical (ie revision) trees cached in the
1697
dirstate for easy access, not the workingtree.
1439
1700
def __init__(self, dirstate, revision_id, repository):
1440
1701
self._dirstate = dirstate
1622
1882
return parent_details[1]
1886
def get_file_revision(self, file_id):
1887
inv, inv_file_id = self._unpack_file_id(file_id)
1888
return inv[inv_file_id].revision
1625
1890
def get_file(self, file_id, path=None):
1626
1891
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
1893
def get_file_size(self, file_id):
1632
1894
"""See Tree.get_file_size"""
1633
return self.inventory[file_id].text_size
1895
inv, inv_file_id = self._unpack_file_id(file_id)
1896
return inv[inv_file_id].text_size
1635
def get_file_text(self, file_id):
1636
return list(self.iter_files_bytes([(file_id, None)]))[0][1]
1898
def get_file_text(self, file_id, path=None):
1899
_, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1900
return ''.join(content)
1638
1902
def get_reference_revision(self, file_id, path=None):
1639
return self.inventory[file_id].reference_revision
1903
inv, inv_file_id = self._unpack_file_id(file_id)
1904
return inv[inv_file_id].reference_revision
1641
1906
def iter_files_bytes(self, desired_files):
1642
1907
"""See Tree.iter_files_bytes.
1653
1918
return self._repository.iter_files_bytes(repo_desired_files)
1655
def get_symlink_target(self, file_id):
1920
def get_symlink_target(self, file_id, path=None):
1656
1921
entry = self._get_entry(file_id=file_id)
1657
1922
parent_index = self._get_parent_index()
1658
1923
if entry[1][parent_index][0] != 'l':
1661
# At present, none of the tree implementations supports non-ascii
1662
# symlink targets. So we will just assume that the dirstate path is
1664
return entry[1][parent_index][1]
1926
target = entry[1][parent_index][1]
1927
target = target.decode('utf8')
1666
1930
def get_revision_id(self):
1667
1931
"""Return the revision id for this tree."""
1668
1932
return self._revision_id
1670
def _get_inventory(self):
1934
def _get_root_inventory(self):
1671
1935
if self._inventory is not None:
1672
1936
return self._inventory
1673
1937
self._must_be_locked()
1674
1938
self._generate_inventory()
1675
1939
return self._inventory
1941
root_inventory = property(_get_root_inventory,
1942
doc="Inventory of this Tree")
1944
@deprecated_method(deprecated_in((2, 5, 0)))
1945
def _get_inventory(self):
1946
return self.root_inventory
1677
1948
inventory = property(_get_inventory,
1678
1949
doc="Inventory of this Tree")
1709
1981
return (kind, None, None, None)
1711
1983
def is_executable(self, file_id, path=None):
1712
ie = self.inventory[file_id]
1984
inv, inv_file_id = self._unpack_file_id(file_id)
1985
ie = inv[inv_file_id]
1713
1986
if ie.kind != "file":
1715
1988
return ie.executable
1717
def list_files(self, include_root=False):
1990
def is_locked(self):
1993
def list_files(self, include_root=False, from_dir=None, recursive=True):
1718
1994
# We use a standard implementation, because DirStateRevisionTree is
1719
1995
# dealing with one of the parents of the current state
1720
inv = self._get_inventory()
1721
entries = inv.iter_entries()
1722
if self.inventory.root is not None and not include_root:
1996
if from_dir is None:
1997
inv = self.root_inventory
2000
inv, from_dir_id = self._path2inv_file_id(from_dir)
2001
if from_dir_id is None:
2002
# Directory not versioned
2004
# FIXME: Support nested trees
2005
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
2006
if inv.root is not None and not include_root and from_dir is None:
1724
2008
for path, entry in entries:
1725
2009
yield path, 'V', entry.kind, entry.file_id, entry
1727
2011
def lock_read(self):
1728
"""Lock the tree for a set of operations."""
2012
"""Lock the tree for a set of operations.
2014
:return: A bzrlib.lock.LogicalLockResult.
1729
2016
if not self._locked:
1730
2017
self._repository.lock_read()
1731
2018
if self._dirstate._lock_token is None:
1732
2019
self._dirstate.lock_read()
1733
2020
self._dirstate_locked = True
1734
2021
self._locked += 1
2022
return LogicalLockResult(self.unlock)
1736
2024
def _must_be_locked(self):
1737
2025
if not self._locked:
2009
2289
def update_format(self, tree):
2010
2290
"""Change the format marker."""
2011
2291
tree._transport.put_bytes('format',
2012
self.target_format.get_format_string(),
2292
self.target_format.as_string(),
2293
mode=tree.bzrdir._get_file_mode())
2296
class Converter4to5(object):
2297
"""Perform an in-place upgrade of format 4 to format 5 trees."""
2300
self.target_format = WorkingTreeFormat5()
2302
def convert(self, tree):
2303
# lock the control files not the tree, so that we don't get tree
2304
# on-unlock behaviours, and so that no-one else diddles with the
2305
# tree during upgrade.
2306
tree._control_files.lock_write()
2308
self.update_format(tree)
2310
tree._control_files.unlock()
2312
def update_format(self, tree):
2313
"""Change the format marker."""
2314
tree._transport.put_bytes('format',
2315
self.target_format.as_string(),
2316
mode=tree.bzrdir._get_file_mode())
2319
class Converter4or5to6(object):
2320
"""Perform an in-place upgrade of format 4 or 5 to format 6 trees."""
2323
self.target_format = WorkingTreeFormat6()
2325
def convert(self, tree):
2326
# lock the control files not the tree, so that we don't get tree
2327
# on-unlock behaviours, and so that no-one else diddles with the
2328
# tree during upgrade.
2329
tree._control_files.lock_write()
2331
self.init_custom_control_files(tree)
2332
self.update_format(tree)
2334
tree._control_files.unlock()
2336
def init_custom_control_files(self, tree):
2337
"""Initialize custom control files."""
2338
tree._transport.put_bytes('views', '',
2339
mode=tree.bzrdir._get_file_mode())
2341
def update_format(self, tree):
2342
"""Change the format marker."""
2343
tree._transport.put_bytes('format',
2344
self.target_format.as_string(),
2013
2345
mode=tree.bzrdir._get_file_mode())