68
68
bzrlib.ui.ui_factory = ThreadSafeUIFactory()
71
def _process_side_by_side_buffers(line_list, delete_list, insert_list):
72
while len(delete_list) < len(insert_list):
73
delete_list.append((None, '', 'context'))
74
while len(insert_list) < len(delete_list):
75
insert_list.append((None, '', 'context'))
76
while len(delete_list) > 0:
77
d = delete_list.pop(0)
78
i = insert_list.pop(0)
79
line_list.append(util.Container(old_lineno=d[0], new_lineno=i[0],
80
old_line=d[1], new_line=i[1],
81
old_type=d[2], new_type=i[2]))
84
def _make_side_by_side(chunk_list):
86
turn a normal unified-style diff (post-processed by parse_delta) into a
87
side-by-side diff structure. the new structure is::
95
type: str('context' or 'changed'),
100
for chunk in chunk_list:
103
delete_list, insert_list = [], []
104
for line in chunk.diff:
105
# Add <wbr/> every X characters so we can wrap properly
106
wrap_line = re.findall(r'.{%d}|.+$' % 78, line.line)
107
wrap_lines = [util.html_clean(_line) for _line in wrap_line]
108
wrapped_line = wrap_char.join(wrap_lines)
110
if line.type == 'context':
111
if len(delete_list) or len(insert_list):
112
_process_side_by_side_buffers(line_list, delete_list,
114
delete_list, insert_list = [], []
115
line_list.append(util.Container(old_lineno=line.old_lineno,
116
new_lineno=line.new_lineno,
117
old_line=wrapped_line,
118
new_line=wrapped_line,
121
elif line.type == 'delete':
122
delete_list.append((line.old_lineno, wrapped_line, line.type))
123
elif line.type == 'insert':
124
insert_list.append((line.new_lineno, wrapped_line, line.type))
125
if len(delete_list) or len(insert_list):
126
_process_side_by_side_buffers(line_list, delete_list, insert_list)
127
out_chunk_list.append(util.Container(diff=line_list))
128
return out_chunk_list
131
70
def is_branch(folder):
133
72
bzrlib.branch.Branch.open(folder)
654
593
for entry, changes in zip(entries, changes_list):
655
594
entry.changes = changes
657
def get_change_with_diff(self, revid, compare_revid=None):
658
change = self.get_changes([revid])[0]
660
if compare_revid is None:
662
compare_revid = change.parents[0].revid
664
compare_revid = 'null:'
666
rev_tree1 = self._branch.repository.revision_tree(compare_revid)
667
rev_tree2 = self._branch.repository.revision_tree(revid)
668
delta = rev_tree2.changes_from(rev_tree1)
670
change.changes = self.parse_delta(delta)
671
change.changes.modified = self._parse_diffs(rev_tree1,
677
596
def get_file(self, file_id, revid):
678
597
"returns (path, filename, data)"
679
598
inv = self.get_inventory(revid)
684
603
path = '/' + path
685
604
return path, inv_entry.name, rev_tree.get_file_text(file_id)
687
def _parse_diffs(self, old_tree, new_tree, delta):
689
Return a list of processed diffs, in the format::
698
type: str('context', 'delete', or 'insert'),
707
for old_path, new_path, fid, \
708
kind, text_modified, meta_modified in delta.renamed:
710
process.append((old_path, new_path, fid, kind))
711
for path, fid, kind, text_modified, meta_modified in delta.modified:
712
process.append((path, path, fid, kind))
714
for old_path, new_path, fid, kind in process:
715
old_lines = old_tree.get_file_lines(fid)
716
new_lines = new_tree.get_file_lines(fid)
718
if old_lines != new_lines:
720
bzrlib.diff.internal_diff(old_path, old_lines,
721
new_path, new_lines, buffer)
722
except bzrlib.errors.BinaryFile:
725
diff = buffer.getvalue()
728
out.append(util.Container(
729
filename=rich_filename(new_path, kind),
731
chunks=self._process_diff(diff),
736
def _process_diff(self, diff):
737
# doesn't really need to be a method; could be static.
740
for line in diff.splitlines():
743
if line.startswith('+++ ') or line.startswith('--- '):
745
if line.startswith('@@ '):
747
if chunk is not None:
749
chunk = util.Container()
751
split_lines = line.split(' ')[1:3]
752
lines = [int(x.split(',')[0][1:]) for x in split_lines]
753
old_lineno = lines[0]
754
new_lineno = lines[1]
755
elif line.startswith(' '):
756
chunk.diff.append(util.Container(old_lineno=old_lineno,
757
new_lineno=new_lineno,
762
elif line.startswith('+'):
763
chunk.diff.append(util.Container(old_lineno=None,
764
new_lineno=new_lineno,
765
type='insert', line=line[1:]))
767
elif line.startswith('-'):
768
chunk.diff.append(util.Container(old_lineno=old_lineno,
770
type='delete', line=line[1:]))
773
chunk.diff.append(util.Container(old_lineno=None,
777
if chunk is not None:
781
606
def parse_delta(self, delta):
783
608
Return a nested data structure containing the changes in a delta::
816
641
return util.Container(added=added, renamed=renamed,
817
642
removed=removed, modified=modified)
820
def add_side_by_side(changes):
821
# FIXME: this is a rotten API.
822
for change in changes:
823
for m in change.changes.modified:
824
m.sbs_chunks = _make_side_by_side(m.chunks)
826
644
def annotate_file(self, file_id, revid):