summaryrefslogtreecommitdiff
path: root/lib/git/diff.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-10-18 13:24:04 +0200
committerSebastian Thiel <byronimo@gmail.com>2009-10-18 13:24:04 +0200
commite063d101face690b8cf4132fa419c5ce3857ef44 (patch)
treef6b9fd358a81217be320100436c82948dd201855 /lib/git/diff.py
parentaed099a73025422f0550f5dd5c3e4651049494b2 (diff)
downloadgitpython-e063d101face690b8cf4132fa419c5ce3857ef44.tar.gz
diff: implemented raw diff parsing which appears to be able to handle possible input types, DiffIndex still requires implementation though
Diffstat (limited to 'lib/git/diff.py')
-rw-r--r--lib/git/diff.py62
1 files changed, 53 insertions, 9 deletions
diff --git a/lib/git/diff.py b/lib/git/diff.py
index 760897ec..6a6a097c 100644
--- a/lib/git/diff.py
+++ b/lib/git/diff.py
@@ -60,15 +60,19 @@ class Diffable(object):
else:
args.append("--raw")
- paths = paths or []
- if paths:
- paths.insert(0, "--")
+ if paths is not None and not isinstance(paths, (tuple,list)):
+ paths = [ paths ]
if other is not None:
args.insert(0, other)
args.insert(0,self)
- args.extend(paths)
+
+ # paths is list here or None
+ if paths:
+ args.append("--")
+ args.extend(paths)
+ # END paths handling
kwargs['as_process'] = True
proc = self.repo.git.diff(*args, **kwargs)
@@ -79,6 +83,16 @@ class Diffable(object):
return diff_method(self.repo, proc.stdout)
+class DiffIndex(list):
+ """
+ Implements an Index for diffs, allowing a list of Diffs to be queried by
+ the diff properties.
+
+ The class improves the diff handling convenience
+ """
+
+
+
class Diff(object):
"""
A Diff contains diff information between two Trees.
@@ -99,7 +113,7 @@ class Diff(object):
``Deleted File``::
b_mode is None
- b_blob is NOne
+ b_blob is None
"""
# precompiled regex
@@ -160,7 +174,7 @@ class Diff(object):
"""
# for now, we have to bake the stream
text = stream.read()
- diffs = []
+ index = DiffIndex()
diff_header = cls.re_header.match
for diff in ('\n' + text).split('\ndiff --git')[1:]:
@@ -171,19 +185,49 @@ class Diff(object):
a_blob_id, b_blob_id, b_mode = header.groups()
new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode)
- diffs.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
+ index.append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode,
new_file, deleted_file, rename_from, rename_to, diff[header.end():]))
- return diffs
+ return index
@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
+
Returns
git.DiffIndex
"""
- raise NotImplementedError("")
+ # handles
+ # :100644 100644 6870991011cc8d9853a7a8a6f02061512c6a8190 37c5e30c879213e9ae83b21e9d11e55fc20c54b7 M .gitignore
+ 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, modification_id, path = line[1:].split()
+ a_path = path
+ b_path = path
+ deleted_file = False
+ new_file = False
+ if modification_id == 'D':
+ b_path = None
+ deleted_file = True
+ elif modification_id == 'A':
+ a_path = None
+ new_file = True
+ # 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, '')
+ index.append(diff)
+ # END for each line
+
+ return index