@@ -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 ('\n diff --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