64
65
:param tree: The tree containing the files.
65
66
:param file_ids: A list of file_ids to perform the updates for.
67
desired_files = [(f, f) for f in file_ids]
68
task = ui_factory.nested_progress_bar()
68
desired_files = [(tree.id2path(f), f) for f in file_ids]
69
with ui_factory.nested_progress_bar() as task:
70
70
for num, (file_id, contents) in enumerate(
71
71
tree.iter_files_bytes(desired_files)):
72
72
task.update(gettext('Calculating hashes'), num, len(file_ids))
74
74
s.writelines(contents)
76
76
self.add_edge_hashes(s.readlines(), file_id)
80
78
def hitcounts(self, lines):
81
79
"""Count the number of hash hits for each tag, for the given lines.
104
102
:return: A list of tuples of count, path, file_id.
107
task = ui_factory.nested_progress_bar()
105
with ui_factory.nested_progress_bar() as task:
109
106
for num, path in enumerate(paths):
110
107
task.update(gettext('Determining hash hits'), num, len(paths))
111
108
hits = self.hitcounts(self.tree.get_file_lines(path))
112
109
all_hits.extend((v, path, k) for k, v in viewitems(hits))
117
112
def file_match(self, paths):
148
143
path = osutils.dirname(path)
149
if self.tree.path2id(path) is not None:
144
if self.tree.is_versioned(path):
151
146
required_parents.setdefault(path, []).append(child)
178
173
missing_files = set()
179
174
missing_parents = {}
180
175
candidate_files = set()
181
task = ui_factory.nested_progress_bar()
182
iterator = self.tree.iter_changes(basis, want_unversioned=True,
176
with ui_factory.nested_progress_bar() as task:
177
iterator = self.tree.iter_changes(basis, want_unversioned=True,
185
179
for (file_id, paths, changed_content, versioned, parent, name,
186
180
kind, executable) in iterator:
187
181
if kind[1] is None and versioned[1]:
202
196
for child in children:
203
197
if child[2] == 'file':
204
198
candidate_files.add(child[0])
207
199
return missing_files, missing_parents, candidate_files
210
def guess_renames(klass, tree, dry_run=False):
202
def guess_renames(klass, from_tree, to_tree, dry_run=False):
211
203
"""Guess which files to rename, and perform the rename.
213
205
We assume that unversioned files and missing files indicate that
214
206
versioned files have been renamed outside of Bazaar.
216
:param tree: A write-locked working tree.
208
:param from_tree: A tree to compare from
209
:param to_tree: A write-locked working tree.
218
211
required_parents = {}
219
task = ui_factory.nested_progress_bar()
212
with ui_factory.nested_progress_bar() as task:
221
213
pp = progress.ProgressPhase('Guessing renames', 4, task)
222
basis = tree.basis_tree()
214
with from_tree.lock_read():
227
217
missing_files, missing_parents, candidate_files = (
228
rn._find_missing_files(basis))
218
rn._find_missing_files(from_tree))
230
rn.add_file_edge_hashes(basis, missing_files)
220
rn.add_file_edge_hashes(from_tree, missing_files)
234
222
matches = rn.file_match(candidate_files)
235
223
parents_matches = matches
244
232
for old, new, file_id, entry in delta:
245
233
trace.note( gettext("{0} => {1}").format(old, new) )
247
tree.add(required_parents)
248
tree.apply_inventory_delta(delta)
235
to_tree.add(required_parents)
236
to_tree.apply_inventory_delta(delta)
252
238
def _make_inventory_delta(self, matches):
254
240
file_id_matches = dict((f, p) for p, f in viewitems(matches))
255
for old_path, entry in self.tree.iter_entries_by_dir(file_id_matches):
242
for f in viewvalues(matches):
244
file_id_query.append(self.tree.id2path(f))
245
except errors.NoSuchId:
247
for old_path, entry in self.tree.iter_entries_by_dir(
248
specific_files=file_id_query):
256
249
new_path = file_id_matches[entry.file_id]
257
250
parent_path, new_name = osutils.split(new_path)
258
251
parent_id = matches.get(parent_path)