@@ -60,15 +60,19 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
6060 else:
6161 args.append("--raw")
6262
63- paths = paths or []
64- if paths:
65- paths.insert(0, "--")
63+ if paths is not None and not isinstance(paths, (tuple,list)):
64+ paths = [ paths ]
6665
6766 if other is not None:
6867 args.insert(0, other)
6968
7069 args.insert(0,self)
71- args.extend(paths)
70+
71+ # paths is list here or None
72+ if paths:
73+ args.append("--")
74+ args.extend(paths)
75+ # END paths handling
7276
7377 kwargs['as_process'] = True
7478 proc = self.repo.git.diff(*args, **kwargs)
@@ -79,6 +83,16 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
7983 return diff_method(self.repo, proc.stdout)
8084
8185
86+ class DiffIndex(list):
87+ """
88+ Implements an Index for diffs, allowing a list of Diffs to be queried by
89+ the diff properties.
90+
91+ The class improves the diff handling convenience
92+ """
93+
94+
95+
8296class Diff(object):
8397 """
8498 A Diff contains diff information between two Trees.
@@ -99,7 +113,7 @@ class Diff(object):
99113 ``Deleted File``::
100114
101115 b_mode is None
102- b_blob is NOne
116+ b_blob is None
103117 """
104118
105119 # precompiled regex
@@ -160,7 +174,7 @@ def _index_from_patch_format(cls, repo, stream):
160174 """
161175 # for now, we have to bake the stream
162176 text = stream.read()
163- diffs = []
177+ index = DiffIndex()
164178
165179 diff_header = cls.re_header.match
166180 for diff in ('\n' + text).split('\ndiff --git')[1:]:
@@ -171,19 +185,49 @@ def _index_from_patch_format(cls, repo, stream):
171185 a_blob_id, b_blob_id, b_mode = header.groups()
172186 new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode)
173187
174- diffs .append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
188+ index .append(Diff(repo, a_path, b_path, a_blob_id, b_blob_id,
175189 old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode,
176190 new_file, deleted_file, rename_from, rename_to, diff[header.end():]))
177191
178- return diffs
192+ return index
179193
180194 @classmethod
181195 def _index_from_raw_format(cls, repo, stream):
182196 """
183197 Create a new DiffIndex from the given stream which must be in raw format.
184198
199+ NOTE:
200+ This format is inherently incapable of detecting renames, hence we only
201+ modify, delete and add files
202+
185203 Returns
186204 git.DiffIndex
187205 """
188- raise NotImplementedError("")
206+ # handles
207+ # :100644 100644 6870991011cc8d9853a7a8a6f02061512c6a8190 37c5e30c879213e9ae83b21e9d11e55fc20c54b7 M .gitignore
208+ index = DiffIndex()
209+ for line in stream:
210+ if not line.startswith(":"):
211+ continue
212+ # END its not a valid diff line
213+ old_mode, new_mode, a_blob_id, b_blob_id, modification_id, path = line[1:].split()
214+ a_path = path
215+ b_path = path
216+ deleted_file = False
217+ new_file = False
218+ if modification_id == 'D':
219+ b_path = None
220+ deleted_file = True
221+ elif modification_id == 'A':
222+ a_path = None
223+ new_file = True
224+ # END add/remove handling
225+
226+
227+ diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode,
228+ new_file, deleted_file, None, None, '')
229+ index.append(diff)
230+ # END for each line
231+
232+ return index
189233
0 commit comments