summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2015-01-08 11:13:41 +0100
committerSebastian Thiel <byronimo@gmail.com>2015-01-08 11:16:49 +0100
commit987f9bbd08446de3f9d135659f2e36ad6c9d14fb (patch)
tree08152431363821b26367fafa5c97990ceb26b700
parent27b4efed7a435153f18598796473b3fba06c513d (diff)
downloadgitpython-987f9bbd08446de3f9d135659f2e36ad6c9d14fb.tar.gz
Added support for rename detection in raw mode (which is the default).
Fixes #36
-rw-r--r--doc/source/changes.rst1
-rw-r--r--git/diff.py14
-rw-r--r--git/test/fixtures/diff_rename_raw1
-rw-r--r--git/test/test_diff.py9
4 files changed, 19 insertions, 6 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
index 4983b3d0..bd768740 100644
--- a/doc/source/changes.rst
+++ b/doc/source/changes.rst
@@ -5,6 +5,7 @@ Changelog
0.3.5 - Bugfixes
================
* push/pull/fetch operations will not block anymore
+* diff() can now properly detect renames, both in patch and raw format. Previously it only worked when create_patch was True.
* A list of all fixed issues can be found here: https://github.com/gitpython-developers/GitPython/issues?q=milestone%3A%22v0.3.5+-+bugfixes%22+
0.3.4 - Python 3 Support
diff --git a/git/diff.py b/git/diff.py
index b59c264c..24e47bad 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -73,9 +73,9 @@ class Diffable(object):
args.append("--abbrev=40") # we need full shas
args.append("--full-index") # get full index paths, not only filenames
+ args.append("-M") # check for renames, in both formats
if create_patch:
args.append("-p")
- args.append("-M") # check for renames
else:
args.append("--raw")
@@ -318,14 +318,11 @@ class Diff(object):
@classmethod
def _index_from_raw_format(cls, repo, stream):
"""Create a new DiffIndex from the given stream which must be in raw format.
- :note:
- This format is inherently incapable of detecting renames, hence we only
- modify, delete and add files
:return: git.DiffIndex"""
# handles
# :100644 100644 687099101... 37c5e30c8... M .gitignore
index = DiffIndex()
- for line in stream:
+ for line in stream.readlines():
line = line.decode(defenc)
if not line.startswith(":"):
continue
@@ -336,6 +333,8 @@ class Diff(object):
b_path = path
deleted_file = False
new_file = False
+ rename_from = None
+ rename_to = None
# NOTE: We cannot conclude from the existance of a blob to change type
# as diffs with the working do not have blobs yet
@@ -345,10 +344,13 @@ class Diff(object):
elif change_type == 'A':
a_blob_id = None
new_file = True
+ elif change_type[0] == 'R': # parses RXXX, where XXX is a confidence value
+ a_path, b_path = path.split('\t', 1)
+ rename_from, rename_to = a_path, b_path
# END add/remove handling
diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode,
- new_file, deleted_file, None, None, '')
+ new_file, deleted_file, rename_from, rename_to, '')
index.append(diff)
# END for each line
diff --git a/git/test/fixtures/diff_rename_raw b/git/test/fixtures/diff_rename_raw
new file mode 100644
index 00000000..92d06d22
--- /dev/null
+++ b/git/test/fixtures/diff_rename_raw
@@ -0,0 +1 @@
+:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 R100 this that
diff --git a/git/test/test_diff.py b/git/test/test_diff.py
index c5183089..ce0f64f2 100644
--- a/git/test/test_diff.py
+++ b/git/test/test_diff.py
@@ -56,6 +56,15 @@ class TestDiff(TestBase):
assert_equal(diff.rename_from, 'AUTHORS')
assert_equal(diff.rename_to, 'CONTRIBUTORS')
+ output = StringProcessAdapter(fixture('diff_rename_raw'))
+ diffs = Diff._index_from_raw_format(self.rorepo, output.stdout)
+ assert len(diffs) == 1
+ diff = diffs[0]
+ assert diff.renamed
+ assert diff.rename_from == 'this'
+ assert diff.rename_to == 'that'
+ assert len(list(diffs.iter_change_type('R'))) == 1
+
def test_diff_patch_format(self):
# test all of the 'old' format diffs for completness - it should at least
# be able to deal with it