@@ -193,6 +193,8 @@ def iter_change_type(self, change_type):
193193 yield diff
194194 elif change_type == "D" and diff .deleted_file :
195195 yield diff
196+ elif change_type == "C" and diff .copied_file :
197+ yield diff
196198 elif change_type == "R" and diff .renamed :
197199 yield diff
198200 elif change_type == "M" and diff .a_blob and diff .b_blob and diff .a_blob != diff .b_blob :
@@ -243,6 +245,7 @@ class Diff(object):
243245 ^rename[ ]to[ ](?P<rename_to>.*)(?:\n|$))?
244246 (?:^new[ ]file[ ]mode[ ](?P<new_file_mode>.+)(?:\n|$))?
245247 (?:^deleted[ ]file[ ]mode[ ](?P<deleted_file_mode>.+)(?:\n|$))?
248+ (?:^copied[ ]file[ ]mode[ ](?P<copied_file_mode>.+)(?:\n|$))?
246249 (?:^index[ ](?P<a_blob_id>[0-9A-Fa-f]+)
247250 \.\.(?P<b_blob_id>[0-9A-Fa-f]+)[ ]?(?P<b_mode>.+)?(?:\n|$))?
248251 (?:^---[ ](?P<a_path>[^\t\n\r\f\v]*)[\t\r\f\v]*(?:\n|$))?
@@ -253,11 +256,11 @@ class Diff(object):
253256 NULL_BIN_SHA = b"\0 " * 20
254257
255258 __slots__ = ("a_blob" , "b_blob" , "a_mode" , "b_mode" , "a_rawpath" , "b_rawpath" ,
256- "new_file" , "deleted_file" , "raw_rename_from " , "raw_rename_to" ,
257- "diff" , "change_type" , "score" )
259+ "new_file" , "deleted_file" , "copied_file " , "raw_rename_from" ,
260+ "raw_rename_to" , " diff" , "change_type" , "score" )
258261
259262 def __init__ (self , repo , a_rawpath , b_rawpath , a_blob_id , b_blob_id , a_mode ,
260- b_mode , new_file , deleted_file , raw_rename_from ,
263+ b_mode , new_file , deleted_file , copied_file , raw_rename_from ,
261264 raw_rename_to , diff , change_type , score ):
262265
263266 self .a_mode = a_mode
@@ -285,6 +288,7 @@ def __init__(self, repo, a_rawpath, b_rawpath, a_blob_id, b_blob_id, a_mode,
285288
286289 self .new_file = new_file
287290 self .deleted_file = deleted_file
291+ self .copied_file = copied_file
288292
289293 # be clear and use None instead of empty strings
290294 assert raw_rename_from is None or isinstance (raw_rename_from , binary_type )
@@ -336,6 +340,8 @@ def __str__(self):
336340 msg += '\n file deleted in rhs'
337341 if self .new_file :
338342 msg += '\n file added in rhs'
343+ if self .copied_file :
344+ msg += '\n file %r copied from %r' % (self .b_path , self .a_path )
339345 if self .rename_from :
340346 msg += '\n file renamed from %r' % self .rename_from
341347 if self .rename_to :
@@ -419,11 +425,12 @@ def _index_from_patch_format(cls, repo, proc):
419425 a_path_fallback , b_path_fallback , \
420426 old_mode , new_mode , \
421427 rename_from , rename_to , \
422- new_file_mode , deleted_file_mode , \
428+ new_file_mode , deleted_file_mode , copied_file_mode , \
423429 a_blob_id , b_blob_id , b_mode , \
424430 a_path , b_path = header .groups ()
425431
426- new_file , deleted_file = bool (new_file_mode ), bool (deleted_file_mode )
432+ new_file , deleted_file , copied_file = \
433+ bool (new_file_mode ), bool (deleted_file_mode ), bool (copied_file_mode )
427434
428435 a_path = cls ._pick_best_path (a_path , rename_from , a_path_fallback )
429436 b_path = cls ._pick_best_path (b_path , rename_to , b_path_fallback )
@@ -445,7 +452,7 @@ def _index_from_patch_format(cls, repo, proc):
445452 b_blob_id and b_blob_id .decode (defenc ),
446453 a_mode and a_mode .decode (defenc ),
447454 b_mode and b_mode .decode (defenc ),
448- new_file , deleted_file ,
455+ new_file , deleted_file , copied_file ,
449456 rename_from ,
450457 rename_to ,
451458 None , None , None ))
@@ -485,6 +492,7 @@ def handle_diff_line(line):
485492 b_path = path .encode (defenc )
486493 deleted_file = False
487494 new_file = False
495+ copied_file = False
488496 rename_from = None
489497 rename_to = None
490498
@@ -496,6 +504,11 @@ def handle_diff_line(line):
496504 elif change_type == 'A' :
497505 a_blob_id = None
498506 new_file = True
507+ elif change_type == 'C' :
508+ copied_file = True
509+ a_path , b_path = path .split ('\t ' , 1 )
510+ a_path = a_path .encode (defenc )
511+ b_path = b_path .encode (defenc )
499512 elif change_type == 'R' :
500513 a_path , b_path = path .split ('\t ' , 1 )
501514 a_path = a_path .encode (defenc )
@@ -507,8 +520,8 @@ def handle_diff_line(line):
507520 # END add/remove handling
508521
509522 diff = Diff (repo , a_path , b_path , a_blob_id , b_blob_id , old_mode , new_mode ,
510- new_file , deleted_file , rename_from , rename_to , '' ,
511- change_type , score )
523+ new_file , deleted_file , copied_file , rename_from , rename_to ,
524+ '' , change_type , score )
512525 index .append (diff )
513526
514527 handle_process_output (proc , handle_diff_line , None , finalize_process , decode_streams = False )
0 commit comments