Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d02f419

Browse files
committed
Merge pull request #131 from pre-commit/non_utf8_diff
Treat diffs as maybe-not-utf8.
2 parents 105af6f + e40a151 commit d02f419

3 files changed

Lines changed: 32 additions & 13 deletions

File tree

pre_commit/prefixed_command_runner.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,24 @@ def _create_path_if_not_exists(self):
5656
if not os.path.exists(self.prefix_dir):
5757
self.__makedirs(self.prefix_dir)
5858

59-
def run(self, cmd, retcode=0, stdin=None, **kwargs):
59+
def run(self, cmd, retcode=0, stdin=None, encoding='UTF-8', **kwargs):
6060
popen_kwargs = {
6161
'stdin': subprocess.PIPE,
6262
'stdout': subprocess.PIPE,
6363
'stderr': subprocess.PIPE,
6464
}
6565
if stdin is not None:
66-
stdin = stdin.encode('utf-8')
66+
stdin = stdin.encode('UTF-8')
6767

6868
popen_kwargs.update(kwargs)
6969
self._create_path_if_not_exists()
7070
replaced_cmd = _replace_cmd(cmd, prefix=self.prefix_dir)
7171
proc = self.__popen(replaced_cmd, **popen_kwargs)
7272
stdout, stderr = proc.communicate(stdin)
73-
if isinstance(stdout, bytes):
74-
stdout = stdout.decode('UTF-8')
75-
if isinstance(stderr, bytes):
76-
stderr = stderr.decode('UTF-8')
73+
if encoding is not None:
74+
stdout = stdout.decode(encoding)
75+
if encoding is not None:
76+
stderr = stderr.decode(encoding)
7777
returncode = proc.returncode
7878

7979
if retcode is not None and retcode != returncode:

pre_commit/staged_files_only.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,20 @@ def staged_files_only(cmd_runner):
2020
cmd_runner - PrefixedCommandRunner
2121
"""
2222
# Determine if there are unstaged files
23-
retcode, diff_stdout, _ = cmd_runner.run(
23+
retcode, diff_stdout_binary, _ = cmd_runner.run(
2424
['git', 'diff', '--ignore-submodules', '--binary', '--exit-code'],
2525
retcode=None,
26+
encoding=None,
2627
)
27-
if retcode and diff_stdout.strip():
28+
if retcode and diff_stdout_binary.strip():
2829
patch_filename = cmd_runner.path('patch{0}'.format(int(time.time())))
2930
logger.warning('Unstaged files detected.')
3031
logger.info(
3132
'Stashing unstaged files to {0}.'.format(patch_filename),
3233
)
3334
# Save the current unstaged changes as a patch
34-
with io.open(patch_filename, 'w', encoding='utf-8') as patch_file:
35-
patch_file.write(diff_stdout)
35+
with io.open(patch_filename, 'wb') as patch_file:
36+
patch_file.write(diff_stdout_binary)
3637

3738
# Clear the working directory of unstaged changes
3839
cmd_runner.run(['git', 'checkout', '--', '.'])

tests/staged_files_only_test.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: UTF-8 -*-
12
from __future__ import absolute_import
23
from __future__ import unicode_literals
34

@@ -34,9 +35,14 @@ def foo_staged(tmpdir_factory):
3435
yield auto_namedtuple(path=path, foo_filename=foo_filename)
3536

3637

37-
def _test_foo_state(path, foo_contents=FOO_CONTENTS, status='A'):
38+
def _test_foo_state(
39+
path,
40+
foo_contents=FOO_CONTENTS,
41+
status='A',
42+
encoding='UTF-8',
43+
):
3844
assert os.path.exists(path.foo_filename)
39-
assert io.open(path.foo_filename, encoding='utf-8').read() == foo_contents
45+
assert io.open(path.foo_filename, encoding=encoding).read() == foo_contents
4046
actual_status = get_short_git_status()['foo']
4147
assert status == actual_status
4248

@@ -246,10 +252,22 @@ def test_diff_returns_1_no_diff_though(fake_logging_handler, foo_staged):
246252

247253
def test_stage_utf8_changes(foo_staged, cmd_runner):
248254
contents = '\u2603'
249-
with io.open('foo', 'w', encoding='utf-8') as foo_file:
255+
with io.open('foo', 'w', encoding='UTF-8') as foo_file:
250256
foo_file.write(contents)
251257

252258
_test_foo_state(foo_staged, contents, 'AM')
253259
with staged_files_only(cmd_runner):
254260
_test_foo_state(foo_staged)
255261
_test_foo_state(foo_staged, contents, 'AM')
262+
263+
264+
def test_stage_non_utf8_changes(foo_staged, cmd_runner):
265+
contents = 'ú'
266+
# Produce a latin-1 diff
267+
with io.open('foo', 'w', encoding='latin-1') as foo_file:
268+
foo_file.write(contents)
269+
270+
_test_foo_state(foo_staged, contents, 'AM', encoding='latin-1')
271+
with staged_files_only(cmd_runner):
272+
_test_foo_state(foo_staged)
273+
_test_foo_state(foo_staged, contents, 'AM', encoding='latin-1')

0 commit comments

Comments
 (0)