164
164
# the physical root needs a new transaction id
165
165
self._tree_path_ids.pop("")
166
166
self._tree_id_paths.pop(old_root)
167
self._new_root = self.get_id_tree(self._tree.get_root_id())
167
self._new_root = self.trans_id_tree_file_id(self._tree.get_root_id())
168
168
if parent == old_root:
169
169
parent = self._new_root
170
170
self.adjust_path(name, parent, old_root)
172
172
self.version_file(old_root_file_id, old_root)
173
173
self.unversion_file(self._new_root)
175
def get_id_tree(self, inventory_id):
175
def trans_id_tree_file_id(self, inventory_id):
176
176
"""Determine the transaction id of a working tree file.
178
178
This reflects only files that already exist, not ones that will be
179
179
added by transactions.
181
181
path = self._tree.inventory.id2path(inventory_id)
182
return self.get_tree_path_id(path)
182
return self.trans_id_tree_path(path)
184
def get_trans_id(self, file_id):
184
def trans_id_file_id(self, file_id):
185
185
"""Determine or set the transaction id associated with a file ID.
186
186
A new id is only created for file_ids that were never present. If
187
187
a transaction has been unversioned, it is deliberately still returned.
190
190
if file_id in self._r_new_id and self._r_new_id[file_id] is not None:
191
191
return self._r_new_id[file_id]
192
192
elif file_id in self._tree.inventory:
193
return self.get_id_tree(file_id)
193
return self.trans_id_tree_file_id(file_id)
194
194
elif file_id in self._non_present_ids:
195
195
return self._non_present_ids[file_id]
205
205
dirname = os.path.realpath(dirname)
206
206
return self._tree.relpath(pathjoin(dirname, basename))
208
def get_tree_path_id(self, path):
208
def trans_id_tree_path(self, path):
209
209
"""Determine (and maybe set) the transaction ID for a tree path."""
210
210
path = self.canonical_path(path)
211
211
if path not in self._tree_path_ids:
218
218
path = self._tree_id_paths[trans_id]
220
220
return ROOT_PARENT
221
return self.get_tree_path_id(os.path.dirname(path))
221
return self.trans_id_tree_path(os.path.dirname(path))
223
223
def create_file(self, contents, trans_id, mode_id=None):
224
224
"""Schedule creation of a new file.
374
374
return self.tree_kind(trans_id)
376
def get_tree_file_id(self, trans_id):
376
def tree_file_id(self, trans_id):
377
377
"""Determine the file id associated with the trans_id in the tree"""
379
379
path = self._tree_id_paths[trans_id]
399
399
if trans_id in self._removed_id:
401
return self.get_tree_file_id(trans_id)
401
return self.tree_file_id(trans_id)
403
403
def inactive_file_id(self, trans_id):
404
404
"""Return the inactive file_id associated with a transaction id.
405
405
That is, the one in the tree or in non_present_ids.
406
406
The file_id may actually be active, too.
408
file_id = self.get_tree_file_id(trans_id)
408
file_id = self.tree_file_id(trans_id)
409
409
if file_id is not None:
411
411
for key, value in self._non_present_ids.iteritems():
477
477
parents.extend([t for t in self._removed_contents if
478
478
self.tree_kind(t) == 'directory'])
479
479
for trans_id in self._removed_id:
480
file_id = self.get_tree_file_id(trans_id)
480
file_id = self.tree_file_id(trans_id)
481
481
if self._tree.inventory[file_id].kind in ('directory',
482
482
'root_directory'):
483
483
parents.append(trans_id)
503
503
childpath = joinpath(path, child)
504
504
if self._tree.is_control_filename(childpath):
506
yield self.get_tree_path_id(childpath)
506
yield self.trans_id_tree_path(childpath)
508
508
def _parent_loops(self):
509
509
"""No entry should be its own ancestor"""
603
603
def _duplicate_ids(self):
604
604
"""Each inventory id may only be used once"""
606
removed_tree_ids = set((self.get_tree_file_id(trans_id) for trans_id in
606
removed_tree_ids = set((self.tree_file_id(trans_id) for trans_id in
607
607
self._removed_id))
608
608
active_tree_ids = set((f for f in self._tree.inventory if
609
609
f not in removed_tree_ids))
610
610
for trans_id, file_id in self._new_id.iteritems():
611
611
if file_id in active_tree_ids:
612
old_trans_id = self.get_id_tree(file_id)
612
old_trans_id = self.trans_id_tree_file_id(file_id)
613
613
conflicts.append(('duplicate id', old_trans_id, trans_id))
690
690
if trans_id == self._new_root:
691
691
file_id = self._tree.inventory.root.file_id
693
file_id = self.get_tree_file_id(trans_id)
693
file_id = self.tree_file_id(trans_id)
695
695
elif trans_id in self._new_name or trans_id in self._new_parent:
696
file_id = self.get_tree_file_id(trans_id)
696
file_id = self.tree_file_id(trans_id)
697
697
if file_id is not None:
698
698
limbo_inv[trans_id] = inv[file_id]
851
851
file_trans_id = {}
852
852
tt = TreeTransform(wt)
854
file_trans_id[wt.get_root_id()] = tt.get_id_tree(wt.get_root_id())
854
file_trans_id[wt.get_root_id()] = tt.trans_id_tree_file_id(wt.get_root_id())
855
855
file_ids = topology_sorted_ids(tree)
856
856
for file_id in file_ids:
857
857
entry = tree.inventory[file_id]
918
918
def change_entry(tt, file_id, working_tree, target_tree,
919
get_trans_id, backups, trans_id):
919
trans_id_file_id, backups, trans_id):
920
920
"""Replace a file_id's contents with those from a target tree."""
921
e_trans_id = get_trans_id(file_id)
921
e_trans_id = trans_id_file_id(file_id)
922
922
entry = target_tree.inventory[file_id]
923
923
has_contents, contents_mod, meta_mod, = _entry_changes(file_id, entry,
929
929
tt.delete_contents(e_trans_id)
931
parent_trans_id = get_trans_id(entry.parent_id)
931
parent_trans_id = trans_id_file_id(entry.parent_id)
932
932
tt.adjust_path(entry.name+"~", parent_trans_id, e_trans_id)
933
933
tt.unversion_file(e_trans_id)
934
934
e_trans_id = tt.create_path(entry.name, parent_trans_id)
994
994
tt = TreeTransform(working_tree)
997
def get_trans_id(file_id):
997
def trans_id_file_id(file_id):
999
999
return trans_id[file_id]
1000
1000
except KeyError:
1001
return tt.get_id_tree(file_id)
1001
return tt.trans_id_tree_file_id(file_id)
1003
1003
for file_id in topology_sorted_ids(target_tree):
1004
1004
if not interesting(file_id):
1006
1006
if file_id not in working_tree.inventory:
1007
1007
entry = target_tree.inventory[file_id]
1008
parent_id = get_trans_id(entry.parent_id)
1008
parent_id = trans_id_file_id(entry.parent_id)
1009
1009
e_trans_id = new_by_entry(tt, entry, parent_id, target_tree)
1010
1010
trans_id[file_id] = e_trans_id
1012
1012
change_entry(tt, file_id, working_tree, target_tree,
1013
get_trans_id, backups, trans_id)
1013
trans_id_file_id, backups, trans_id)
1014
1014
for file_id in working_tree.inventory:
1015
1015
if not interesting(file_id):
1017
1017
if file_id not in target_tree:
1018
tt.unversion_file(tt.get_id_tree(file_id))
1018
tt.unversion_file(tt.trans_id_tree_file_id(file_id))
1019
1019
raw_conflicts = resolve_conflicts(tt)
1020
1020
for line in conflicts_strings(cook_conflicts(raw_conflicts, tt)):