1263
1224
@needs_tree_write_lock
1264
1225
def _write_inventory(self, inv):
1265
1226
"""Write inventory as the current inventory."""
1267
raise AssertionError("attempting to write an inventory when the "
1268
"dirstate is dirty will lose pending changes")
1269
had_inventory = self._inventory is not None
1270
# Setting self._inventory = None forces the dirstate to regenerate the
1271
# working inventory. We do this because self.inventory may be inv, or
1272
# may have been modified, and either case would prevent a clean delta
1274
self._inventory = None
1276
delta = inv._make_delta(self.inventory)
1278
self.apply_inventory_delta(delta)
1227
assert not self._dirty, ("attempting to write an inventory when the "
1228
"dirstate is dirty will cause data loss")
1229
self.current_dirstate().set_state_from_inventory(inv)
1230
self._make_dirty(reset_inventory=False)
1231
if self._inventory is not None:
1280
1232
self._inventory = inv
1284
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1286
def __init__(self, tree):
1289
def sha1(self, abspath):
1290
"""See dirstate.SHA1Provider.sha1()."""
1291
filters = self.tree._content_filter_stack(
1292
self.tree.relpath(osutils.safe_unicode(abspath)))
1293
return internal_size_sha_file_byname(abspath, filters)[1]
1295
def stat_and_sha1(self, abspath):
1296
"""See dirstate.SHA1Provider.stat_and_sha1()."""
1297
filters = self.tree._content_filter_stack(
1298
self.tree.relpath(osutils.safe_unicode(abspath)))
1299
file_obj = file(abspath, 'rb', 65000)
1301
statvalue = os.fstat(file_obj.fileno())
1303
file_obj = filtered_input_file(file_obj, filters)
1304
sha1 = osutils.size_sha_file(file_obj)[1]
1307
return statvalue, sha1
1310
class ContentFilteringDirStateWorkingTree(DirStateWorkingTree):
1311
"""Dirstate working tree that supports content filtering.
1313
The dirstate holds the hash and size of the canonical form of the file,
1314
and most methods must return that.
1317
def _file_content_summary(self, path, stat_result):
1318
# This is to support the somewhat obsolete path_content_summary method
1319
# with content filtering: see
1320
# <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
1322
# If the dirstate cache is up to date and knows the hash and size,
1324
# Otherwise if there are no content filters, return the on-disk size
1325
# and leave the hash blank.
1326
# Otherwise, read and filter the on-disk file and use its size and
1329
# The dirstate doesn't store the size of the canonical form so we
1330
# can't trust it for content-filtered trees. We just return None.
1331
dirstate_sha1 = self._dirstate.sha1_from_stat(path, stat_result)
1332
executable = self._is_executable_from_path_and_stat(path, stat_result)
1333
return ('file', None, executable, dirstate_sha1)
1336
class WorkingTree4(DirStateWorkingTree):
1337
"""This is the Format 4 working tree.
1339
This differs from WorkingTree3 by:
1340
- Having a consolidated internal dirstate, stored in a
1341
randomly-accessible sorted file on disk.
1342
- Not having a regular inventory attribute. One can be synthesized
1343
on demand but this is expensive and should be avoided.
1345
This is new in bzr 0.15.
1349
class WorkingTree5(ContentFilteringDirStateWorkingTree):
1350
"""This is the Format 5 working tree.
1352
This differs from WorkingTree4 by:
1353
- Supporting content filtering.
1355
This is new in bzr 1.11.
1359
class WorkingTree6(ContentFilteringDirStateWorkingTree):
1360
"""This is the Format 6 working tree.
1362
This differs from WorkingTree5 by:
1363
- Supporting a current view that may mask the set of files in a tree
1364
impacted by most user operations.
1366
This is new in bzr 1.14.
1369
def _make_views(self):
1370
return views.PathBasedViews(self)
1373
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1375
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1376
accelerator_tree=None, hardlink=False):
1236
class WorkingTreeFormat4(WorkingTreeFormat3):
1237
"""The first consolidated dirstate working tree format.
1240
- exists within a metadir controlling .bzr
1241
- includes an explicit version marker for the workingtree control
1242
files, separate from the BzrDir format
1243
- modifies the hash cache format
1244
- is new in bzr 0.15
1245
- uses a LockDir to guard access to it.
1248
upgrade_recommended = False
1250
def get_format_string(self):
1251
"""See WorkingTreeFormat.get_format_string()."""
1252
return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1254
def get_format_description(self):
1255
"""See WorkingTreeFormat.get_format_description()."""
1256
return "Working tree format 4"
1258
def initialize(self, a_bzrdir, revision_id=None, from_branch=None):
1377
1259
"""See WorkingTreeFormat.initialize().
1379
1261
:param revision_id: allows creating a working tree at a different
1380
1262
revision than the branch is at.
1381
:param accelerator_tree: A tree which can be used for retrieving file
1382
contents more quickly than the revision tree, i.e. a workingtree.
1383
The revision tree will be used for cases where accelerator_tree's
1384
content is different.
1385
:param hardlink: If true, hard-link files from accelerator_tree,
1388
1264
These trees get an initial random root id, if their repository supports
1389
1265
rich root data, TREE_ROOT otherwise.
2080
1810
if not found_versioned:
2081
1811
# none of the indexes was not 'absent' at all ids for this
2083
not_versioned.append(path)
2084
if len(not_versioned) > 0:
2085
raise errors.PathsNotVersionedError(not_versioned)
1813
all_versioned = False
1815
if not all_versioned:
1816
raise errors.PathsNotVersionedError(specific_files)
2086
1817
# -- remove redundancy in supplied specific_files to prevent over-scanning --
2087
search_specific_files = osutils.minimum_path_selection(specific_files)
1818
search_specific_files = set()
1819
for path in specific_files:
1820
other_specific_files = specific_files.difference(set([path]))
1821
if not osutils.is_inside_any(other_specific_files, path):
1822
# this is a top level path, we must check it.
1823
search_specific_files.add(path)
1825
# compare source_index and target_index at or under each element of search_specific_files.
1826
# follow the following comparison table. Note that we only want to do diff operations when
1827
# the target is fdl because thats when the walkdirs logic will have exposed the pathinfo
1831
# Source | Target | disk | action
1832
# r | fdlt | | add source to search, add id path move and perform
1833
# | | | diff check on source-target
1834
# r | fdlt | a | dangling file that was present in the basis.
1836
# r | a | | add source to search
1838
# r | r | | this path is present in a non-examined tree, skip.
1839
# r | r | a | this path is present in a non-examined tree, skip.
1840
# a | fdlt | | add new id
1841
# a | fdlt | a | dangling locally added file, skip
1842
# a | a | | not present in either tree, skip
1843
# a | a | a | not present in any tree, skip
1844
# a | r | | not present in either tree at this path, skip as it
1845
# | | | may not be selected by the users list of paths.
1846
# a | r | a | not present in either tree at this path, skip as it
1847
# | | | may not be selected by the users list of paths.
1848
# fdlt | fdlt | | content in both: diff them
1849
# fdlt | fdlt | a | deleted locally, but not unversioned - show as deleted ?
1850
# fdlt | a | | unversioned: output deleted id for now
1851
# fdlt | a | a | unversioned and deleted: output deleted id
1852
# fdlt | r | | relocated in this tree, so add target to search.
1853
# | | | Dont diff, we will see an r,fd; pair when we reach
1854
# | | | this id at the other path.
1855
# fdlt | r | a | relocated in this tree, so add target to search.
1856
# | | | Dont diff, we will see an r,fd; pair when we reach
1857
# | | | this id at the other path.
1859
# for all search_indexs in each path at or under each element of
1860
# search_specific_files, if the detail is relocated: add the id, and add the
1861
# relocated path as one to search if its not searched already. If the
1862
# detail is not relocated, add the id.
1863
searched_specific_files = set()
1864
NULL_PARENT_DETAILS = dirstate.DirState.NULL_PARENT_DETAILS
1865
# Using a list so that we can access the values and change them in
1866
# nested scope. Each one is [path, file_id, entry]
1867
last_source_parent = [None, None]
1868
last_target_parent = [None, None]
2089
1870
use_filesystem_for_exec = (sys.platform != 'win32')
2090
iter_changes = self.target._iter_changes(include_unchanged,
2091
use_filesystem_for_exec, search_specific_files, state,
2092
source_index, target_index, want_unversioned, self.target)
2093
return iter_changes.iter_changes()
1872
# Just a sentry, so that _process_entry can say that this
1873
# record is handled, but isn't interesting to process (unchanged)
1874
uninteresting = object()
1877
old_dirname_to_file_id = {}
1878
new_dirname_to_file_id = {}
1879
# TODO: jam 20070516 - Avoid the _get_entry lookup overhead by
1880
# keeping a cache of directories that we have seen.
1882
def _process_entry(entry, path_info):
1883
"""Compare an entry and real disk to generate delta information.
1885
:param path_info: top_relpath, basename, kind, lstat, abspath for
1886
the path of entry. If None, then the path is considered absent.
1887
(Perhaps we should pass in a concrete entry for this ?)
1888
Basename is returned as a utf8 string because we expect this
1889
tuple will be ignored, and don't want to take the time to
1891
:return: None if these don't match
1892
A tuple of information about the change, or
1893
the object 'uninteresting' if these match, but are
1894
basically identical.
1896
if source_index is None:
1897
source_details = NULL_PARENT_DETAILS
1899
source_details = entry[1][source_index]
1900
target_details = entry[1][target_index]
1901
target_minikind = target_details[0]
1902
if path_info is not None and target_minikind in 'fdlt':
1903
assert target_index == 0
1904
link_or_sha1 = state.update_entry(entry, abspath=path_info[4],
1905
stat_value=path_info[3])
1906
# The entry may have been modified by update_entry
1907
target_details = entry[1][target_index]
1908
target_minikind = target_details[0]
1911
file_id = entry[0][2]
1912
source_minikind = source_details[0]
1913
if source_minikind in 'fdltr' and target_minikind in 'fdlt':
1914
# claimed content in both: diff
1915
# r | fdlt | | add source to search, add id path move and perform
1916
# | | | diff check on source-target
1917
# r | fdlt | a | dangling file that was present in the basis.
1919
if source_minikind in 'r':
1920
# add the source to the search path to find any children it
1921
# has. TODO ? : only add if it is a container ?
1922
if not osutils.is_inside_any(searched_specific_files,
1924
search_specific_files.add(source_details[1])
1925
# generate the old path; this is needed for stating later
1927
old_path = source_details[1]
1928
old_dirname, old_basename = os.path.split(old_path)
1929
path = pathjoin(entry[0][0], entry[0][1])
1930
old_entry = state._get_entry(source_index,
1932
# update the source details variable to be the real
1934
source_details = old_entry[1][source_index]
1935
source_minikind = source_details[0]
1937
old_dirname = entry[0][0]
1938
old_basename = entry[0][1]
1939
old_path = path = None
1940
if path_info is None:
1941
# the file is missing on disk, show as removed.
1942
content_change = True
1946
# source and target are both versioned and disk file is present.
1947
target_kind = path_info[2]
1948
if target_kind == 'directory':
1950
old_path = path = pathjoin(old_dirname, old_basename)
1951
new_dirname_to_file_id[path] = file_id
1952
if source_minikind != 'd':
1953
content_change = True
1955
# directories have no fingerprint
1956
content_change = False
1958
elif target_kind == 'file':
1959
if source_minikind != 'f':
1960
content_change = True
1962
# We could check the size, but we already have the
1964
content_change = (link_or_sha1 != source_details[1])
1965
# Target details is updated at update_entry time
1966
if use_filesystem_for_exec:
1967
# We don't need S_ISREG here, because we are sure
1968
# we are dealing with a file.
1969
target_exec = bool(stat.S_IEXEC & path_info[3].st_mode)
1971
target_exec = target_details[3]
1972
elif target_kind == 'symlink':
1973
if source_minikind != 'l':
1974
content_change = True
1976
content_change = (link_or_sha1 != source_details[1])
1978
elif target_kind == 'tree-reference':
1979
if source_minikind != 't':
1980
content_change = True
1982
content_change = False
1985
raise Exception, "unknown kind %s" % path_info[2]
1986
if source_minikind == 'd':
1988
old_path = path = pathjoin(old_dirname, old_basename)
1989
old_dirname_to_file_id[old_path] = file_id
1990
# parent id is the entry for the path in the target tree
1991
if old_dirname == last_source_parent[0]:
1992
source_parent_id = last_source_parent[1]
1995
source_parent_id = old_dirname_to_file_id[old_dirname]
1997
source_parent_entry = state._get_entry(source_index,
1998
path_utf8=old_dirname)
1999
source_parent_id = source_parent_entry[0][2]
2000
if source_parent_id == entry[0][2]:
2001
# This is the root, so the parent is None
2002
source_parent_id = None
2004
last_source_parent[0] = old_dirname
2005
last_source_parent[1] = source_parent_id
2006
new_dirname = entry[0][0]
2007
if new_dirname == last_target_parent[0]:
2008
target_parent_id = last_target_parent[1]
2011
target_parent_id = new_dirname_to_file_id[new_dirname]
2013
# TODO: We don't always need to do the lookup, because the
2014
# parent entry will be the same as the source entry.
2015
target_parent_entry = state._get_entry(target_index,
2016
path_utf8=new_dirname)
2017
assert target_parent_entry != (None, None), (
2018
"Could not find target parent in wt: %s\nparent of: %s"
2019
% (new_dirname, entry))
2020
target_parent_id = target_parent_entry[0][2]
2021
if target_parent_id == entry[0][2]:
2022
# This is the root, so the parent is None
2023
target_parent_id = None
2025
last_target_parent[0] = new_dirname
2026
last_target_parent[1] = target_parent_id
2028
source_exec = source_details[3]
2029
if (include_unchanged
2031
or source_parent_id != target_parent_id
2032
or old_basename != entry[0][1]
2033
or source_exec != target_exec
2035
if old_path is None:
2036
old_path = path = pathjoin(old_dirname, old_basename)
2037
old_path_u = utf8_decode(old_path)[0]
2040
old_path_u = utf8_decode(old_path)[0]
2041
if old_path == path:
2044
path_u = utf8_decode(path)[0]
2045
source_kind = _minikind_to_kind[source_minikind]
2046
return (entry[0][2],
2047
(old_path_u, path_u),
2050
(source_parent_id, target_parent_id),
2051
(utf8_decode(old_basename)[0], utf8_decode(entry[0][1])[0]),
2052
(source_kind, target_kind),
2053
(source_exec, target_exec))
2055
return uninteresting
2056
elif source_minikind in 'a' and target_minikind in 'fdlt':
2057
# looks like a new file
2058
if path_info is not None:
2059
path = pathjoin(entry[0][0], entry[0][1])
2060
# parent id is the entry for the path in the target tree
2061
# TODO: these are the same for an entire directory: cache em.
2062
parent_id = state._get_entry(target_index,
2063
path_utf8=entry[0][0])[0][2]
2064
if parent_id == entry[0][2]:
2066
if use_filesystem_for_exec:
2067
# We need S_ISREG here, because we aren't sure if this
2070
stat.S_ISREG(path_info[3].st_mode)
2071
and stat.S_IEXEC & path_info[3].st_mode)
2073
target_exec = target_details[3]
2074
return (entry[0][2],
2075
(None, utf8_decode(path)[0]),
2079
(None, utf8_decode(entry[0][1])[0]),
2080
(None, path_info[2]),
2081
(None, target_exec))
2083
# but its not on disk: we deliberately treat this as just
2084
# never-present. (Why ?! - RBC 20070224)
2086
elif source_minikind in 'fdlt' and target_minikind in 'a':
2087
# unversioned, possibly, or possibly not deleted: we dont care.
2088
# if its still on disk, *and* theres no other entry at this
2089
# path [we dont know this in this routine at the moment -
2090
# perhaps we should change this - then it would be an unknown.
2091
old_path = pathjoin(entry[0][0], entry[0][1])
2092
# parent id is the entry for the path in the target tree
2093
parent_id = state._get_entry(source_index, path_utf8=entry[0][0])[0][2]
2094
if parent_id == entry[0][2]:
2096
return (entry[0][2],
2097
(utf8_decode(old_path)[0], None),
2101
(utf8_decode(entry[0][1])[0], None),
2102
(_minikind_to_kind[source_minikind], None),
2103
(source_details[3], None))
2104
elif source_minikind in 'fdlt' and target_minikind in 'r':
2105
# a rename; could be a true rename, or a rename inherited from
2106
# a renamed parent. TODO: handle this efficiently. Its not
2107
# common case to rename dirs though, so a correct but slow
2108
# implementation will do.
2109
if not osutils.is_inside_any(searched_specific_files, target_details[1]):
2110
search_specific_files.add(target_details[1])
2111
elif source_minikind in 'ra' and target_minikind in 'ra':
2112
# neither of the selected trees contain this file,
2113
# so skip over it. This is not currently directly tested, but
2114
# is indirectly via test_too_much.TestCommands.test_conflicts.
2117
raise AssertionError("don't know how to compare "
2118
"source_minikind=%r, target_minikind=%r"
2119
% (source_minikind, target_minikind))
2120
## import pdb;pdb.set_trace()
2123
while search_specific_files:
2124
# TODO: the pending list should be lexically sorted? the
2125
# interface doesn't require it.
2126
current_root = search_specific_files.pop()
2127
current_root_unicode = current_root.decode('utf8')
2128
searched_specific_files.add(current_root)
2129
# process the entries for this containing directory: the rest will be
2130
# found by their parents recursively.
2131
root_entries = _entries_for_path(current_root)
2132
root_abspath = self.target.abspath(current_root_unicode)
2134
root_stat = os.lstat(root_abspath)
2136
if e.errno == errno.ENOENT:
2137
# the path does not exist: let _process_entry know that.
2138
root_dir_info = None
2140
# some other random error: hand it up.
2143
root_dir_info = ('', current_root,
2144
osutils.file_kind_from_stat_mode(root_stat.st_mode), root_stat,
2146
if root_dir_info[2] == 'directory':
2147
if self.target._directory_is_tree_reference(
2148
current_root.decode('utf8')):
2149
root_dir_info = root_dir_info[:2] + \
2150
('tree-reference',) + root_dir_info[3:]
2152
if not root_entries and not root_dir_info:
2153
# this specified path is not present at all, skip it.
2155
path_handled = False
2156
for entry in root_entries:
2157
result = _process_entry(entry, root_dir_info)
2158
if result is not None:
2160
if result is not uninteresting:
2162
if want_unversioned and not path_handled and root_dir_info:
2163
new_executable = bool(
2164
stat.S_ISREG(root_dir_info[3].st_mode)
2165
and stat.S_IEXEC & root_dir_info[3].st_mode)
2167
(None, current_root_unicode),
2171
(None, splitpath(current_root_unicode)[-1]),
2172
(None, root_dir_info[2]),
2173
(None, new_executable)
2175
initial_key = (current_root, '', '')
2176
block_index, _ = state._find_block_index_from_key(initial_key)
2177
if block_index == 0:
2178
# we have processed the total root already, but because the
2179
# initial key matched it we should skip it here.
2181
if root_dir_info and root_dir_info[2] == 'tree-reference':
2182
current_dir_info = None
2184
dir_iterator = osutils._walkdirs_utf8(root_abspath, prefix=current_root)
2186
current_dir_info = dir_iterator.next()
2188
# on win32, python2.4 has e.errno == ERROR_DIRECTORY, but
2189
# python 2.5 has e.errno == EINVAL,
2190
# and e.winerror == ERROR_DIRECTORY
2191
e_winerror = getattr(e, 'winerror', None)
2192
win_errors = (ERROR_DIRECTORY, ERROR_PATH_NOT_FOUND)
2193
# there may be directories in the inventory even though
2194
# this path is not a file on disk: so mark it as end of
2196
if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
2197
current_dir_info = None
2198
elif (sys.platform == 'win32'
2199
and (e.errno in win_errors
2200
or e_winerror in win_errors)):
2201
current_dir_info = None
2205
if current_dir_info[0][0] == '':
2206
# remove .bzr from iteration
2207
bzr_index = bisect_left(current_dir_info[1], ('.bzr',))
2208
assert current_dir_info[1][bzr_index][0] == '.bzr'
2209
del current_dir_info[1][bzr_index]
2210
# walk until both the directory listing and the versioned metadata
2212
if (block_index < len(state._dirblocks) and
2213
osutils.is_inside(current_root, state._dirblocks[block_index][0])):
2214
current_block = state._dirblocks[block_index]
2216
current_block = None
2217
while (current_dir_info is not None or
2218
current_block is not None):
2219
if (current_dir_info and current_block
2220
and current_dir_info[0][0] != current_block[0]):
2221
if cmp_by_dirs(current_dir_info[0][0], current_block[0]) < 0:
2222
# filesystem data refers to paths not covered by the dirblock.
2223
# this has two possibilities:
2224
# A) it is versioned but empty, so there is no block for it
2225
# B) it is not versioned.
2227
# if (A) then we need to recurse into it to check for
2228
# new unknown files or directories.
2229
# if (B) then we should ignore it, because we don't
2230
# recurse into unknown directories.
2232
while path_index < len(current_dir_info[1]):
2233
current_path_info = current_dir_info[1][path_index]
2234
if want_unversioned:
2235
if current_path_info[2] == 'directory':
2236
if self.target._directory_is_tree_reference(
2237
current_path_info[0].decode('utf8')):
2238
current_path_info = current_path_info[:2] + \
2239
('tree-reference',) + current_path_info[3:]
2240
new_executable = bool(
2241
stat.S_ISREG(current_path_info[3].st_mode)
2242
and stat.S_IEXEC & current_path_info[3].st_mode)
2244
(None, utf8_decode(current_path_info[0])[0]),
2248
(None, utf8_decode(current_path_info[1])[0]),
2249
(None, current_path_info[2]),
2250
(None, new_executable))
2251
# dont descend into this unversioned path if it is
2253
if current_path_info[2] in ('directory',
2255
del current_dir_info[1][path_index]
2259
# This dir info has been handled, go to the next
2261
current_dir_info = dir_iterator.next()
2262
except StopIteration:
2263
current_dir_info = None
2265
# We have a dirblock entry for this location, but there
2266
# is no filesystem path for this. This is most likely
2267
# because a directory was removed from the disk.
2268
# We don't have to report the missing directory,
2269
# because that should have already been handled, but we
2270
# need to handle all of the files that are contained
2272
for current_entry in current_block[1]:
2273
# entry referring to file not present on disk.
2274
# advance the entry only, after processing.
2275
result = _process_entry(current_entry, None)
2276
if result is not None:
2277
if result is not uninteresting:
2280
if (block_index < len(state._dirblocks) and
2281
osutils.is_inside(current_root,
2282
state._dirblocks[block_index][0])):
2283
current_block = state._dirblocks[block_index]
2285
current_block = None
2288
if current_block and entry_index < len(current_block[1]):
2289
current_entry = current_block[1][entry_index]
2291
current_entry = None
2292
advance_entry = True
2294
if current_dir_info and path_index < len(current_dir_info[1]):
2295
current_path_info = current_dir_info[1][path_index]
2296
if current_path_info[2] == 'directory':
2297
if self.target._directory_is_tree_reference(
2298
current_path_info[0].decode('utf8')):
2299
current_path_info = current_path_info[:2] + \
2300
('tree-reference',) + current_path_info[3:]
2302
current_path_info = None
2304
path_handled = False
2305
while (current_entry is not None or
2306
current_path_info is not None):
2307
if current_entry is None:
2308
# the check for path_handled when the path is adnvaced
2309
# will yield this path if needed.
2311
elif current_path_info is None:
2312
# no path is fine: the per entry code will handle it.
2313
result = _process_entry(current_entry, current_path_info)
2314
if result is not None:
2315
if result is not uninteresting:
2317
elif (current_entry[0][1] != current_path_info[1]
2318
or current_entry[1][target_index][0] in 'ar'):
2319
# The current path on disk doesn't match the dirblock
2320
# record. Either the dirblock is marked as absent, or
2321
# the file on disk is not present at all in the
2322
# dirblock. Either way, report about the dirblock
2323
# entry, and let other code handle the filesystem one.
2325
# Compare the basename for these files to determine
2327
if current_path_info[1] < current_entry[0][1]:
2328
# extra file on disk: pass for now, but only
2329
# increment the path, not the entry
2330
advance_entry = False
2332
# entry referring to file not present on disk.
2333
# advance the entry only, after processing.
2334
result = _process_entry(current_entry, None)
2335
if result is not None:
2336
if result is not uninteresting:
2338
advance_path = False
2340
result = _process_entry(current_entry, current_path_info)
2341
if result is not None:
2343
if result is not uninteresting:
2345
if advance_entry and current_entry is not None:
2347
if entry_index < len(current_block[1]):
2348
current_entry = current_block[1][entry_index]
2350
current_entry = None
2352
advance_entry = True # reset the advance flaga
2353
if advance_path and current_path_info is not None:
2354
if not path_handled:
2355
# unversioned in all regards
2356
if want_unversioned:
2357
new_executable = bool(
2358
stat.S_ISREG(current_path_info[3].st_mode)
2359
and stat.S_IEXEC & current_path_info[3].st_mode)
2361
(None, utf8_decode(current_path_info[0])[0]),
2365
(None, utf8_decode(current_path_info[1])[0]),
2366
(None, current_path_info[2]),
2367
(None, new_executable))
2368
# dont descend into this unversioned path if it is
2370
if current_path_info[2] in ('directory'):
2371
del current_dir_info[1][path_index]
2373
# dont descend the disk iterator into any tree
2375
if current_path_info[2] == 'tree-reference':
2376
del current_dir_info[1][path_index]
2379
if path_index < len(current_dir_info[1]):
2380
current_path_info = current_dir_info[1][path_index]
2381
if current_path_info[2] == 'directory':
2382
if self.target._directory_is_tree_reference(
2383
current_path_info[0].decode('utf8')):
2384
current_path_info = current_path_info[:2] + \
2385
('tree-reference',) + current_path_info[3:]
2387
current_path_info = None
2388
path_handled = False
2390
advance_path = True # reset the advance flagg.
2391
if current_block is not None:
2393
if (block_index < len(state._dirblocks) and
2394
osutils.is_inside(current_root, state._dirblocks[block_index][0])):
2395
current_block = state._dirblocks[block_index]
2397
current_block = None
2398
if current_dir_info is not None:
2400
current_dir_info = dir_iterator.next()
2401
except StopIteration:
2402
current_dir_info = None
2096
2406
def is_compatible(source, target):
2097
2407
# the target must be a dirstate working tree
2098
if not isinstance(target, DirStateWorkingTree):
2408
if not isinstance(target, WorkingTree4):
2100
# the source must be a revtree or dirstate rev tree.
2410
# the source must be a revtreee or dirstate rev tree.
2101
2411
if not isinstance(source,
2102
2412
(revisiontree.RevisionTree, DirStateRevisionTree)):
2104
2414
# the source revid must be in the target dirstate
2105
if not (source._revision_id == _mod_revision.NULL_REVISION or
2415
if not (source._revision_id == NULL_REVISION or
2106
2416
source._revision_id in target.get_parent_ids()):
2107
# TODO: what about ghosts? it may well need to
2417
# TODO: what about ghosts? it may well need to
2108
2418
# check for them explicitly.