@@ -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+
2529def diff (self ,other = None ,paths = None ,create_patch = False ,** kwargs ):
2630"""
2731Creates 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``
3135Is the item to compare us with.
3236If None, we will be compared to the working tree.
37+ If Index ( type ), it will be compared against the index
3338
3439``paths``
3540is 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):
6368if paths is not None and not isinstance (paths , (tuple ,list )):
6469paths = [paths ]
6570
66- if other is not None :
71+ if other is not None and other is not self . Index :
6772args .insert (0 ,other )
73+ if other is self .Index :
74+ args .insert (0 ,"--cached" )
6875
6976args .insert (0 ,self )
7077
@@ -90,7 +97,33 @@ class DiffIndex(list):
9097
9198The 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 )
133166re_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
137170def __init__ (self ,repo ,a_path ,b_path ,a_blob_id ,b_blob_id ,a_mode ,
138171b_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
149182self .a_mode = a_mode
150183self .b_mode = b_mode
184+
151185if self .a_mode :
152186self .a_mode = blob .Blob ._mode_str_to_int (self .a_mode )
153187if self .b_mode :
154188self .b_mode = blob .Blob ._mode_str_to_int (self .b_mode )
189+
155190self .new_file = new_file
156191self .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+
160197self .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
163208def _index_from_patch_format (cls ,repo ,stream ):
164209"""
@@ -210,20 +255,22 @@ def _index_from_raw_format(cls, repo, stream):
210255if not line .startswith (":" ):
211256continue
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 ()
214259a_path = path
215260b_path = path
216261deleted_file = False
217262new_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' :
219267b_path = None
220268deleted_file = True
221- elif modification_id == 'A' :
269+ elif change_type == 'A' :
222270a_path = None
223271new_file = True
224272# END add/remove handling
225273
226-
227274diff = Diff (repo ,a_path ,b_path ,a_blob_id ,b_blob_id ,old_mode ,new_mode ,
228275new_file ,deleted_file ,None ,None ,'' )
229276index .append (diff )