From 6964e3efc4ac779d458733a05c9d71be2194b2ba Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Thu, 14 Apr 2016 15:58:27 +0200 Subject: [PATCH 1/2] Drop dependency on six --- git/compat.py | 7 ++++--- git/repo/base.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/git/compat.py b/git/compat.py index 146bfd4bc..b892a9eaa 100644 --- a/git/compat.py +++ b/git/compat.py @@ -8,7 +8,6 @@ # flake8: noqa import sys -import six from gitdb.utils.compat import ( PY3, @@ -34,6 +33,7 @@ def bchr(n): return bytes([n]) def mviter(d): return d.values() + range = xrange unicode = str else: FileType = file @@ -44,6 +44,7 @@ def mviter(d): byte_ord = ord bchr = chr unicode = unicode + range = xrange def mviter(d): return d.itervalues() @@ -52,9 +53,9 @@ def mviter(d): def safe_decode(s): """Safely decodes a binary string to unicode""" - if isinstance(s, six.text_type): + if isinstance(s, unicode): return s - elif isinstance(s, six.binary_type): + elif isinstance(s, bytes): if PRE_PY27: return s.decode(defenc) # we're screwed else: diff --git a/git/repo/base.py b/git/repo/base.py index 9d0132308..f74e0b591 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -54,12 +54,12 @@ defenc, PY3, safe_decode, + range, ) import os import sys import re -from six.moves import range DefaultDBType = GitCmdObjectDB if sys.version_info[:2] < (2, 5): # python 2.4 compatiblity From 2f1b69ad52670a67e8b766e89451080219871739 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Thu, 14 Apr 2016 13:29:33 +0200 Subject: [PATCH 2/2] Return all available data from git-blame Returning this now to avoid having to change the function's return value structure later on if we want to emit more information. --- git/repo/base.py | 22 ++++++++++++++++------ git/test/test_repo.py | 11 +++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index f74e0b591..0274c0a7b 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -60,12 +60,15 @@ import os import sys import re +from collections import namedtuple DefaultDBType = GitCmdObjectDB if sys.version_info[:2] < (2, 5): # python 2.4 compatiblity DefaultDBType = GitCmdObjectDB # END handle python 2.4 +BlameEntry = namedtuple('BlameEntry', ['commit', 'linenos', 'orig_path', 'orig_linenos']) + __all__ = ('Repo', ) @@ -661,10 +664,10 @@ def blame_incremental(self, rev, file, **kwargs): """Iterator for blame information for the given file at the given revision. Unlike .blame(), this does not return the actual file's contents, only - a stream of (commit, range) tuples. + a stream of BlameEntry tuples. :parm rev: revision specifier, see git-rev-parse for viable options. - :return: lazy iterator of (git.Commit, range) tuples, where the commit + :return: lazy iterator of BlameEntry tuples, where the commit indicates the commit to blame for the line, and range indicates a span of line numbers in the resulting file. @@ -678,9 +681,10 @@ def blame_incremental(self, rev, file, **kwargs): while True: line = next(stream) # when exhausted, casues a StopIteration, terminating this function - hexsha, _, lineno, num_lines = line.split() + hexsha, orig_lineno, lineno, num_lines = line.split() lineno = int(lineno) num_lines = int(num_lines) + orig_lineno = int(orig_lineno) if hexsha not in commits: # Now read the next few lines and build up a dict of properties # for this commit @@ -696,6 +700,7 @@ def blame_incremental(self, rev, file, **kwargs): props[tag] = value if tag == b'filename': # "filename" formally terminates the entry for --incremental + orig_filename = value break c = Commit(self, hex_to_bin(hexsha), @@ -710,9 +715,14 @@ def blame_incremental(self, rev, file, **kwargs): else: # Discard the next line (it's a filename end tag) line = next(stream) - assert line.startswith(b'filename'), 'Unexpected git blame output' - - yield commits[hexsha], range(lineno, lineno + num_lines) + tag, value = line.split(b' ', 1) + assert tag == b'filename', 'Unexpected git blame output' + orig_filename = value + + yield BlameEntry(commits[hexsha], + range(lineno, lineno + num_lines), + safe_decode(orig_filename), + range(orig_lineno, orig_lineno + num_lines)) def blame(self, rev, file, incremental=False, **kwargs): """The blame information for the given file at the given revision. diff --git a/git/test/test_repo.py b/git/test/test_repo.py index ab6c502fd..d7437d35b 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -341,12 +341,19 @@ def test_blame_incremental(self, git): assert len(blame_output) == 5 # Check all outputted line numbers - ranges = flatten([line_numbers for _, line_numbers in blame_output]) + ranges = flatten([entry.linenos for entry in blame_output]) assert ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(3, 14), range(15, 17)]), str(ranges) - commits = [c.hexsha[:7] for c, _ in blame_output] + commits = [entry.commit.hexsha[:7] for entry in blame_output] assert commits == ['82b8902', '82b8902', 'c76852d', 'c76852d', 'c76852d'], str(commits) + # Original filenames + assert all([entry.orig_path == u'AUTHORS' for entry in blame_output]) + + # Original line numbers + orig_ranges = flatten([entry.orig_linenos for entry in blame_output]) + assert orig_ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(2, 13), range(13, 15)]), str(orig_ranges) # noqa + @patch.object(Git, '_call_process') def test_blame_complex_revision(self, git): git.return_value = fixture('blame_complex_revision')