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,
65
49
import bzrlib.branch
66
from bzrlib.transport import get_transport
70
from bzrlib import symbol_versioning
71
53
from bzrlib.decorators import needs_read_lock, needs_write_lock
72
54
from bzrlib.filters import filtered_input_file, internal_size_sha_file_byname
73
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, entry_factory
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
464
435
return osutils.lexists(pathjoin(
465
436
self.basedir, row[0].decode('utf8'), row[1].decode('utf8')))
438
def has_or_had_id(self, file_id):
439
state = self.current_dirstate()
440
row, parents = self._get_entry(file_id=file_id)
441
return row is not None
468
444
def id2path(self, file_id):
469
445
"Convert a file-id to a path."
716
692
from_entry = self._get_entry(path=from_rel)
717
693
if from_entry == (None, None):
718
694
raise errors.BzrMoveFailedError(from_rel,to_dir,
719
errors.NotVersionedError(path=str(from_rel)))
695
errors.NotVersionedError(path=from_rel))
721
697
from_id = from_entry[0][2]
722
698
to_rel = pathjoin(to_dir, from_tail)
1051
1027
def set_last_revision(self, new_revision):
1052
1028
"""Change the last revision in the working tree."""
1053
1029
parents = self.get_parent_ids()
1054
if new_revision in (NULL_REVISION, None):
1030
if new_revision in (_mod_revision.NULL_REVISION, None):
1055
1031
if len(parents) >= 2:
1056
1032
raise AssertionError(
1057
1033
"setting the last parent to none with a pending merge is "
1224
1200
# just forget the whole block.
1225
1201
entry_index = 0
1226
1202
while entry_index < len(block[1]):
1227
# Mark this file id as having been removed
1228
1203
entry = block[1][entry_index]
1229
ids_to_unversion.discard(entry[0][2])
1230
if (entry[1][0][0] in 'ar' # don't remove absent or renamed
1232
or not state._make_absent(entry)):
1204
if entry[1][0][0] in 'ar':
1205
# don't remove absent or renamed entries
1233
1206
entry_index += 1
1208
# Mark this file id as having been removed
1209
ids_to_unversion.discard(entry[0][2])
1210
if not state._make_absent(entry):
1211
# The block has not shrunk.
1234
1213
# go to the next block. (At the moment we dont delete empty
1236
1215
block_index += 1
1403
1382
wt.lock_tree_write()
1405
1384
self._init_custom_control_files(wt)
1406
if revision_id in (None, NULL_REVISION):
1385
if revision_id in (None, _mod_revision.NULL_REVISION):
1407
1386
if branch.repository.supports_rich_root():
1408
1387
wt._set_root_id(generate_ids.gen_root_id())
1421
1400
if basis is None:
1422
1401
basis = branch.repository.revision_tree(revision_id)
1423
if revision_id == NULL_REVISION:
1402
if revision_id == _mod_revision.NULL_REVISION:
1424
1403
parents_list = []
1426
1405
parents_list = [(revision_id, basis)]
1440
1419
# Note: do NOT move this logic up higher - using the basis from
1441
1420
# the accelerator tree is still desirable because that can save
1442
1421
# a minute or more of processing on large trees!
1422
# The original tree may not have the same content filters
1423
# applied so we can't safely build the inventory delta from
1443
1425
if wt.supports_content_filtering():
1444
1426
accelerator_tree = None
1427
delta_from_tree = False
1429
delta_from_tree = True
1445
1430
# delta_from_tree is safe even for DirStateRevisionTrees,
1446
1431
# because wt4.apply_inventory_delta does not mutate the input
1447
1432
# inventory entries.
1448
1433
transform.build_tree(basis, wt, accelerator_tree,
1449
hardlink=hardlink, delta_from_tree=True)
1435
delta_from_tree=delta_from_tree)
1838
1824
return ie.executable
1840
def list_files(self, include_root=False):
1826
def list_files(self, include_root=False, from_dir=None, recursive=True):
1841
1827
# We use a standard implementation, because DirStateRevisionTree is
1842
1828
# dealing with one of the parents of the current state
1843
1829
inv = self._get_inventory()
1844
entries = inv.iter_entries()
1845
if self.inventory.root is not None and not include_root:
1830
if from_dir is None:
1833
from_dir_id = inv.path2id(from_dir)
1834
if from_dir_id is None:
1835
# Directory not versioned
1837
entries = inv.iter_entries(from_dir=from_dir_id, recursive=recursive)
1838
if inv.root is not None and not include_root and from_dir is None:
1847
1840
for path, entry in entries:
1848
1841
yield path, 'V', entry.kind, entry.file_id, entry
1956
1949
if not CompiledDirstateHelpersFeature.available():
1957
1950
from bzrlib.tests import UnavailableFeature
1958
1951
raise UnavailableFeature(CompiledDirstateHelpersFeature)
1959
from bzrlib._dirstate_helpers_c import ProcessEntryC
1952
from bzrlib._dirstate_helpers_pyx import ProcessEntryC
1960
1953
result = klass.make_source_parent_tree(source, target)
1961
1954
result[1]._iter_changes = ProcessEntryC
2002
1995
require_versioned, want_unversioned=want_unversioned)
2003
1996
parent_ids = self.target.get_parent_ids()
2004
1997
if not (self.source._revision_id in parent_ids
2005
or self.source._revision_id == NULL_REVISION):
1998
or self.source._revision_id == _mod_revision.NULL_REVISION):
2006
1999
raise AssertionError(
2007
2000
"revision {%s} is not stored in {%s}, but %s "
2008
2001
"can only be used for trees stored in the dirstate"
2009
2002
% (self.source._revision_id, self.target, self.iter_changes))
2010
2003
target_index = 0
2011
if self.source._revision_id == NULL_REVISION:
2004
if self.source._revision_id == _mod_revision.NULL_REVISION:
2012
2005
source_index = None
2013
2006
indices = (target_index,)
2035
2028
state._read_dirblocks_if_needed()
2036
2029
if require_versioned:
2037
2030
# -- check all supplied paths are versioned in a search tree. --
2038
all_versioned = True
2039
2032
for path in specific_files:
2040
2033
path_entries = state._entries_for_path(path)
2041
2034
if not path_entries:
2042
2035
# this specified path is not present at all: error
2043
all_versioned = False
2036
not_versioned.append(path)
2045
2038
found_versioned = False
2046
2039
# for each id at this path
2047
2040
for entry in path_entries:
2054
2047
if not found_versioned:
2055
2048
# none of the indexes was not 'absent' at all ids for this
2057
all_versioned = False
2059
if not all_versioned:
2060
raise errors.PathsNotVersionedError(specific_files)
2050
not_versioned.append(path)
2051
if len(not_versioned) > 0:
2052
raise errors.PathsNotVersionedError(not_versioned)
2061
2053
# -- remove redundancy in supplied specific_files to prevent over-scanning --
2062
2054
search_specific_files = osutils.minimum_path_selection(specific_files)
2077
2069
(revisiontree.RevisionTree, DirStateRevisionTree)):
2079
2071
# the source revid must be in the target dirstate
2080
if not (source._revision_id == NULL_REVISION or
2072
if not (source._revision_id == _mod_revision.NULL_REVISION or
2081
2073
source._revision_id in target.get_parent_ids()):
2082
2074
# TODO: what about ghosts? it may well need to
2083
2075
# check for them explicitly.