Skip to content

detect renames in "git diff --raw" output #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 16, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions git/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,21 +310,24 @@ def _index_from_patch_format(cls, repo, stream):
@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 6870991011cc8d9853a7a8a6f02061512c6a8190 37c5e30c879213e9ae83b21e9d11e55fc20c54b7 M .gitignore
# or
# :100644 100644 4aab7ea753e2867dd464f2a50dd266d426ddc8c8 4aab7ea753e2867dd464f2a50dd266d426ddc8c8 R100 src/bootstrap/package.json package.json
index = DiffIndex()
for line in stream:
if not line.startswith(":"):
continue
# END its not a valid diff line
old_mode, new_mode, a_blob_id, b_blob_id, change_type, path = line[1:].split(None, 5)
path = path.strip()
a_path = path
b_path = path
if change_type[0] != 'R':
a_path = b_path = path
rename_from = rename_to = None
else:
a_path, b_path = path.split('\t')
rename_from, rename_to = a_path, b_path
deleted_file = False
new_file = False

Expand All @@ -339,7 +342,7 @@ def _index_from_raw_format(cls, repo, stream):
# 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

Expand Down
4 changes: 4 additions & 0 deletions git/test/fixtures/diff_rename_raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:000000 100644 0000000000000000000000000000000000000000 8b137891791fe96927ad78e64b0aad7bded08bdc A git/test/refs/__init__.py
:100644 100644 271924aa5bf43ef58a0b0dae5a356e502c48dcf8 271924aa5bf43ef58a0b0dae5a356e502c48dcf8 R100 git/test/test_reflog.py git/test/refs/test_reflog.py
:100644 100644 e49b23abc5c47f26e8cf64d46aa6851593ce1404 e49b23abc5c47f26e8cf64d46aa6851593ce1404 R100 git/test/test_refs.py git/test/refs/test_refs.py
:100644 100644 b9a0b617b66962d2c2ba211641675d06f591461f b9a0b617b66962d2c2ba211641675d06f591461f R100 git/test/test_git.py git/test/test_cmd.py
21 changes: 21 additions & 0 deletions git/test/test_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ def test_diff_with_rename(self):
assert_equal(diff.rename_from, 'AUTHORS')
assert_equal(diff.rename_to, 'CONTRIBUTORS')

def test_diff_with_rename_raw(self):
output = StringProcessAdapter(fixture('diff_rename_raw'))
diffs = Diff._index_from_raw_format(self.rorepo, output.stdout)
self._assert_diff_format(diffs)

diffs = filter(lambda d: d.renamed, diffs)
assert_equal(3, len(diffs))

diff = diffs[0]
assert_true(diff.renamed)
assert_equal(diff.rename_from, 'git/test/test_reflog.py')
assert_equal(diff.rename_to, 'git/test/refs/test_reflog.py')

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
Expand Down Expand Up @@ -98,6 +111,14 @@ def test_diff_interface(self):
# END for each path option
# END for each other side
# END for each commit

# test rename detection
rename_commit = self.rorepo.rev_parse('4772fe0')
rename_diffs = rename_commit.parents[0].diff(rename_commit, M=True)
rename_diffs = filter(lambda d: d.renamed, rename_diffs)
assert len(rename_diffs) == 3
assert rename_diffs[0].rename_from == rename_diffs[0].a_blob.path
assert rename_diffs[0].rename_to == rename_diffs[0].b_blob.path

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