90
93
class TreeTransformBase(object):
91
94
"""The base class for TreeTransform and its kin."""
93
def __init__(self, tree, pb=None,
96
def __init__(self, tree, pb=None, case_sensitive=True):
97
99
:param tree: The tree that will be transformed, but not necessarily
297
299
return self._r_new_id[file_id]
300
next(self._tree.iter_entries_by_dir([file_id]))
301
except StopIteration:
302
path = self._tree.id2path(file_id)
303
except errors.NoSuchId:
302
304
if file_id in self._non_present_ids:
303
305
return self._non_present_ids[file_id]
306
308
self._non_present_ids[file_id] = trans_id
309
path = self._tree.id2path(file_id)
310
311
return self.trans_id_tree_path(path)
312
313
def trans_id_tree_path(self, path):
445
446
return self.tree_kind(trans_id)
448
def tree_path(self, trans_id):
449
"""Determine the tree path associated with the trans_id."""
450
return self._tree_id_paths.get(trans_id)
447
452
def tree_file_id(self, trans_id):
448
453
"""Determine the file id associated with the trans_id in the tree"""
450
path = self._tree_id_paths[trans_id]
452
# the file is a new, unversioned file, or invalid trans_id
454
path = self.tree_path(trans_id)
454
457
# the file is old; the old id is still valid
455
458
if self._new_root == trans_id:
557
560
parents.extend([t for t in self._removed_contents if
558
561
self.tree_kind(t) == 'directory'])
559
562
for trans_id in self._removed_id:
560
file_id = self.tree_file_id(trans_id)
561
path = self._tree.id2path(file_id)
562
if file_id is not None:
563
if self._tree.stored_kind(path, file_id) == 'directory':
563
path = self.tree_path(trans_id)
565
if self._tree.stored_kind(path) == 'directory':
564
566
parents.append(trans_id)
565
567
elif self.tree_kind(trans_id) == 'directory':
566
568
parents.append(trans_id)
1068
1070
return revision_id
1070
1072
def _text_parent(self, trans_id):
1071
file_id = self.tree_file_id(trans_id)
1073
path = self.tree_path(trans_id)
1073
if (file_id is None or
1074
self._tree.kind(self._tree.id2path(file_id), file_id) != 'file'):
1075
if path is None or self._tree.kind(path) != 'file':
1076
1077
except errors.NoSuchFile:
1080
1081
def _get_parents_texts(self, trans_id):
1081
1082
"""Get texts for compression parents of this file."""
1082
file_id = self._text_parent(trans_id)
1083
path = self._text_parent(trans_id)
1085
return (self._tree.get_file_text(self._tree.id2path(file_id), file_id),)
1086
return (self._tree.get_file_text(path),)
1087
1088
def _get_parents_lines(self, trans_id):
1088
1089
"""Get lines for compression parents of this file."""
1089
file_id = self._text_parent(trans_id)
1090
path = self._text_parent(trans_id)
1092
return (self._tree.get_file_lines(self._tree.id2path(file_id), file_id),)
1093
return (self._tree.get_file_lines(path),)
1094
1095
def serialize(self, serializer):
1095
1096
"""Serialize this TreeTransform.
2002
2003
vf.fallback_versionedfiles.append(base_vf)
2003
2004
return tree_revision
2005
def _stat_limbo_file(self, trans_id=None):
2006
def _stat_limbo_file(self, trans_id):
2006
2007
name = self._transform._limbo_name(trans_id)
2007
2008
return os.lstat(name)
2112
2113
self._all_children_cache[trans_id] = children
2113
2114
return children
2115
def iter_children(self, file_id):
2116
def _iter_children(self, file_id):
2116
2117
trans_id = self._transform.trans_id_file_id(file_id)
2117
2118
for child_trans_id in self._all_children(trans_id):
2118
2119
yield self._transform.final_file_id(child_trans_id)
2241
2242
return self._transform._tree.get_file_mtime(
2242
2243
self._transform._tree.id2path(file_id), file_id)
2243
2244
trans_id = self._path2trans_id(path)
2244
return self._stat_limbo_file(trans_id=trans_id).st_mtime
2245
return self._stat_limbo_file(trans_id).st_mtime
2246
2247
def get_file_size(self, path, file_id=None):
2247
2248
"""See Tree.get_file_size"""
2252
2253
if kind != 'file':
2254
2255
if trans_id in self._transform._new_contents:
2255
return self._stat_limbo_file(trans_id=trans_id).st_size
2256
return self._stat_limbo_file(trans_id).st_size
2256
2257
if self.kind(path, file_id) == 'file':
2257
2258
return self._transform._tree.get_file_size(path, file_id)
2605
2606
divert.add(file_id)
2606
2607
if (file_id not in divert and
2607
_content_match(tree, entry, file_id, kind,
2608
_content_match(tree, entry, tree_path, file_id, kind,
2609
2610
tt.delete_contents(tt.trans_id_tree_path(tree_path))
2610
2611
if kind == 'directory':
2716
2717
return by_parent[old_parent]
2719
def _content_match(tree, entry, file_id, kind, target_path):
2720
def _content_match(tree, entry, tree_path, file_id, kind, target_path):
2720
2721
if entry.kind != kind:
2722
2723
if entry.kind == "directory":
2724
path = tree.id2path(file_id)
2725
2725
if entry.kind == "file":
2726
2726
f = file(target_path, 'rb')
2728
if tree.get_file_text(path, file_id) == f.read():
2728
if tree.get_file_text(tree_path, file_id) == f.read():
2732
2732
elif entry.kind == "symlink":
2733
if tree.get_symlink_target(path, file_id) == os.readlink(target_path):
2733
if tree.get_symlink_target(tree_path, file_id) == os.readlink(target_path):
2906
2904
if basis_tree is None:
2907
2905
basis_tree = working_tree.basis_tree()
2908
2906
basis_tree.lock_read()
2910
basis_path = basis_tree.id2path(file_id)
2911
except errors.NoSuchId:
2907
basis_path = find_previous_path(working_tree, basis_tree, wt_path)
2908
if basis_path is None:
2912
2909
if target_kind is None and not target_versioned:
2913
2910
keep_content = True
2945
2942
basis_tree = working_tree.basis_tree()
2946
2943
basis_tree.lock_read()
2947
2944
new_sha1 = target_tree.get_file_sha1(target_path, file_id)
2949
basis_path = basis_tree.id2path(file_id)
2950
except errors.NoSuchId:
2945
basis_path = find_previous_path(target_tree, basis_tree, target_path)
2952
2946
if (basis_path is not None and
2953
2947
new_sha1 == basis_tree.get_file_sha1(basis_path, file_id)):
2954
2948
if file_id in merge_modified:
3104
3098
elif c_type == 'unversioned parent':
3105
3099
file_id = tt.inactive_file_id(conflict[1])
3106
3100
# special-case the other tree root (move its children instead)
3107
if path_tree and path_tree.has_id(file_id):
3108
if path_tree.path2id('') == file_id:
3101
if path_tree and path_tree.path2id('') == file_id:
3109
3102
# This is the root entry, skip it
3111
3104
tt.version_file(file_id, conflict[1])