[PATCH STABLE] dispatch: setup color before pager for correct console information on windows

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Mon May 22 18:29:52 UTC 2017


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1495477763 -32400
#      Tue May 23 03:29:23 2017 +0900
# Branch stable
# Node ID f928d53b687cb5738528d2eae97f58da10ca8bae
# Parent  99515353c72a4c54e4aac1a2ad4f8f724c7fdc9c
dispatch: setup color before pager for correct console information on windows

Before this patch, "hg CMD --pager on" on Windows shows output
unintentionally decorated with ANSI color escape sequences, if color
mode is "auto". This issue occurs in steps below.

  1. dispatch() invokes ui.pager() at detection of "--pager on"
  2. stdout of hg process is redirected into stdin of pager process
  3. "ui.formatted" = True, because isatty(stdout) is so before (2)
  4. color module is loaded for colorization
  5. color.w32effects = None, because GetConsoleScreenBufferInfo()
     fails on stdout redirected at (2)
  6. "ansi" color mode is chosen, because of "not w32effects"
  7. output is colorized in "ansi" mode because of "ui.formatted" = True

Even if "ansi" color mode is chosen, ordinarily redirected stdout
makes ui.formatted() return False, and colorization is avoided. But in
this issue case, "ui.formatted" = True at (3) forces output to be
colorized.

For correct console information on win32, it is needed to ensure that
color module is loaded before redirection of stdout for pagination.

BTW, if any of enabled extensions has "colortable" attribute, this
issue is avoided even before this patch, because color module is
imported as a part of loading such extension, and extension loading
occurs before setting up pager. For example, mq and keyword have
"colortable".

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -833,22 +833,23 @@ def _dispatch(req):
             for ui_ in uis:
                 ui_.setconfig('ui', 'interactive', 'off', '-y')
 
-        if util.parsebool(options['pager']):
-            ui.pager('internal-always-' + cmd)
-        elif options['pager'] != 'auto':
-            ui.disablepager()
-
         if cmdoptions.get('insecure', False):
             for ui_ in uis:
                 ui_.insecureconnections = True
 
-        # setup color handling
+        # setup color handling before pager, because setting up pager
+        # might cause incorrect console information
         coloropt = options['color']
         for ui_ in uis:
             if coloropt:
                 ui_.setconfig('ui', 'color', coloropt, '--color')
             color.setup(ui_)
 
+        if util.parsebool(options['pager']):
+            ui.pager('internal-always-' + cmd)
+        elif options['pager'] != 'auto':
+            ui.disablepager()
+
         if options['version']:
             return commands.version_(ui)
         if options['help']:


More information about the Mercurial-devel mailing list