34
34
precursor=precursor,
35
35
precursor_sha1=precursor_sha1)
37
def _get_revision_set(branch):
37
def _get_revision_set(branch, target_rev_id=None):
38
38
"""Get the set of all revisions that are in the ancestry
42
to_search = [branch.last_patch()]
42
if target_rev_id is None:
43
to_search = [branch.last_patch()]
45
to_search = [target_rev_id]
44
47
while len(to_search) > 0:
45
48
rev_id = to_search.pop(0)
52
55
to_search.append(parent.revision_id)
55
def _find_best_base(branch, other_rev_id, other_branch=None):
58
def _find_best_base(target_branch, target_rev_id, base_branch, base_rev_id):
56
59
"""Find the best base revision based on ancestry.
57
60
All revisions should already be pulled into the local tree.
59
this_revs = _get_revision_set(branch)
62
this_revs = _get_revision_set(target_branch, target_rev_id)
61
64
# This does a breadth first search through history, looking for
62
65
# something which matches
64
to_check = [other_rev_id]
67
to_check = [base_rev_id]
65
68
while len(to_check) > 0:
66
69
# Removing the '0' would make this depth-first search
67
70
rev_id = to_check.pop(0)
71
74
if rev_id in this_revs:
74
if rev_id in branch.revision_store:
75
rev = branch.get_revision(rev_id)
76
elif (other_branch is not None
77
and rev_id in other_branch.revision_store):
78
rev = other_branch.get_revision(rev_id)
77
if rev_id in target_branch.revision_store:
78
rev = target_branch.get_revision(rev_id)
79
elif (rev_id in base_branch.revision_store):
80
rev = base_branch.get_revision(rev_id)
80
82
# Should we just continue here?
81
83
warning('Could not find revision for rev: {%s}'
145
147
if cur_rev_id == ancestor_rev_id:
148
if rev_id in branch.revision_store:
149
rev = branch.get_revision(rev_id)
150
if cur_rev_id in branch.revision_store:
151
rev = branch.get_revision(cur_rev_id)
151
153
# Should we just continue here?
152
154
warning('Could not find revision for rev: {%s}, unable to'
153
' trace ancestry.' % rev_id)
155
' trace ancestry.' % cur_rev_id)
156
158
for parent in rev.parents:
157
if parent.revision_id not in checked:
158
to_check.append(cur_trail + [parent.revision_id])
159
if parent.revision_id not in checked_rev_ids:
160
cur_trails.append(cur_trail + [parent.revision_id])
160
162
raise BzrCommandError('Revision id {%s} not an ancestor of {%s}'
161
163
% (ancestor_rev_id, this_rev_id))
180
182
self.base_branch = base_branch
181
183
self.base_rev_id = base_rev_id
182
184
self.base_tree = base_tree
185
self.base_revision = self.base_branch.get_revision(self.base_rev_id)
184
187
self.target_branch = target_branch
185
188
self.target_rev_id = target_rev_id
213
216
It fills out the internal self.revision_list with Revision
214
217
entries which should be in the changeset.
216
for revno, rev in enumerate(rh):
217
if rev == revisions[0]:
219
if rev == revisions[1]:
222
self.revision_list = []
223
if base_revno is None:
224
self.base_revision = None # Effectively the EmptyTree()
227
self.base_revision = self.branch.get_revision(rh[base_revno])
228
if new_revno is None:
229
# For the future, when we support working tree changesets.
230
for rev_id in rh[base_revno+1:]:
231
self.revision_list.append(self.branch.get_revision(rev_id))
232
self.revision_list.append(_fake_working_revision(self.branch))
234
for rev_id in rh[base_revno+1:new_revno+1]:
235
self.revision_list.append(self.branch.get_revision(rev_id))
236
#self.parent_revno = base_revno+1
237
#self.revno = new_revno+1
219
if self.starting_rev_id is None:
220
self.starting_rev_id = _find_best_base(self.target_branch,
222
self.base_branch, self.base_rev_id)
225
# print 'target: %s' % self.target_rev_id
226
# print 'base: %s' % self.base_rev_id
227
# print 'start: %s' % self.starting_rev_id
229
rev_id_list = _create_ancestry_to_rev(self.target_branch,
230
self.starting_rev_id, self.target_rev_id)
231
rev_id_list.reverse()
233
self.revision_list = [self.target_branch.get_revision(rid)
234
for rid in rev_id_list]
239
236
def _write(self, txt, key=None):
295
292
and self.base_revision.revision_id != assumed_base):
296
293
base = self.base_revision.revision_id
297
294
write(base, key='base')
298
write(self.branch.get_revision_sha1(base), key='base sha1')
295
write(self.target_branch.get_revision_sha1(base), key='base sha1')
300
297
self._write_revisions()
307
304
rev_id = rev.revision_id
308
305
self.to_file.write('# revision: %s\n' % rev_id)
309
306
self.to_file.write('# sha1: %s\n' %
310
self.branch.get_revision_sha1(rev_id))
307
self.target_branch.get_revision_sha1(rev_id))
311
308
if rev.committer != self.committer:
312
309
self.to_file.write('# committer: %s\n' % rev.committer)
313
310
date = format_highres_date(rev.timestamp, rev.timezone)
337
334
# Get the target tree so that we can check for
338
335
# Appropriate text ids.
339
336
rev_id = self.revision_list[-1].revision_id
340
tree = self.branch.revision_tree(rev_id)
337
tree = self.target_branch.revision_tree(rev_id)
343
340
def get_text_id_str(file_id, modified=True):
359
356
print >>self.to_file, '*** removed %s %s' % (kind,
361
358
if kind == 'file' and self.full_remove:
362
diff_file(self.old_label + path,
359
diff_file(self.base_label + path,
363
360
self.base_tree.get_file(file_id).readlines(),
382
379
encode(old_path), encode(new_path),
383
380
get_text_id_str(file_id, text_modified))
384
381
if self.full_rename and kind == 'file':
385
diff_file(self.old_label + old_path,
382
diff_file(self.base_label + old_path,
386
383
self.base_tree.get_file(file_id).readlines(),
390
387
diff_file(DEVNULL,
392
self.new_label + new_path,
389
self.target_label + new_path,
393
390
self.target_tree.get_file(file_id).readlines(),
395
392
elif text_modified:
396
diff_file(self.old_label + old_path,
393
diff_file(self.base_label + old_path,
397
394
self.base_tree.get_file(file_id).readlines(),
398
self.new_label + new_path,
395
self.target_label + new_path,
399
396
self.target_tree.get_file(file_id).readlines(),
403
400
print >>self.to_file, '*** modified %s %s%s' % (kind,
404
401
encode(path), get_text_id_str(file_id))
405
402
if kind == 'file':
406
diff_file(self.old_label + path,
403
diff_file(self.base_label + path,
407
404
self.base_tree.get_file(file_id).readlines(),
408
self.new_label + path,
405
self.target_label + path,
409
406
self.target_tree.get_file(file_id).readlines(),
418
415
if to_file is None:
420
417
to_file = sys.stdout
421
base_tree = base_branch.get_revision_tree(base_rev_id)
422
target_tree = target_branch.get_revision_tree(target_rev_id)
418
base_tree = base_branch.revision_tree(base_rev_id)
419
target_tree = target_branch.revision_tree(target_rev_id)
424
421
delta = compare_trees(base_tree, target_tree, want_unchanged=False)