Skip to content

Commit 864cf1a

Browse files
committed
Merge pull request #62 from P2000/p2000
detect renames in "git diff --raw" output
2 parents cd72d78 + 3da67f3 commit 864cf1a

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

git/diff.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,24 @@ def _index_from_patch_format(cls, repo, stream):
310310
@classmethod
311311
def _index_from_raw_format(cls, repo, stream):
312312
"""Create a new DiffIndex from the given stream which must be in raw format.
313-
:note:
314-
This format is inherently incapable of detecting renames, hence we only
315-
modify, delete and add files
316313
:return: git.DiffIndex"""
317314
# handles
318315
# :100644 100644 6870991011cc8d9853a7a8a6f02061512c6a8190 37c5e30c879213e9ae83b21e9d11e55fc20c54b7 M .gitignore
316+
# or
317+
# :100644 100644 4aab7ea753e2867dd464f2a50dd266d426ddc8c8 4aab7ea753e2867dd464f2a50dd266d426ddc8c8 R100 src/bootstrap/package.json package.json
319318
index = DiffIndex()
320319
for line in stream:
321320
if not line.startswith(":"):
322321
continue
323322
# END its not a valid diff line
324323
old_mode, new_mode, a_blob_id, b_blob_id, change_type, path = line[1:].split(None, 5)
325324
path = path.strip()
326-
a_path = path
327-
b_path = path
325+
if change_type[0] != 'R':
326+
a_path = b_path = path
327+
rename_from = rename_to = None
328+
else:
329+
a_path, b_path = path.split('\t')
330+
rename_from, rename_to = a_path, b_path
328331
deleted_file = False
329332
new_file = False
330333

@@ -339,7 +342,7 @@ def _index_from_raw_format(cls, repo, stream):
339342
# END add/remove handling
340343

341344
diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode,
342-
new_file, deleted_file, None, None, '')
345+
new_file, deleted_file, rename_from, rename_to, '')
343346
index.append(diff)
344347
# END for each line
345348

git/test/fixtures/diff_rename_raw

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:000000 100644 0000000000000000000000000000000000000000 8b137891791fe96927ad78e64b0aad7bded08bdc A git/test/refs/__init__.py
2+
:100644 100644 271924aa5bf43ef58a0b0dae5a356e502c48dcf8 271924aa5bf43ef58a0b0dae5a356e502c48dcf8 R100 git/test/test_reflog.py git/test/refs/test_reflog.py
3+
:100644 100644 e49b23abc5c47f26e8cf64d46aa6851593ce1404 e49b23abc5c47f26e8cf64d46aa6851593ce1404 R100 git/test/test_refs.py git/test/refs/test_refs.py
4+
:100644 100644 b9a0b617b66962d2c2ba211641675d06f591461f b9a0b617b66962d2c2ba211641675d06f591461f R100 git/test/test_git.py git/test/test_cmd.py

git/test/test_diff.py

+21
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ def test_diff_with_rename(self):
5151
assert_equal(diff.rename_from, 'AUTHORS')
5252
assert_equal(diff.rename_to, 'CONTRIBUTORS')
5353

54+
def test_diff_with_rename_raw(self):
55+
output = StringProcessAdapter(fixture('diff_rename_raw'))
56+
diffs = Diff._index_from_raw_format(self.rorepo, output.stdout)
57+
self._assert_diff_format(diffs)
58+
59+
diffs = filter(lambda d: d.renamed, diffs)
60+
assert_equal(3, len(diffs))
61+
62+
diff = diffs[0]
63+
assert_true(diff.renamed)
64+
assert_equal(diff.rename_from, 'git/test/test_reflog.py')
65+
assert_equal(diff.rename_to, 'git/test/refs/test_reflog.py')
66+
5467
def test_diff_patch_format(self):
5568
# test all of the 'old' format diffs for completness - it should at least
5669
# be able to deal with it
@@ -98,6 +111,14 @@ def test_diff_interface(self):
98111
# END for each path option
99112
# END for each other side
100113
# END for each commit
114+
115+
# test rename detection
116+
rename_commit = self.rorepo.rev_parse('4772fe0')
117+
rename_diffs = rename_commit.parents[0].diff(rename_commit, M=True)
118+
rename_diffs = filter(lambda d: d.renamed, rename_diffs)
119+
assert len(rename_diffs) == 3
120+
assert rename_diffs[0].rename_from == rename_diffs[0].a_blob.path
121+
assert rename_diffs[0].rename_to == rename_diffs[0].b_blob.path
101122

102123
# assert we could always find at least one instance of the members we
103124
# can iterate in the diff index - if not this indicates its not working correctly

0 commit comments

Comments
 (0)