-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathhgpatch.py
More file actions
50 lines (39 loc) · 1.74 KB
/
hgpatch.py
File metadata and controls
50 lines (39 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from mercurial import scmutil
from types import MethodType
from mercurial import encoding
import codecs
# Patches commit-message unicode handling on Python 2.x
# Mercurial is internally unicode. But because it runs from ASCII console, it tries to convert
# all input from "input encoding" (set in mercurial/encoding.py)
# Problem 1:
# If you just pass it u'unicode string', it'll fail. Even if you set "input encoding" to utf-8,
# it'll still try to decode it to ASCII.
# Solution:
# Patch this decoding function to pass unicode unchanged.
old_fromlocal = None
def better_fromlocal(s):
if isinstance(s, unicode):
return s.encode('utf-8')
global old_fromlocal
return old_fromlocal(s)
old_fromlocal = encoding.fromlocal
encoding.fromlocal = better_fromlocal
# Problem 2:
# Separate from actual log, Mercurial stores commit message in commit-message.txt.
# Unfortunately it uses default Python 2.x file.open which expects ASCII and auto-conversion fails.
# Solution:
# Patch virtual-fs open() function to use codecs.open wrapper in this particular case.
old_vfs_call = None
def better_vfs_call(self, path, mode="r", atomictemp=False, notindexed=False,
backgroundclose=False, checkambig=False, auditpath=True,
makeparentdirs=True):
fp = old_vfs_call(self, path, mode, atomictemp, notindexed, backgroundclose,
checkambig, auditpath, makeparentdirs)
if path.endswith('last-message.txt'):
# Create a wrapper like codecs.open does:
info = codecs.lookup("utf-8")
fp = codecs.StreamReaderWriter(fp, info.streamreader, info.streamwriter, 'strict')
fp.encoding = 'utf-8'
return fp
old_vfs_call = scmutil.vfs.vfs.__call__
scmutil.vfs.vfs.__call__ = better_vfs_call