| Index: patch.py
|
| diff --git a/patch.py b/patch.py
|
| index 69ba32305bf32a8acfaaa6b9352f06d34d12574d..90886e9a0fc23ae142e1f524ecee7f18f83d39fe 100644
|
| --- a/patch.py
|
| +++ b/patch.py
|
| @@ -37,6 +37,15 @@ class FilePatchBase(object):
|
| # Set when the file is copied or moved.
|
| self.source_filename = None
|
|
|
| + @property
|
| + def filename_utf8(self):
|
| + return self.filename.encode('utf-8')
|
| +
|
| + @property
|
| + def source_filename_utf8(self):
|
| + if self.source_filename is not None:
|
| + return self.source_filename.encode('utf-8')
|
| +
|
| @staticmethod
|
| def _process_filename(filename):
|
| filename = filename.replace('\\', '/')
|
| @@ -88,8 +97,8 @@ class FilePatchBase(object):
|
| out += ' '
|
| out += ' '
|
| if self.source_filename:
|
| - out += '%s->' % self.source_filename
|
| - return out + str(self.filename)
|
| + out += '%s->' % self.source_filename_utf8
|
| + return out + self.filename_utf8
|
|
|
|
|
| class FilePatchDelete(FilePatchBase):
|
| @@ -153,25 +162,27 @@ class FilePatchDiff(FilePatchBase):
|
| # patch is stupid. It patches the source_filename instead so get rid of
|
| # any source_filename reference if needed.
|
| return (
|
| - self.diff_header.replace(self.source_filename, self.filename) +
|
| + self.diff_header.replace(
|
| + self.source_filename_utf8, self.filename_utf8) +
|
| self.diff_hunks)
|
|
|
| def set_relpath(self, relpath):
|
| - old_filename = self.filename
|
| - old_source_filename = self.source_filename or self.filename
|
| + old_filename = self.filename_utf8
|
| + old_source_filename = self.source_filename_utf8 or self.filename_utf8
|
| super(FilePatchDiff, self).set_relpath(relpath)
|
| # Update the header too.
|
| - source_filename = self.source_filename or self.filename
|
| + filename = self.filename_utf8
|
| + source_filename = self.source_filename_utf8 or self.filename_utf8
|
| lines = self.diff_header.splitlines(True)
|
| for i, line in enumerate(lines):
|
| if line.startswith('diff --git'):
|
| lines[i] = line.replace(
|
| 'a/' + old_source_filename, source_filename).replace(
|
| - 'b/' + old_filename, self.filename)
|
| + 'b/' + old_filename, filename)
|
| elif re.match(r'^\w+ from .+$', line) or line.startswith('---'):
|
| lines[i] = line.replace(old_source_filename, source_filename)
|
| elif re.match(r'^\w+ to .+$', line) or line.startswith('+++'):
|
| - lines[i] = line.replace(old_filename, self.filename)
|
| + lines[i] = line.replace(old_filename, filename)
|
| self.diff_header = ''.join(lines)
|
|
|
| def _split_header(self, diff):
|
| @@ -197,7 +208,7 @@ class FilePatchDiff(FilePatchBase):
|
|
|
| # Mangle any \\ in the header to /.
|
| header_lines = ('Index:', 'diff', 'copy', 'rename', '+++', '---')
|
| - basename = os.path.basename(self.filename)
|
| + basename = os.path.basename(self.filename_utf8)
|
| for i in xrange(len(header)):
|
| if (header[i].split(' ', 1)[0] in header_lines or
|
| header[i].endswith(basename)):
|
| @@ -314,7 +325,7 @@ class FilePatchDiff(FilePatchBase):
|
| new = self.mangle(match.group(2))
|
|
|
| # The rename is about the new file so the old file can be anything.
|
| - if new not in (self.filename, 'dev/null'):
|
| + if new not in (self.filename_utf8, 'dev/null'):
|
| self._fail('Unexpected git diff output name %s.' % new)
|
| if old == 'dev/null' and new == 'dev/null':
|
| self._fail('Unexpected /dev/null git diff.')
|
| @@ -323,9 +334,9 @@ class FilePatchDiff(FilePatchBase):
|
| if not old or not new:
|
| self._fail('Unexpected git diff; couldn\'t find git header.')
|
|
|
| - if old not in (self.filename, 'dev/null'):
|
| + if old not in (self.filename_utf8, 'dev/null'):
|
| # Copy or rename.
|
| - self.source_filename = old
|
| + self.source_filename = old.decode('utf-8')
|
| self.is_new = True
|
|
|
| last_line = ''
|
| @@ -337,7 +348,7 @@ class FilePatchDiff(FilePatchBase):
|
|
|
| # Cheap check to make sure the file name is at least mentioned in the
|
| # 'diff' header. That the only remaining invariant.
|
| - if not self.filename in self.diff_header:
|
| + if not self.filename_utf8 in self.diff_header:
|
| self._fail('Diff seems corrupted.')
|
|
|
| def _verify_git_header_process_line(self, lines, line, last_line):
|
| @@ -349,7 +360,7 @@ class FilePatchDiff(FilePatchBase):
|
| http://www.kernel.org/pub/software/scm/git/docs/git-diff.html
|
| """
|
| match = re.match(r'^(rename|copy) from (.+)$', line)
|
| - old = self.source_filename or self.filename
|
| + old = self.source_filename_utf8 or self.filename_utf8
|
| if match:
|
| if old != match.group(2):
|
| self._fail('Unexpected git diff input name for line %s.' % line)
|
| @@ -361,7 +372,7 @@ class FilePatchDiff(FilePatchBase):
|
|
|
| match = re.match(r'^(rename|copy) to (.+)$', line)
|
| if match:
|
| - if self.filename != match.group(2):
|
| + if self.filename_utf8 != match.group(2):
|
| self._fail('Unexpected git diff output name for line %s.' % line)
|
| if not last_line.startswith('%s from ' % match.group(1)):
|
| self._fail(
|
| @@ -404,7 +415,7 @@ class FilePatchDiff(FilePatchBase):
|
| self._fail('Unexpected git diff: --- not following +++.')
|
| if '/dev/null' == match.group(1):
|
| self.is_delete = True
|
| - elif self.filename != self.mangle(match.group(1)):
|
| + elif self.filename_utf8 != self.mangle(match.group(1)):
|
| self._fail(
|
| 'Unexpected git diff: %s != %s.' % (self.filename, match.group(1)))
|
| if lines:
|
| @@ -429,7 +440,7 @@ class FilePatchDiff(FilePatchBase):
|
|
|
| # Cheap check to make sure the file name is at least mentioned in the
|
| # 'diff' header. That the only remaining invariant.
|
| - if not self.filename in self.diff_header:
|
| + if not self.filename_utf8 in self.diff_header:
|
| self._fail('Diff seems corrupted.')
|
|
|
| def _verify_svn_header_process_line(self, lines, line, last_line):
|
| @@ -443,9 +454,9 @@ class FilePatchDiff(FilePatchBase):
|
| self._fail('--- and +++ are reversed')
|
| if match.group(1) == '/dev/null':
|
| self.is_new = True
|
| - elif self.mangle(match.group(1)) != self.filename:
|
| + elif self.mangle(match.group(1)) != self.filename_utf8:
|
| # guess the source filename.
|
| - self.source_filename = match.group(1)
|
| + self.source_filename = match.group(1).decode('utf-8')
|
| self.is_new = True
|
| if not lines or not lines[0].startswith('+++'):
|
| self._fail('Nothing after header.')
|
| @@ -457,7 +468,7 @@ class FilePatchDiff(FilePatchBase):
|
| self._fail('Unexpected diff: --- not following +++.')
|
| if match.group(1) == '/dev/null':
|
| self.is_delete = True
|
| - elif self.mangle(match.group(1)) != self.filename:
|
| + elif self.mangle(match.group(1)) != self.filename_utf8:
|
| self._fail('Unexpected diff: %s.' % match.group(1))
|
| if lines:
|
| self._fail('Crap after +++')
|
| @@ -479,10 +490,10 @@ class PatchSet(object):
|
| Deletes are last.
|
| """
|
| if p.source_filename:
|
| - return (p.is_delete, p.source_filename, p.filename)
|
| + return (p.is_delete, p.source_filename_utf8, p.filename_utf8)
|
| else:
|
| # tuple are always greater than string, abuse that fact.
|
| - return (p.is_delete, (p.filename,), p.filename)
|
| + return (p.is_delete, (p.filename_utf8,), p.filename_utf8)
|
|
|
| self.patches = sorted(patches, key=key)
|
|
|
|
|