diff --git a/mercurial/posix.py b/mercurial/posix.py --- a/mercurial/posix.py +++ b/mercurial/posix.py @@ -381,6 +381,10 @@ return getattr(osutil, 'getfstype', lambda x: None)(dirpath) +def get_password(): + return encoding.strtolocal(getpass.getpass('')) + + def setbinary(fd): pass diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -11,7 +11,6 @@ import contextlib import datetime import errno -import getpass import inspect import os import re @@ -1779,7 +1778,7 @@ raise EOFError return l.rstrip(b'\n') else: - return encoding.strtolocal(getpass.getpass('')) + return util.get_password() except EOFError: raise error.ResponseExpected() diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -106,6 +106,7 @@ expandglobs = platform.expandglobs getfsmountpoint = platform.getfsmountpoint getfstype = platform.getfstype +get_password = platform.get_password groupmembers = platform.groupmembers groupname = platform.groupname isexec = platform.isexec diff --git a/mercurial/windows.py b/mercurial/windows.py --- a/mercurial/windows.py +++ b/mercurial/windows.py @@ -194,6 +194,28 @@ return False +def get_password(): + """Prompt for password with echo off, using Windows getch(). + + This shouldn't be called directly- use ``ui.getpass()`` instead, which + checks if the session is interactive first. + """ + pw = "" + while True: + c = msvcrt.getwch() + if c == '\r' or c == '\n': + break + if c == '\003': + raise KeyboardInterrupt + if c == '\b': + pw = pw[:-1] + else: + pw = pw + c + msvcrt.putwch('\r') + msvcrt.putwch('\n') + return encoding.strtolocal(pw) + + class winstdout(object): """Some files on Windows misbehave.