669
670
new_entry = to_block[1][added_entry_index]
670
671
rollbacks.append(lambda:state._make_absent(new_entry))
672
# create rename entries and tuples
673
673
for from_rel in from_paths:
674
674
# from_rel is 'pathinroot/foo/bar'
675
675
from_rel_utf8 = from_rel.encode('utf8')
774
774
if minikind == 'd':
775
775
def update_dirblock(from_dir, to_key, to_dir_utf8):
776
"""all entries in this block need updating.
778
TODO: This is pretty ugly, and doesn't support
779
reverting, but it works.
776
"""Recursively update all entries in this dirblock."""
781
777
assert from_dir != '', "renaming root not supported"
782
778
from_key = (from_dir, '')
783
779
from_block_idx, present = \
794
790
to_block_index = state._ensure_block(
795
791
to_block_index, to_entry_index, to_dir_utf8)
796
792
to_block = state._dirblocks[to_block_index]
797
for entry in from_block[1]:
794
# Grab a copy since move_one may update the list.
795
for entry in from_block[1][:]:
798
796
assert entry[0][0] == from_dir
799
797
cur_details = entry[1][0]
800
798
to_key = (to_dir_utf8, entry[0][1], entry[0][2])
801
799
from_path_utf8 = osutils.pathjoin(entry[0][0], entry[0][1])
802
800
to_path_utf8 = osutils.pathjoin(to_dir_utf8, entry[0][1])
803
801
minikind = cur_details[0]
803
# Deleted children of a renamed directory
804
# Do not need to be updated.
805
# Children that have been renamed out of this
806
# directory should also not be updated
804
808
move_one(entry, from_path_utf8=from_path_utf8,
805
809
minikind=minikind,
806
810
executable=cur_details[3],
1245
1249
:param revision_id: allows creating a working tree at a different
1246
1250
revision than the branch is at.
1248
These trees get an initial random root id.
1252
These trees get an initial random root id, if their repository supports
1253
rich root data, TREE_ROOT otherwise.
1250
1255
revision_id = osutils.safe_revision_id(revision_id)
1251
1256
if not isinstance(a_bzrdir.transport, LocalTransport):
1273
1278
wt.current_dirstate()._validate()
1275
1280
if revision_id in (None, NULL_REVISION):
1276
wt._set_root_id(generate_ids.gen_root_id())
1281
if branch.repository.supports_rich_root():
1282
wt._set_root_id(generate_ids.gen_root_id())
1284
wt._set_root_id(ROOT_ID)
1278
1286
wt.current_dirstate()._validate()
1279
1287
wt.set_last_revision(revision_id)
1915
1923
# parent entry will be the same as the source entry.
1916
1924
target_parent_entry = state._get_entry(target_index,
1917
1925
path_utf8=new_dirname)
1926
assert target_parent_entry != (None, None), (
1927
"Could not find target parent in wt: %s\nparent of: %s"
1928
% (new_dirname, entry))
1918
1929
target_parent_id = target_parent_entry[0][2]
1919
1930
if target_parent_id == entry[0][2]:
1920
1931
# This is the root, so the parent is None
2082
2093
# python 2.5 has e.errno == EINVAL,
2083
2094
# and e.winerror == ERROR_DIRECTORY
2084
2095
e_winerror = getattr(e, 'winerror', None)
2096
win_errors = (ERROR_DIRECTORY, ERROR_PATH_NOT_FOUND)
2085
2097
# there may be directories in the inventory even though
2086
2098
# this path is not a file on disk: so mark it as end of
2088
2100
if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
2089
2101
current_dir_info = None
2090
2102
elif (sys.platform == 'win32'
2091
and ERROR_DIRECTORY in (e.errno, e_winerror)):
2103
and (e.errno in win_errors
2104
or e_winerror in win_errors)):
2092
2105
current_dir_info = None
2114
2127
# this has two possibilities:
2115
2128
# A) it is versioned but empty, so there is no block for it
2116
2129
# B) it is not versioned.
2117
# in either case it was processed by the containing directories walk:
2118
# if it is root/foo, when we walked root we emitted it,
2119
# or if we ere given root/foo to walk specifically, we
2120
# emitted it when checking the walk-root entries
2121
# advance the iterator and loop - we dont need to emit it.
2131
# if (A) then we need to recurse into it to check for
2132
# new unknown files or directories.
2133
# if (B) then we should ignore it, because we don't
2134
# recurse into unknown directories.
2135
if want_unversioned:
2137
while path_index < len(current_dir_info[1]):
2138
current_path_info = current_dir_info[1][path_index]
2139
if current_path_info[2] == 'directory':
2140
if self.target._directory_is_tree_reference(
2141
current_path_info[0].decode('utf8')):
2142
current_path_info = current_path_info[:2] + \
2143
('tree-reference',) + current_path_info[3:]
2144
new_executable = bool(
2145
stat.S_ISREG(current_path_info[3].st_mode)
2146
and stat.S_IEXEC & current_path_info[3].st_mode)
2148
(None, utf8_decode_or_none(current_path_info[0])),
2152
(None, utf8_decode_or_none(current_path_info[1])),
2153
(None, current_path_info[2]),
2154
(None, new_executable))
2155
# dont descend into this unversioned path if it is
2157
if current_path_info[2] in ('directory',
2159
del current_dir_info[1][path_index]
2163
# This dir info has been handled, go to the next
2123
2165
current_dir_info = dir_iterator.next()
2124
2166
except StopIteration:
2287
2329
new_executable = bool(
2288
2330
stat.S_ISREG(current_path_info[3].st_mode)
2289
2331
and stat.S_IEXEC & current_path_info[3].st_mode)
2290
if want_unversioned:
2292
(None, utf8_decode_or_none(current_path_info[0])),
2296
(None, utf8_decode_or_none(current_path_info[1])),
2297
(None, current_path_info[2]),
2298
(None, new_executable))
2333
(None, utf8_decode_or_none(current_path_info[0])),
2337
(None, utf8_decode_or_none(current_path_info[1])),
2338
(None, current_path_info[2]),
2339
(None, new_executable))
2299
2340
# dont descend into this unversioned path if it is
2301
2342
if current_path_info[2] in ('directory'):