@ -34,7 +34,6 @@ class FilePatchBase(object):
def __init__ ( self , filename ) :
def __init__ ( self , filename ) :
assert self . __class__ is not FilePatchBase
assert self . __class__ is not FilePatchBase
self . filename = self . _process_filename ( filename )
self . filename = self . _process_filename ( filename )
self . patchlevel = 0
# Set when the file is copied or moved.
# Set when the file is copied or moved.
self . source_filename = None
self . source_filename = None
@ -66,25 +65,6 @@ class FilePatchBase(object):
filename , ' Filename can \' t be \' %s \' . ' % filename )
filename , ' Filename can \' t be \' %s \' . ' % filename )
return filename
return filename
def filename_after_patchlevel ( self ) :
""" Applies patchlevel to self.filename.
Applies patchlevel to self . filename so the resulting filename is the same as
the one git - apply would have used .
"""
# We use self.patchlevel-1 since git-apply considers the "a/" in the diff
# as part of the file path.
return self . _apply_patchlevel ( self . filename , self . patchlevel - 1 )
def _apply_patchlevel ( self , string , patchlevel = None ) :
""" Apply patchlevel to a file path.
This function replaces backslashes with slashes and removes the first
patchlevel elements of string . patchlevel is self . patchlevel by default .
"""
patchlevel = patchlevel or self . patchlevel
return ' / ' . join ( string . replace ( ' \\ ' , ' / ' ) . split ( ' / ' ) [ patchlevel : ] )
def set_relpath ( self , relpath ) :
def set_relpath ( self , relpath ) :
if not relpath :
if not relpath :
return
return
@ -183,6 +163,7 @@ class FilePatchDiff(FilePatchBase):
self . diff_header , self . diff_hunks = self . _split_header ( diff )
self . diff_header , self . diff_hunks = self . _split_header ( diff )
self . svn_properties = svn_properties or [ ]
self . svn_properties = svn_properties or [ ]
self . is_git_diff = self . _is_git_diff_header ( self . diff_header )
self . is_git_diff = self . _is_git_diff_header ( self . diff_header )
self . patchlevel = 0
if self . is_git_diff :
if self . is_git_diff :
self . _verify_git_header ( )
self . _verify_git_header ( )
else :
else :
@ -333,6 +314,10 @@ class FilePatchDiff(FilePatchBase):
hunks [ 0 ] . start_src - = 1
hunks [ 0 ] . start_src - = 1
return hunks
return hunks
def mangle ( self , string ) :
""" Mangle a file path. """
return ' / ' . join ( string . replace ( ' \\ ' , ' / ' ) . split ( ' / ' ) [ self . patchlevel : ] )
def _verify_git_header ( self ) :
def _verify_git_header ( self ) :
""" Sanity checks the header.
""" Sanity checks the header.
@ -361,8 +346,8 @@ class FilePatchDiff(FilePatchBase):
continue
continue
if match . group ( 1 ) . startswith ( ' a/ ' ) and match . group ( 2 ) . startswith ( ' b/ ' ) :
if match . group ( 1 ) . startswith ( ' a/ ' ) and match . group ( 2 ) . startswith ( ' b/ ' ) :
self . patchlevel = 1
self . patchlevel = 1
old = self . _apply_patchlevel ( match . group ( 1 ) )
old = self . mangle ( match . group ( 1 ) )
new = self . _apply_patchlevel ( match . group ( 2 ) )
new = self . mangle ( match . group ( 2 ) )
# The rename is about the new file so the old file can be anything.
# The rename is about the new file so the old file can be anything.
if new not in ( self . filename_utf8 , ' dev/null ' ) :
if new not in ( self . filename_utf8 , ' dev/null ' ) :
@ -445,7 +430,7 @@ class FilePatchDiff(FilePatchBase):
self . _fail ( ' --- and +++ are reversed ' )
self . _fail ( ' --- and +++ are reversed ' )
if match . group ( 1 ) == ' /dev/null ' :
if match . group ( 1 ) == ' /dev/null ' :
self . is_new = True
self . is_new = True
elif self . _apply_patchlevel ( match . group ( 1 ) ) != old :
elif self . mangle ( match . group ( 1 ) ) != old :
# git patches are always well formatted, do not allow random filenames.
# git patches are always well formatted, do not allow random filenames.
self . _fail ( ' Unexpected git diff: %s != %s . ' % ( old , match . group ( 1 ) ) )
self . _fail ( ' Unexpected git diff: %s != %s . ' % ( old , match . group ( 1 ) ) )
if not lines or not lines [ 0 ] . startswith ( ' +++ ' ) :
if not lines or not lines [ 0 ] . startswith ( ' +++ ' ) :
@ -458,7 +443,7 @@ class FilePatchDiff(FilePatchBase):
self . _fail ( ' Unexpected git diff: --- not following +++. ' )
self . _fail ( ' Unexpected git diff: --- not following +++. ' )
if ' /dev/null ' == match . group ( 1 ) :
if ' /dev/null ' == match . group ( 1 ) :
self . is_delete = True
self . is_delete = True
elif self . filename_utf8 != self . _apply_patchlevel ( match . group ( 1 ) ) :
elif self . filename_utf8 != self . mangle ( match . group ( 1 ) ) :
self . _fail (
self . _fail (
' Unexpected git diff: %s != %s . ' % ( self . filename , match . group ( 1 ) ) )
' Unexpected git diff: %s != %s . ' % ( self . filename , match . group ( 1 ) ) )
if lines :
if lines :
@ -497,7 +482,7 @@ class FilePatchDiff(FilePatchBase):
self . _fail ( ' --- and +++ are reversed ' )
self . _fail ( ' --- and +++ are reversed ' )
if match . group ( 1 ) == ' /dev/null ' :
if match . group ( 1 ) == ' /dev/null ' :
self . is_new = True
self . is_new = True
elif self . _apply_patchlevel ( match . group ( 1 ) ) != self . filename_utf8 :
elif self . mangle ( match . group ( 1 ) ) != self . filename_utf8 :
# guess the source filename.
# guess the source filename.
self . source_filename = match . group ( 1 ) . decode ( ' utf-8 ' )
self . source_filename = match . group ( 1 ) . decode ( ' utf-8 ' )
self . is_new = True
self . is_new = True
@ -511,7 +496,7 @@ class FilePatchDiff(FilePatchBase):
self . _fail ( ' Unexpected diff: --- not following +++. ' )
self . _fail ( ' Unexpected diff: --- not following +++. ' )
if match . group ( 1 ) == ' /dev/null ' :
if match . group ( 1 ) == ' /dev/null ' :
self . is_delete = True
self . is_delete = True
elif self . _apply_patchlevel ( match . group ( 1 ) ) != self . filename_utf8 :
elif self . mangle ( match . group ( 1 ) ) != self . filename_utf8 :
self . _fail ( ' Unexpected diff: %s . ' % match . group ( 1 ) )
self . _fail ( ' Unexpected diff: %s . ' % match . group ( 1 ) )
if lines :
if lines :
self . _fail ( ' Crap after +++ ' )
self . _fail ( ' Crap after +++ ' )