416
426
@with_branch_lock
417
427
def get_file_view(self, revid, file_id):
419
Given an optional revid and optional path, return a (revlist, revid)
420
for navigation through the current scope: from the revid (or the
421
latest revision) back to the original revision.
429
Given a revid and optional path, return a (revlist, revid) for
430
navigation through the current scope: from the revid (or the latest
431
revision) back to the original revision.
423
433
If file_id is None, the entire revision history is the list scope.
424
If revid is None, the latest revision is used.
426
435
if revid is None:
427
436
revid = self._last_revid
428
437
if file_id is not None:
429
# since revid is 'start_revid', possibly should start the path tracing from revid... FIXME
438
# since revid is 'start_revid', possibly should start the path
439
# tracing from revid... FIXME
430
440
revlist = list(self.get_short_revision_history_by_fileid(file_id))
431
441
revlist = list(self.get_revids_from(revlist, revid))
433
443
revlist = list(self.get_revids_from(None, revid))
436
return revlist, revid
438
446
@with_branch_lock
439
447
def get_view(self, revid, start_revid, file_id, query=None):
733
if C{get_diffs} is false, the C{chunks} will be omitted.
746
old_tree, new_tree, delta = self._get_diff(revid1, revid2)
750
for old_path, new_path, fid, kind, text_modified, meta_modified in delta.renamed:
752
process.append((old_path, new_path, fid, kind))
753
for path, fid, kind, text_modified, meta_modified in delta.modified:
754
process.append((path, path, fid, kind))
756
for old_path, new_path, fid, kind in process:
757
old_lines = old_tree.get_file_lines(fid)
758
new_lines = new_tree.get_file_lines(fid)
760
if old_lines != new_lines:
762
bzrlib.diff.internal_diff(old_path, old_lines,
763
new_path, new_lines, buffer)
764
except bzrlib.errors.BinaryFile:
767
diff = buffer.getvalue()
770
out.append(util.Container(filename=rich_filename(new_path, kind), file_id=fid, chunks=self._process_diff(diff)))
774
def _process_diff(self, diff):
775
# doesn't really need to be a method; could be static.
778
for line in diff.splitlines():
781
if line.startswith('+++ ') or line.startswith('--- '):
783
if line.startswith('@@ '):
785
if chunk is not None:
787
chunk = util.Container()
789
lines = [int(x.split(',')[0][1:]) for x in line.split(' ')[1:3]]
790
old_lineno = lines[0]
791
new_lineno = lines[1]
792
elif line.startswith(' '):
793
chunk.diff.append(util.Container(old_lineno=old_lineno, new_lineno=new_lineno,
794
type='context', line=util.fixed_width(line[1:])))
797
elif line.startswith('+'):
798
chunk.diff.append(util.Container(old_lineno=None, new_lineno=new_lineno,
799
type='insert', line=util.fixed_width(line[1:])))
801
elif line.startswith('-'):
802
chunk.diff.append(util.Container(old_lineno=old_lineno, new_lineno=None,
803
type='delete', line=util.fixed_width(line[1:])))
806
chunk.diff.append(util.Container(old_lineno=None, new_lineno=None,
807
type='unknown', line=util.fixed_width(repr(line))))
808
if chunk is not None:
813
def parse_delta(self, delta, get_diffs=True, old_tree=None, new_tree=None):
815
Return a nested data structure containing the changes in a delta::
817
added: list((filename, file_id)),
818
renamed: list((old_filename, new_filename, file_id)),
819
deleted: list((filename, file_id)),
740
def rich_filename(path, kind):
741
if kind == 'directory':
743
if kind == 'symlink':
747
def process_diff(diff):
750
for line in diff.splitlines():
753
if line.startswith('+++ ') or line.startswith('--- '):
755
if line.startswith('@@ '):
757
if chunk is not None:
759
chunk = util.Container()
761
lines = [int(x.split(',')[0][1:]) for x in line.split(' ')[1:3]]
762
old_lineno = lines[0]
763
new_lineno = lines[1]
764
elif line.startswith(' '):
765
chunk.diff.append(util.Container(old_lineno=old_lineno, new_lineno=new_lineno,
766
type='context', line=util.html_clean(line[1:])))
769
elif line.startswith('+'):
770
chunk.diff.append(util.Container(old_lineno=None, new_lineno=new_lineno,
771
type='insert', line=util.html_clean(line[1:])))
773
elif line.startswith('-'):
774
chunk.diff.append(util.Container(old_lineno=old_lineno, new_lineno=None,
775
type='delete', line=util.html_clean(line[1:])))
778
chunk.diff.append(util.Container(old_lineno=None, new_lineno=None,
779
type='unknown', line=util.html_clean(repr(line))))
780
if chunk is not None:
784
def handle_modify(old_path, new_path, fid, kind):
786
modified.append(util.Container(filename=rich_filename(new_path, kind), file_id=fid))
788
old_lines = old_tree.get_file_lines(fid)
789
new_lines = new_tree.get_file_lines(fid)
792
bzrlib.diff.internal_diff(old_path, old_lines,
793
new_path, new_lines, buffer)
794
except bzrlib.errors.BinaryFile:
797
diff = buffer.getvalue()
798
modified.append(util.Container(filename=rich_filename(new_path, kind), file_id=fid, chunks=process_diff(diff), raw_diff=diff))
800
830
for path, fid, kind in delta.added:
801
831
added.append((rich_filename(path, kind), fid))
803
833
for path, fid, kind, text_modified, meta_modified in delta.modified:
804
handle_modify(path, path, fid, kind)
834
modified.append(util.Container(filename=rich_filename(path, kind), file_id=fid))
806
for oldpath, newpath, fid, kind, text_modified, meta_modified in delta.renamed:
807
renamed.append((rich_filename(oldpath, kind), rich_filename(newpath, kind), fid))
836
for old_path, new_path, fid, kind, text_modified, meta_modified in delta.renamed:
837
renamed.append((rich_filename(old_path, kind), rich_filename(new_path, kind), fid))
808
838
if meta_modified or text_modified:
809
handle_modify(oldpath, newpath, fid, kind)
839
modified.append(util.Container(filename=rich_filename(new_path, kind), file_id=fid))
811
841
for path, fid, kind in delta.removed:
812
842
removed.append((rich_filename(path, kind), fid))
821
851
m.sbs_chunks = _make_side_by_side(m.chunks)
823
853
@with_branch_lock
824
def get_filelist(self, inv, path, sort_type=None):
854
def get_filelist(self, inv, file_id, sort_type=None):
826
856
return the list of all files (and their attributes) within a given
829
while path.endswith('/'):
831
if path.startswith('/'):
834
entries = inv.entries()
860
dir_ie = inv[file_id]
861
path = inv.id2path(file_id)
837
for filepath, entry in entries:
838
if posixpath.dirname(filepath) != path:
840
filename = posixpath.basename(filepath)
864
for filename, entry in dir_ie.children.iteritems():
841
865
pathname = filename
842
866
if entry.kind == 'directory':
845
869
revid = entry.revision
846
revision = self._branch.repository.get_revision(revid)
870
if self._change_cache:
871
timestamp = self.get_changes([revid])[0].date
873
revision = self._branch.repository.get_revision(revid)
874
timestamp = datetime.datetime.fromtimestamp(revision.timestamp)
848
change = util.Container(date=datetime.datetime.fromtimestamp(revision.timestamp),
876
change = util.Container(date=timestamp,
849
877
revno=self.get_revno(revid))
851
file = util.Container(filename=filename, executable=entry.executable, kind=entry.kind,
852
pathname=pathname, file_id=entry.file_id, size=entry.text_size, revid=revid, change=change)
879
file = util.Container(
880
filename=filename, executable=entry.executable, kind=entry.kind,
881
pathname=pathname, file_id=entry.file_id, size=entry.text_size,
882
revid=revid, change=change)
853
883
file_list.append(file)
855
if sort_type == 'filename':
885
if sort_type == 'filename' or sort_type is None:
856
886
file_list.sort(key=lambda x: x.filename)
857
887
elif sort_type == 'size':
858
888
file_list.sort(key=lambda x: x.size)
859
889
elif sort_type == 'date':
860
890
file_list.sort(key=lambda x: x.change.date)
863
893
for file in file_list:
864
894
file.parity = parity