You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mercurial执行拉取/提交/推送时触发UnicodeDecodeError求助

Mercurial 6.1.1 全操作触发UnicodeDecodeError 解决方案

问题概述

Mercurial 6.1.1执行pull、commit、push等所有操作时均触发UnicodeDecodeError,错误核心为:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128)

从栈追踪看,问题出在Mercurial尝试用ASCII编码解码包含非ASCII字符的密码(或认证信息)时失败。

错误栈详情

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128)

** unknown exception encountered, please report by visiting
** https://mercurial-scm.org/wiki/BugTracker
** Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]
** Mercurial Distributed SCM (version 6.1.1)
** Extensions loaded: 
Traceback (most recent call last):
  File "/usr/bin/hg", line 61, in <module>
    dispatch.run()
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 144, in run
    status = dispatch(req)
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 250, in dispatch
    status = _rundispatch(req)
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 294, in _rundispatch
    ret = _runcatch(req) or 0
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 470, in _runcatch
    return _callcatch(ui, _runcatchfunc)
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 480, in _callcatch
    return scmutil.callcatch(ui, func)
  File "/usr/lib/python3/dist-packages/mercurial/scmutil.py", line 153, in callcatch
    return func()
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 460, in _runcatchfunc
    return _dispatch(req)
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 1273, in _dispatch
    return runcommand(
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 918, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 1285, in _runcommand
    return cmdfunc()
  File "/usr/lib/python3/dist-packages/mercurial/dispatch.py", line 1271, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
  File "/usr/lib/python3/dist-packages/mercurial/util.py", line 1887, in check
    return func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/mercurial/commands.py", line 5407, in pull
    other = hg.peer(repo, opts, source)
  File "/usr/lib/python3/dist-packages/mercurial/hg.py", line 239, in peer
    return _peerorrepo(
  File "/usr/lib/python3/dist-packages/mercurial/hg.py", line 187, in _peerorrepo
    obj = _peerlookup(path).instance(
  File "/usr/lib/python3/dist-packages/mercurial/httppeer.py", line 645, in instance
    inst = makepeer(ui, path)
  File "/usr/lib/python3/dist-packages/mercurial/httppeer.py", line 629, in makepeer
    respurl, info = performhandshake(ui, url, opener, requestbuilder)
  File "/usr/lib/python3/dist-packages/mercurial/httppeer.py", line 568, in performhandshake
    resp = sendrequest(ui, opener, req)
  File "/usr/lib/python3/dist-packages/mercurial/httppeer.py", line 288, in sendrequest
    res = opener.open(req)
  File "/usr/lib/python3.10/urllib/request.py", line 525, in open
    response = meth(req, response)
  File "/usr/lib/python3.10/urllib/request.py", line 634, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.10/urllib/request.py", line 557, in error
    result = self._call_chain(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.10/urllib/request.py", line 1056, in http_error_401
    response = self.http_error_auth_reqed('www-authenticate',
  File "/usr/lib/python3/dist-packages/mercurial/url.py", line 524, in http_error_auth_reqed
    return urlreq.httpbasicauthhandler.http_error_auth_reqed(
  File "/usr/lib/python3.10/urllib/request.py", line 1005, in http_error_auth_reqed
    return self.retry_http_basic_auth(host, req, realm)
  File "/usr/lib/python3/dist-packages/mercurial/url.py", line 529, in retry_http_basic_auth
    user, pw = self.passwd.find_user_password(
  File "/usr/lib/python3/dist-packages/mercurial/url.py", line 108, in find_user_password
    self.passwddb.add_password(realm, authuri, user, passwd)
  File "/usr/lib/python3/dist-packages/mercurial/ui.py", line 189, in add_password
    _maybestrurl(passwd),
  File "/usr/lib/python3/dist-packages/mercurial/ui.py", line 166, in _maybestrurl
    return pycompat.rapply(pycompat.strurl, maybebytes)
  File "/usr/lib/python3/dist-packages/mercurial/pycompat.py", line 98, in rapply
    return _rapply(f, xs)
  File "/usr/lib/python3/dist-packages/mercurial/pycompat.py", line 74, in _rapply
    return f(xs)
  File "/usr/lib/python3/dist-packages/mercurial/pycompat.py", line 293, in strurl
    return url.decode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128)

解决方案

  • 检查并修复认证信息
    打开全局~/.hgrc或仓库本地.hg/hgrc文件,查看[auth]段中的username和password字段,确认是否包含非ASCII字符(比如0xe2对应类似“€”的符号)。将这类字符替换为ASCII兼容内容,同时确保配置文件以UTF-8编码保存。

  • 临时修改Mercurial解码逻辑
    找到/usr/lib/python3/dist-packages/mercurial/pycompat.py文件,定位到strurl函数:

    def strurl(url):
        return url.decode('ascii')
    

    将其修改为:

    def strurl(url):
        return url.decode('utf-8')
    

    保存文件后重试操作,该修改让Mercurial用UTF-8解码包含特殊字符的认证信息。

  • 升级Mercurial版本
    该ASCII解码问题已在Mercurial 6.2及以上版本中修复,直接升级到最新稳定版即可彻底解决。

  • 配置系统UTF-8环境
    确保系统环境变量设置为UTF-8编码:

    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8
    

    避免Mercurial默认使用ASCII编码处理文本内容。

内容的提问来源于stack exchange,提问作者Chad_Manoj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:44:53