@@ -22,6 +22,10 @@ class Diffable(object):
2222 # them in this tuple
2323 _diff_args = tuple ()
2424
25+ # Temporary standin for Index type until we have a real index type
26+ class Index (object ):
27+ pass
28+
2529 def diff (self , other = None , paths = None , create_patch = False , ** kwargs ):
2630 """
2731 Creates diffs between two items being trees, trees and index or an
@@ -30,6 +34,7 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
3034 ``other``
3135 Is the item to compare us with.
3236 If None, we will be compared to the working tree.
37+ If Index ( type ), it will be compared against the index
3338
3439 ``paths``
3540 is a list of paths or a single path to limit the diff to.
@@ -63,8 +68,10 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
6368 if paths is not None and not isinstance (paths , (tuple ,list )):
6469 paths = [ paths ]
6570
66- if other is not None :
71+ if other is not None and other is not self . Index :
6772 args .insert (0 , other )
73+ if other is self .Index :
74+ args .insert (0 , "--cached" )
6875
6976 args .insert (0 ,self )
7077
@@ -90,7 +97,33 @@ class DiffIndex(list):
9097
9198 The class improves the diff handling convenience
9299 """
100+ # change type invariant identifying possible ways a blob can have changed
101+ # A = Added
102+ # D = Deleted
103+ # R = Renamed
104+ # NOTE: 'Modified' mode is impllied as it wouldn't be listed as a diff otherwise
105+ change_type = ("A" , "D" , "R" )
106+
93107
108+ def iter_change_type (self , change_type ):
109+ """
110+ Return
111+ iterator yieling Diff instances that match the given change_type
112+
113+ ``change_type``
114+ Member of DiffIndex.change_type
115+ """
116+ if change_type not in self .change_type :
117+ raise ValueError ( "Invalid change type: %s" % change_type )
118+
119+ for diff in self :
120+ if change_type == "A" and diff .new_file :
121+ yield diff
122+ elif change_type == "D" and diff .deleted_file :
123+ yield diff
124+ elif change_type == "R" and diff .renamed :
125+ yield diff
126+ # END for each diff
94127
95128
96129class Diff (object ):
@@ -132,7 +165,7 @@ class Diff(object):
132165 """ , re .VERBOSE | re .MULTILINE )
133166 re_is_null_hexsha = re .compile ( r'^0{40}$' )
134167 __slots__ = ("a_blob" , "b_blob" , "a_mode" , "b_mode" , "new_file" , "deleted_file" ,
135- "rename_from" , "rename_to" , "renamed" , " diff" )
168+ "rename_from" , "rename_to" , "diff" )
136169
137170 def __init__ (self , repo , a_path , b_path , a_blob_id , b_blob_id , a_mode ,
138171 b_mode , new_file , deleted_file , rename_from ,
@@ -148,17 +181,29 @@ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode,
148181
149182 self .a_mode = a_mode
150183 self .b_mode = b_mode
184+
151185 if self .a_mode :
152186 self .a_mode = blob .Blob ._mode_str_to_int ( self .a_mode )
153187 if self .b_mode :
154188 self .b_mode = blob .Blob ._mode_str_to_int ( self .b_mode )
189+
155190 self .new_file = new_file
156191 self .deleted_file = deleted_file
157- self .rename_from = rename_from
158- self .rename_to = rename_to
159- self .renamed = rename_from != rename_to
192+
193+ # be clear and use None instead of empty strings
194+ self .rename_from = rename_from or None
195+ self .rename_to = rename_to or None
196+
160197 self .diff = diff
161198
199+ @property
200+ def renamed (self ):
201+ """
202+ Returns:
203+ True if the blob of our diff has been renamed
204+ """
205+ return self .rename_from != self .rename_to
206+
162207 @classmethod
163208 def _index_from_patch_format (cls , repo , stream ):
164209 """
@@ -210,20 +255,22 @@ def _index_from_raw_format(cls, repo, stream):
210255 if not line .startswith (":" ):
211256 continue
212257 # END its not a valid diff line
213- old_mode , new_mode , a_blob_id , b_blob_id , modification_id , path = line [1 :].split ()
258+ old_mode , new_mode , a_blob_id , b_blob_id , change_type , path = line [1 :].split ()
214259 a_path = path
215260 b_path = path
216261 deleted_file = False
217262 new_file = False
218- if modification_id == 'D' :
263+
264+ # NOTE: We cannot conclude from the existance of a blob to change type
265+ # as diffs with the working do not have blobs yet
266+ if change_type == 'D' :
219267 b_path = None
220268 deleted_file = True
221- elif modification_id == 'A' :
269+ elif change_type == 'A' :
222270 a_path = None
223271 new_file = True
224272 # END add/remove handling
225273
226-
227274 diff = Diff (repo , a_path , b_path , a_blob_id , b_blob_id , old_mode , new_mode ,
228275 new_file , deleted_file , None , None , '' )
229276 index .append (diff )
0 commit comments