1010from .objects .blob import Blob
1111from .objects .util import mode_str_to_int
1212
13- from git .compat import defenc
13+ from git .compat import (
14+ defenc ,
15+ PY3
16+ )
1417
1518
1619__all__ = ('Diffable' , 'DiffIndex' , 'Diff' )
@@ -194,7 +197,7 @@ class Diff(object):
194197 (?:^deleted[ ]file[ ]mode[ ](?P<deleted_file_mode>.+)(?:\n|$))?
195198 (?:^index[ ](?P<a_blob_id>[0-9A-Fa-f]+)
196199 \.\.(?P<b_blob_id>[0-9A-Fa-f]+)[ ]?(?P<b_mode>.+)?(?:\n|$))?
197- """ , re .VERBOSE | re .MULTILINE )
200+ """ . encode ( 'ascii' ) , re .VERBOSE | re .MULTILINE )
198201 # can be used for comparisons
199202 NULL_HEX_SHA = "0" * 40
200203 NULL_BIN_SHA = b"\0 " * 20
@@ -280,11 +283,21 @@ def __str__(self):
280283 msg += '\n file renamed to %r' % self .rename_to
281284 if self .diff :
282285 msg += '\n ---'
283- msg += self .diff
286+ try :
287+ msg += self .diff .decode (defenc )
288+ except UnicodeDecodeError :
289+ msg += 'OMITTED BINARY DATA'
290+ # end handle encoding
284291 msg += '\n ---'
285292 # END diff info
286293
287- return h + msg
294+ # Python2 sillyness: have to assure we convert our likely to be unicode object to a string with the
295+ # right encoding. Otherwise it tries to convert it using ascii, which may fail ungracefully
296+ res = h + msg
297+ if not PY3 :
298+ res = res .encode (defenc )
299+ # end
300+ return res
288301
289302 @property
290303 def renamed (self ):
@@ -298,7 +311,7 @@ def _index_from_patch_format(cls, repo, stream):
298311 :param stream: result of 'git diff' as a stream (supporting file protocol)
299312 :return: git.DiffIndex """
300313 # for now, we have to bake the stream
301- text = stream .read (). decode ( defenc )
314+ text = stream .read ()
302315 index = DiffIndex ()
303316 previous_header = None
304317 for header in cls .re_header .finditer (text ):
@@ -317,8 +330,17 @@ def _index_from_patch_format(cls, repo, stream):
317330 # We just use the one mode we should have parsed
318331 a_mode = old_mode or deleted_file_mode or (a_path and (b_mode or new_mode or new_file_mode ))
319332 b_mode = b_mode or new_mode or new_file_mode or (b_path and a_mode )
320- index .append (Diff (repo , a_path , b_path , a_blob_id , b_blob_id , a_mode , b_mode ,
321- new_file , deleted_file , rename_from , rename_to , None ))
333+ index .append (Diff (repo ,
334+ a_path and a_path .decode (defenc ),
335+ b_path and b_path .decode (defenc ),
336+ a_blob_id and a_blob_id .decode (defenc ),
337+ b_blob_id and b_blob_id .decode (defenc ),
338+ a_mode and a_mode .decode (defenc ),
339+ b_mode and b_mode .decode (defenc ),
340+ new_file , deleted_file ,
341+ rename_from and rename_from .decode (defenc ),
342+ rename_to and rename_to .decode (defenc ),
343+ None ))
322344
323345 previous_header = header
324346 # end for each header we parse
0 commit comments