[PATCH 2 of 8 simple] color: move '_effect' mapping into core

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1479491318 -3600
#  Fri Nov 18 18:48:38 2016 +0100
# Node ID fd46adc1f3ab7bb0800a9ff6482f7554bad8637e
# Parent  42d4b49b39d6879065209ea3ca71f1e3fa88fcbc
# EXP-Topic color
color: move '_effect' mapping into core

This is the second things we can move into core safely.

diff -r 42d4b49b39d6 -r fd46adc1f3ab hgext/color.py
--- a/hgext/color.pyFri Nov 18 18:43:39 2016 +0100
+++ b/hgext/color.pyFri Nov 18 18:48:38 2016 +0100
@@ -186,30 +186,6 @@ command = cmdutil.command(cmdtable)
 # leave the attribute unspecified.
 testedwith = 'ships-with-hg-core'
 
-# start and stop parameters for effects
-_effects = {'none': 0,
-'black': 30,
-'red': 31,
-'green': 32,
-'yellow': 33,
-'blue': 34,
-'magenta': 35,
-'cyan': 36,
-'white': 37,
-'bold': 1,
-'italic': 3,
-'underline': 4,
-'inverse': 7,
-'dim': 2,
-'black_background': 40,
-'red_background': 41,
-'green_background': 42,
-'yellow_background': 43,
-'blue_background': 44,
-'purple_background': 45,
-'cyan_background': 46,
-'white_background': 47}
-
 def _terminfosetup(ui, mode):
 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
 
@@ -298,7 +274,7 @@ def _modesetup(ui, coloropt):
 if not w32effects:
 modewarn()
 return None
-_effects.update(w32effects)
+color._effects.update(w32effects)
 elif realmode == 'ansi':
 _terminfo_params.clear()
 elif realmode == 'terminfo':
@@ -365,9 +341,9 @@ def render_effects(text, effects):
 if not text:
 return text
 if not _terminfo_params:
-start = [str(_effects[e]) for e in ['none'] + effects.split()]
+start = [str(color._effects[e]) for e in ['none'] + effects.split()]
 start = '\033[' + ';'.join(start) + 'm'
-stop = '\033[' + str(_effects['none']) + 'm'
+stop = '\033[' + str(color._effects['none']) + 'm'
 else:
 start = ''.join(_effect_str(effect)
 for effect in ['none'] + effects.split())
@@ -377,7 +353,7 @@ def render_effects(text, effects):
 def valideffect(effect):
 'Determine if the effect is valid or not.'
 good = False
-if not _terminfo_params and effect in _effects:
+if not _terminfo_params and effect in color._effects:
 good = True
 elif effect in _terminfo_params or effect[:-11] in _terminfo_params:
 good = True
@@ -505,7 +481,7 @@ def _debugdisplaycolor(ui):
 oldstyle = color._styles.copy()
 try:
 color._styles.clear()
-for effect in _effects.keys():
+for effect in color._effects.keys():
 color._styles[effect] = effect
 if _terminfo_params:
 for k, v in ui.configitems('color'):
diff -r 42d4b49b39d6 -r fd46adc1f3ab mercurial/color.py
--- a/mercurial/color.pyFri Nov 18 18:43:39 2016 +0100
+++ b/mercurial/color.pyFri Nov 18 18:48:38 2016 +0100
@@ -7,6 +7,30 @@
 
 from __future__ import absolute_import
 
+# start and stop parameters for effects
+_effects = {'none': 0,
+'black': 30,
+'red': 31,
+'green': 32,
+'yellow': 33,
+'blue': 34,
+'magenta': 35,
+'cyan': 36,
+'white': 37,
+'bold': 1,
+'italic': 3,
+'underline': 4,
+'inverse': 7,
+'dim': 2,
+'black_background': 40,
+'red_background': 41,
+'green_background': 42,
+'yellow_background': 43,
+'blue_background': 44,
+'purple_background': 45,
+'cyan_background': 46,
+'white_background': 47}
+
 _styles = {'grep.match': 'red bold',
'grep.linenumber': 'green',
'grep.rev': 'green',
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8 simple] color: move configstyles into the core module

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482370462 -3600
#  Thu Dec 22 02:34:22 2016 +0100
# Node ID 93992a625b7141ab5ba0a6cdd5db1aac3ab75361
# Parent  07618a3840fbce3ab1084765d94ac8d7a9380ff8
# EXP-Topic color
color: move configstyles into the core module

The extension is getting thinner as we speak!

diff -r 07618a3840fb -r 93992a625b71 hgext/color.py
--- a/hgext/color.pyThu Dec 22 02:30:03 2016 +0100
+++ b/hgext/color.pyThu Dec 22 02:34:22 2016 +0100
@@ -332,22 +332,6 @@ def render_effects(text, effects):
 stop = _effect_str('none')
 return ''.join([start, text, stop])
 
-def configstyles(ui):
-for status, cfgeffects in ui.configitems('color'):
-if '.' not in status or status.startswith(('color.', 'terminfo.')):
-continue
-cfgeffects = ui.configlist('color', status)
-if cfgeffects:
-good = []
-for e in cfgeffects:
-if color.valideffect(e):
-good.append(e)
-else:
-ui.warn(_("ignoring unknown color/effect %r "
-  "(configured in color.%s)\n")
-% (e, status))
-color._styles[status] = ' '.join(good)
-
 class colorui(uimod.ui):
 _colormode = 'ansi'
 def write(self, *args, **opts):
@@ -420,7 +404,7 @@ def uisetup(ui):
 mode = _modesetup(ui_, opts['color'])
 colorui._colormode = mode
 if mode and mode != 'debug':
-configstyles(ui_)
+color.configstyles(ui_)
 return orig(ui_, opts, cmd, cmdfunc)
 def colorgit(orig, gitsub, commands, env=None, stream=False, cwd=None):
 if gitsub.ui._colormode and len(commands) and commands[0] == "diff":
diff -r 07618a3840fb -r 93992a625b71 mercurial/color.py
--- a/mercurial/color.pyThu Dec 22 02:30:03 2016 +0100
+++ b/mercurial/color.pyThu Dec 22 02:34:22 2016 +0100
@@ -7,6 +7,8 @@
 
 from __future__ import absolute_import
 
+from .i18n import _
+
 try:
 import curses
 # Mapping from effect name to terminfo attribute name (or raw code) or
@@ -114,6 +116,22 @@ except ImportError:
 def loadcolortable(ui, extname, colortable):
 _styles.update(colortable)
 
+def configstyles(ui):
+for status, cfgeffects in ui.configitems('color'):
+if '.' not in status or status.startswith(('color.', 'terminfo.')):
+continue
+cfgeffects = ui.configlist('color', status)
+if cfgeffects:
+good = []
+for e in cfgeffects:
+if valideffect(e):
+good.append(e)
+else:
+ui.warn(_("ignoring unknown color/effect %r "
+  "(configured in color.%s)\n")
+% (e, status))
+_styles[status] = ' '.join(good)
+
 def valideffect(effect):
 'Determine if the effect is valid or not.'
 return ((not _terminfo_params and effect in _effects)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8 simple] color: move 'valideffect' function into the core module

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482370010 -3600
#  Thu Dec 22 02:26:50 2016 +0100
# Node ID bb59bec58bcdf57a3aeb1a9cd4a9b5b004c7c139
# Parent  b0ca5e9e8d9a6afa98accda7fcd5433ff19ddd1e
# EXP-Topic color
color: move 'valideffect' function into the core module

diff -r b0ca5e9e8d9a -r bb59bec58bcd hgext/color.py
--- a/hgext/color.pyThu Dec 22 02:23:23 2016 +0100
+++ b/hgext/color.pyThu Dec 22 02:26:50 2016 +0100
@@ -332,16 +332,6 @@ def render_effects(text, effects):
 stop = _effect_str('none')
 return ''.join([start, text, stop])
 
-def valideffect(effect):
-'Determine if the effect is valid or not.'
-good = False
-if not color._terminfo_params and effect in color._effects:
-good = True
-elif (effect in color._terminfo_params
-  or effect[:-11] in color._terminfo_params):
-good = True
-return good
-
 def configstyles(ui):
 for status, cfgeffects in ui.configitems('color'):
 if '.' not in status or status.startswith(('color.', 'terminfo.')):
@@ -350,7 +340,7 @@ def configstyles(ui):
 if cfgeffects:
 good = []
 for e in cfgeffects:
-if valideffect(e):
+if color.valideffect(e):
 good.append(e)
 else:
 ui.warn(_("ignoring unknown color/effect %r "
@@ -412,7 +402,7 @@ class colorui(uimod.ui):
 s = color._styles.get(l, '')
 if s:
 effects.append(s)
-elif valideffect(l):
+elif color.valideffect(l):
 effects.append(l)
 effects = ' '.join(effects)
 if effects:
diff -r b0ca5e9e8d9a -r bb59bec58bcd mercurial/color.py
--- a/mercurial/color.pyThu Dec 22 02:23:23 2016 +0100
+++ b/mercurial/color.pyThu Dec 22 02:26:50 2016 +0100
@@ -113,3 +113,13 @@ except ImportError:
 
 def loadcolortable(ui, extname, colortable):
 _styles.update(colortable)
+
+def valideffect(effect):
+'Determine if the effect is valid or not.'
+good = False
+if not _terminfo_params and effect in _effects:
+good = True
+elif (effect in _terminfo_params
+  or effect[:-11] in _terminfo_params):
+good = True
+return good
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8 simple] color: move '_effect_str' function into the core module

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482370638 -3600
#  Thu Dec 22 02:37:18 2016 +0100
# Node ID 93e658cd6e685593ddc94d2b46ba596b1bb0d143
# Parent  93992a625b7141ab5ba0a6cdd5db1aac3ab75361
# EXP-Topic color
color: move '_effect_str' function into the core module

diff -r 93992a625b71 -r 93e658cd6e68 hgext/color.py
--- a/hgext/color.pyThu Dec 22 02:34:22 2016 +0100
+++ b/hgext/color.pyThu Dec 22 02:37:18 2016 +0100
@@ -297,27 +297,6 @@ def _modesetup(ui, coloropt):
 return realmode
 return None
 
-def _effect_str(effect):
-'''Helper function for render_effects().'''
-
-bg = False
-if effect.endswith('_background'):
-bg = True
-effect = effect[:-11]
-try:
-attr, val, termcode = color._terminfo_params[effect]
-except KeyError:
-return ''
-if attr:
-if termcode:
-return termcode
-else:
-return curses.tigetstr(val)
-elif bg:
-return curses.tparm(curses.tigetstr('setab'), val)
-else:
-return curses.tparm(curses.tigetstr('setaf'), val)
-
 def render_effects(text, effects):
 'Wrap text in commands to turn on each effect.'
 if not text:
@@ -327,9 +306,9 @@ def render_effects(text, effects):
 start = '\033[' + ';'.join(start) + 'm'
 stop = '\033[' + str(color._effects['none']) + 'm'
 else:
-start = ''.join(_effect_str(effect)
+start = ''.join(color._effect_str(effect)
 for effect in ['none'] + effects.split())
-stop = _effect_str('none')
+stop = color._effect_str('none')
 return ''.join([start, text, stop])
 
 class colorui(uimod.ui):
diff -r 93992a625b71 -r 93e658cd6e68 mercurial/color.py
--- a/mercurial/color.pyThu Dec 22 02:34:22 2016 +0100
+++ b/mercurial/color.pyThu Dec 22 02:37:18 2016 +0100
@@ -137,3 +137,24 @@ def valideffect(effect):
 return ((not _terminfo_params and effect in _effects)
  or (effect in _terminfo_params
  or effect[:-11] in _terminfo_params))
+
+def _effect_str(effect):
+'''Helper function for render_effects().'''
+
+bg = False
+if effect.endswith('_background'):
+bg = True
+effect = effect[:-11]
+try:
+attr, val, termcode = _terminfo_params[effect]
+except KeyError:
+return ''
+if attr:
+if termcode:
+return termcode
+else:
+return curses.tigetstr(val)
+elif bg:
+return curses.tparm(curses.tigetstr('setab'), val)
+else:
+return curses.tparm(curses.tigetstr('setaf'), val)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8 simple] color: move the '_render_effects' function to the core module

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482370733 -3600
#  Thu Dec 22 02:38:53 2016 +0100
# Node ID f0f04ac8d4b17345b5375e4b11d895e7c22eb6ab
# Parent  93e658cd6e685593ddc94d2b46ba596b1bb0d143
# EXP-Topic color
color: move the '_render_effects' function to the core module

diff -r 93e658cd6e68 -r f0f04ac8d4b1 hgext/color.py
--- a/hgext/color.pyThu Dec 22 02:37:18 2016 +0100
+++ b/hgext/color.pyThu Dec 22 02:38:53 2016 +0100
@@ -297,20 +297,6 @@ def _modesetup(ui, coloropt):
 return realmode
 return None
 
-def render_effects(text, effects):
-'Wrap text in commands to turn on each effect.'
-if not text:
-return text
-if not color._terminfo_params:
-start = [str(color._effects[e]) for e in ['none'] + effects.split()]
-start = '\033[' + ';'.join(start) + 'm'
-stop = '\033[' + str(color._effects['none']) + 'm'
-else:
-start = ''.join(color._effect_str(effect)
-for effect in ['none'] + effects.split())
-stop = color._effect_str('none')
-return ''.join([start, text, stop])
-
 class colorui(uimod.ui):
 _colormode = 'ansi'
 def write(self, *args, **opts):
@@ -369,7 +355,7 @@ class colorui(uimod.ui):
 effects.append(l)
 effects = ' '.join(effects)
 if effects:
-return '\n'.join([render_effects(line, effects)
+return '\n'.join([color._render_effects(line, effects)
   for line in msg.split('\n')])
 return msg
 
diff -r 93e658cd6e68 -r f0f04ac8d4b1 mercurial/color.py
--- a/mercurial/color.pyThu Dec 22 02:37:18 2016 +0100
+++ b/mercurial/color.pyThu Dec 22 02:38:53 2016 +0100
@@ -158,3 +158,17 @@ def _effect_str(effect):
 return curses.tparm(curses.tigetstr('setab'), val)
 else:
 return curses.tparm(curses.tigetstr('setaf'), val)
+
+def _render_effects(text, effects):
+'Wrap text in commands to turn on each effect.'
+if not text:
+return text
+if not _terminfo_params:
+start = [str(_effects[e]) for e in ['none'] + effects.split()]
+start = '\033[' + ';'.join(start) + 'm'
+stop = '\033[' + str(_effects['none']) + 'm'
+else:
+start = ''.join(_effect_str(effect)
+for effect in ['none'] + effects.split())
+stop = _effect_str('none')
+return ''.join([start, text, stop])
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8 simple] color: spread '_effect' values for readability

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1479491019 -3600
#  Fri Nov 18 18:43:39 2016 +0100
# Node ID 42d4b49b39d6879065209ea3ca71f1e3fa88fcbc
# Parent  354020079723e02ad6db68f58ef26eb7ebd005a8
# EXP-Topic color
color: spread '_effect' values for readability

We move to our "usual" one value per line style.

diff -r 354020079723 -r 42d4b49b39d6 hgext/color.py
--- a/hgext/color.pyTue Feb 07 17:33:35 2017 +0100
+++ b/hgext/color.pyFri Nov 18 18:43:39 2016 +0100
@@ -187,13 +187,28 @@ command = cmdutil.command(cmdtable)
 testedwith = 'ships-with-hg-core'
 
 # start and stop parameters for effects
-_effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
-'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
-'italic': 3, 'underline': 4, 'inverse': 7, 'dim': 2,
-'black_background': 40, 'red_background': 41,
-'green_background': 42, 'yellow_background': 43,
-'blue_background': 44, 'purple_background': 45,
-'cyan_background': 46, 'white_background': 47}
+_effects = {'none': 0,
+'black': 30,
+'red': 31,
+'green': 32,
+'yellow': 33,
+'blue': 34,
+'magenta': 35,
+'cyan': 36,
+'white': 37,
+'bold': 1,
+'italic': 3,
+'underline': 4,
+'inverse': 7,
+'dim': 2,
+'black_background': 40,
+'red_background': 41,
+'green_background': 42,
+'yellow_background': 43,
+'blue_background': 44,
+'purple_background': 45,
+'cyan_background': 46,
+'white_background': 47}
 
 def _terminfosetup(ui, mode):
 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8 simple] color: rework conditional 'valideffect'

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482370203 -3600
#  Thu Dec 22 02:30:03 2016 +0100
# Node ID 07618a3840fbce3ab1084765d94ac8d7a9380ff8
# Parent  bb59bec58bcdf57a3aeb1a9cd4a9b5b004c7c139
# EXP-Topic color
color: rework conditional 'valideffect'

Not very important, but the full conditional is not that hard to follow and
having it unified make the function role a bit clearer in my opinion.

diff -r bb59bec58bcd -r 07618a3840fb mercurial/color.py
--- a/mercurial/color.pyThu Dec 22 02:26:50 2016 +0100
+++ b/mercurial/color.pyThu Dec 22 02:30:03 2016 +0100
@@ -116,10 +116,6 @@ def loadcolortable(ui, extname, colortab
 
 def valideffect(effect):
 'Determine if the effect is valid or not.'
-good = False
-if not _terminfo_params and effect in _effects:
-good = True
-elif (effect in _terminfo_params
-  or effect[:-11] in _terminfo_params):
-good = True
-return good
+return ((not _terminfo_params and effect in _effects)
+ or (effect in _terminfo_params
+ or effect[:-11] in _terminfo_params))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8 simple] color: move '_terminfo_params' into the core 'color' module

2017-02-15 Thread Pierre-Yves David
# HG changeset patch
# User Pierre-Yves David 
# Date 1482369803 -3600
#  Thu Dec 22 02:23:23 2016 +0100
# Node ID b0ca5e9e8d9a6afa98accda7fcd5433ff19ddd1e
# Parent  fd46adc1f3ab7bb0800a9ff6482f7554bad8637e
# EXP-Topic color
color: move '_terminfo_params' into the core 'color' module

On step closer to have color in core.

diff -r fd46adc1f3ab -r b0ca5e9e8d9a hgext/color.py
--- a/hgext/color.pyFri Nov 18 18:48:38 2016 +0100
+++ b/hgext/color.pyThu Dec 22 02:23:23 2016 +0100
@@ -164,6 +164,12 @@ If ``pagermode`` is not defined, the ``m
 
 from __future__ import absolute_import
 
+try:
+import curses
+curses.COLOR_BLACK # force import
+except ImportError:
+curses = None
+
 from mercurial.i18n import _
 from mercurial import (
 cmdutil,
@@ -190,40 +196,41 @@ def _terminfosetup(ui, mode):
 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
 
 # If we failed to load curses, we go ahead and return.
-if not _terminfo_params:
+if not color._terminfo_params:
 return
 # Otherwise, see what the config file says.
 if mode not in ('auto', 'terminfo'):
 return
 
-_terminfo_params.update((key[6:], (False, int(val), ''))
+color._terminfo_params.update((key[6:], (False, int(val), ''))
 for key, val in ui.configitems('color')
 if key.startswith('color.'))
-_terminfo_params.update((key[9:], (True, '', val.replace('\\E', '\x1b')))
+color._terminfo_params.update((key[9:],
+   (True, '', val.replace('\\E', '\x1b')))
 for key, val in ui.configitems('color')
 if key.startswith('terminfo.'))
 
 try:
 curses.setupterm()
 except curses.error as e:
-_terminfo_params.clear()
+color._terminfo_params.clear()
 return
 
-for key, (b, e, c) in _terminfo_params.items():
+for key, (b, e, c) in color._terminfo_params.items():
 if not b:
 continue
 if not c and not curses.tigetstr(e):
 # Most terminals don't support dim, invis, etc, so don't be
 # noisy and use ui.debug().
 ui.debug("no terminfo entry for %s\n" % e)
-del _terminfo_params[key]
+del color._terminfo_params[key]
 if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
 # Only warn about missing terminfo entries if we explicitly asked for
 # terminfo mode.
 if mode == "terminfo":
 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
   "ECMA-48 color\n"))
-_terminfo_params.clear()
+color._terminfo_params.clear()
 
 def _modesetup(ui, coloropt):
 if coloropt == 'debug':
@@ -270,16 +277,16 @@ def _modesetup(ui, coloropt):
 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
 
 if realmode == 'win32':
-_terminfo_params.clear()
+color._terminfo_params.clear()
 if not w32effects:
 modewarn()
 return None
 color._effects.update(w32effects)
 elif realmode == 'ansi':
-_terminfo_params.clear()
+color._terminfo_params.clear()
 elif realmode == 'terminfo':
 _terminfosetup(ui, mode)
-if not _terminfo_params:
+if not color._terminfo_params:
 ## FIXME Shouldn't we return None in this case too?
 modewarn()
 realmode = 'ansi'
@@ -290,31 +297,6 @@ def _modesetup(ui, coloropt):
 return realmode
 return None
 
-try:
-import curses
-# Mapping from effect name to terminfo attribute name (or raw code) or
-# color number.  This will also force-load the curses module.
-_terminfo_params = {'none': (True, 'sgr0', ''),
-'standout': (True, 'smso', ''),
-'underline': (True, 'smul', ''),
-'reverse': (True, 'rev', ''),
-'inverse': (True, 'rev', ''),
-'blink': (True, 'blink', ''),
-'dim': (True, 'dim', ''),
-'bold': (True, 'bold', ''),
-'invisible': (True, 'invis', ''),
-'italic': (True, 'sitm', ''),
-'black': (False, curses.COLOR_BLACK, ''),
-'red': (False, curses.COLOR_RED, ''),
-'green': (False, curses.COLOR_GREEN, ''),
-'yellow': (False, curses.COLOR_YELLOW, ''),
-'blue': (False, curses.COLOR_BLUE, ''),
-'magenta': (False, curses.COLOR_MAGENTA, ''),
-'cyan': (False, curses.COLOR_CYAN, ''),
-'white': (False, curses.COLOR_WHITE, '')}
-except ImportError:
-_terminfo_params = {}
-
 def _effect_str(effect):
 '''Helper function for render_effects().'''
 
@@ -323,7 +305,7 @@ def _effect_str(effect):
 bg = True
 

[PATCH stable] make: update .PHONY targets

2017-02-15 Thread Anton Shestakov
# HG changeset patch
# User Anton Shestakov 
# Date 1487141373 -28800
#  Wed Feb 15 14:49:33 2017 +0800
# Branch stable
# Node ID 8e70ce179fc3b418023213ecae804b8825d04331
# Parent  aa25989b0658dcefbd4c1bce7c389f006f22af30
make: update .PHONY targets

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -262,5 +262,9 @@ docker-centos7:
 .PHONY: help all local build doc cleanbutpackages clean install install-bin \
install-doc install-home install-home-bin install-home-doc \
dist dist-notests check tests check-code update-pot \
-   osx fedora20 docker-fedora20 fedora21 docker-fedora21 \
+   osx deb ppa docker-debian-jessie \
+   docker-ubuntu-trusty docker-ubuntu-trusty-ppa \
+   docker-ubuntu-xenial docker-ubuntu-xenial-ppa \
+   docker-ubuntu-yakkety docker-ubuntu-yakkety-ppa \
+   fedora20 docker-fedora20 fedora21 docker-fedora21 \
centos5 docker-centos5 centos6 docker-centos6 centos7 docker-centos7
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 4 RFC] chgcache: implement simple IPC mechanism

2017-02-15 Thread Yuya Nishihara
On Tue, 14 Feb 2017 11:05:00 -0800, Jun Wu wrote:
> Excerpts from Yuya Nishihara's message of 2017-02-14 22:49:34 +0900:
> > On Mon, 13 Feb 2017 09:46:21 -0800, Jun Wu wrote:
> > > Excerpts from Yuya Nishihara's message of 2017-02-13 23:00:25 +0900:
> > > > Why not os.pipe()?
> > > >
> > > > We share the same (dup-ed) file descriptors. In this case, the write 
> > > > end can
> > > > be used by many forked processes, but IIRC the read end can't. Only one
> > > > reader can read out a message. So I think there's no reason to set up a
> > > > full duplex IPC channel.
> > > 
> > > Duplex IRC is not needed. But I do want to use DGRAM.
> > > 
> > > DGRAM makes it impossible to send incomplete messages. I think that makes
> > > the code simpler and maybe more efficient.
> > 
> > Ok.
> > 
> > Perhaps you won't need the suffix as datagram socket is message oriented?
> 
> Right. It's not needed if we can figure out the message length first.

I don't know the datagram unix socket, but if it acts the same as UDP socket,
recv() will read exactly one message. Contiguous messages won't be streamed.

> That could be done via "fcntl.ioctl(fd, termios.FIONREAD, buf)", which won't
> work on Windows. I think that's fine since we have so many non-Windows code
> already.

Sure. chg will never run on Windows.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


RE: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Gábor STEFANIK
> 


--
This message, including its attachments, is confidential. For more information 
please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.


-Original Message-
> From: Martin von Zweigbergk [mailto:martinv...@google.com]
> Sent: Tuesday, February 14, 2017 11:36 PM
> To: Gábor STEFANIK 
> Cc: Mercurial-devel 
> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
> topological branches (issue5125)
> 
> (+mercurial-devel)
> 
> On Tue, Feb 14, 2017 at 10:48 AM, Gábor STEFANIK
>  wrote:
> >>
> >
> >
> > --
> >  This message, including its attachments, is confidential. For
> > more information please read NNG's email policy here:
> > http://www.nng.com/emailpolicy/
> > By responding to this email you accept the email policy.
> >
> >
> > -Original Message-
> >> From: Mercurial-devel
> >> [mailto:mercurial-devel-boun...@mercurial-scm.org]
> >> On Behalf Of Martin von Zweigbergk via Mercurial-devel
> >> Sent: Tuesday, February 14, 2017 2:07 AM
> >> To: mercurial-devel@mercurial-scm.org
> >> Subject: [PATCH 5 of 6] update: learn --merge to allow merging across
> >> topological branches (issue5125)
> >>
> >> # HG changeset patch
> >> # User Martin von Zweigbergk  # Date
> >> 1487019517 28800
> >> #  Mon Feb 13 12:58:37 2017 -0800
> >> # Node ID 75e5a492d7f69420a554fe498ae24060c755b09f
> >> # Parent  59e2d3da607cc09ebe133ab199fc4f343d74e1e6
> >> update: learn --merge to allow merging across topological branches
> >> (issue5125)
> >>
> >> diff -r 59e2d3da607c -r 75e5a492d7f6 mercurial/commands.py
> >> --- a/mercurial/commands.py   Mon Feb 13 15:04:46 2017 -0800
> >> +++ b/mercurial/commands.py   Mon Feb 13 12:58:37 2017 -0800
> >> @@ -6471,12 +6471,13 @@
> >>  @command('^update|up|checkout|co',
> >>  [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
> >>  ('c', 'check', None, _('require clean working directory')),
> >> +('m', 'merge', None, _('merge local changes')),
> >>  ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
> >>  ('r', 'rev', '', _('revision'), _('REV'))
> >>   ] + mergetoolopts,
> >> -_('[-C|-c] [-d DATE] [[-r] REV]'))
> >> +_('[-C|-c|-m] [-d DATE] [[-r] REV]'))
> >>  def update(ui, repo, node=None, rev=None, clean=False, date=None,
> >> check=False,
> >> -   tool=None):
> >> +   merge=None, tool=None):
> >>  """update working directory (or switch revisions)
> >>
> >>  Update the repository's working directory to the specified @@
> >> -6498,7 +6499,7 @@
> >>The following rules apply when the working directory contains
> >>uncommitted changes:
> >>
> >> -  1. If neither -c/--check nor -C/--clean is specified, and if
> >> +  1. If none of -c/--check, -C/--clean, or -m/--merge is
> >> + specified, and if
> >>   the requested changeset is an ancestor or descendant of
> >>   the working directory's parent, the uncommitted changes
> >>   are merged into the requested changeset and the merged @@
> >> -6507,10 +6508,14 @@
> >>   branch), the update is aborted and the uncommitted changes
> >>   are preserved.
> >>
> >> -  2. With the -c/--check option, the update is aborted and the
> >> +  2. With the -m/--merge option, the update is allowed even if the
> >> + requested changeset is not an ancestor or descendant of
> >> + the working directory's parent.
> >> +
> >> +  3. With the -c/--check option, the update is aborted and the
> >>   uncommitted changes are preserved.
> >>
> >> -  3. With the -C/--clean option, uncommitted changes are discarded and
> >> +  4. With the -C/--clean option, uncommitted changes are
> >> + discarded and
> >>   the working directory is updated to the requested changeset.
> >>
> >>  To cancel an uncommitted merge (and lose your changes), use @@
> >> -6535,8 +6540,15 @@
> >>  if date and rev is not None:
> >>  raise error.Abort(_("you can't specify a revision and a
> >> date"))
> >>
> >> -if check and clean:
> >> -raise error.Abort(_("cannot specify both -c/--check and 
> >> -C/--clean"))
> >> +if len([x for x in (check, clean , merge) if x]) > 1:
> >> +raise error.Abort(_("can only specify one of -c/--check, 
> >> -C/--clean, "
> >> +"and -m/merge"))
> >> +
> >> +updatecheck = 'linear'
> >> +if check:
> >> +updatecheck = 'abort'
> >> +elif merge:
> >> +updatecheck = None
> >
> > I don't really like the use of None to indicate "always merge".
> > I would strongly prefer updatecheck = 'merge', with None instead
> > representing a default or "unset" case.
> 
> Makes sense. Since the check that's done is not about merging, I'll call i

RE: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Gábor STEFANIK
> 


--
This message, including its attachments, is confidential. For more information 
please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.


-Original Message-
> From: Martin von Zweigbergk [mailto:martinv...@google.com]
> Sent: Tuesday, February 14, 2017 11:36 PM
> To: Gábor STEFANIK 
> Cc: Mercurial-devel 
> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
> topological branches (issue5125)
> 
> (+mercurial-devel)
> 
> On Tue, Feb 14, 2017 at 10:48 AM, Gábor STEFANIK
>  wrote:
> >>
> >
> >
> > --
> >  This message, including its attachments, is confidential. For
> > more information please read NNG's email policy here:
> > http://www.nng.com/emailpolicy/
> > By responding to this email you accept the email policy.
> >
> >
> > -Original Message-
> >> From: Mercurial-devel
> >> [mailto:mercurial-devel-boun...@mercurial-scm.org]
> >> On Behalf Of Martin von Zweigbergk via Mercurial-devel
> >> Sent: Tuesday, February 14, 2017 2:07 AM
> >> To: mercurial-devel@mercurial-scm.org
> >> Subject: [PATCH 5 of 6] update: learn --merge to allow merging across
> >> topological branches (issue5125)
> >>
> >> # HG changeset patch
> >> # User Martin von Zweigbergk  # Date
> >> 1487019517 28800
> >> #  Mon Feb 13 12:58:37 2017 -0800
> >> # Node ID 75e5a492d7f69420a554fe498ae24060c755b09f
> >> # Parent  59e2d3da607cc09ebe133ab199fc4f343d74e1e6
> >> update: learn --merge to allow merging across topological branches
> >> (issue5125)
> >>
> >> diff -r 59e2d3da607c -r 75e5a492d7f6 mercurial/commands.py
> >> --- a/mercurial/commands.py   Mon Feb 13 15:04:46 2017 -0800
> >> +++ b/mercurial/commands.py   Mon Feb 13 12:58:37 2017 -0800
> >> @@ -6471,12 +6471,13 @@
> >>  @command('^update|up|checkout|co',
> >>  [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
> >>  ('c', 'check', None, _('require clean working directory')),
> >> +('m', 'merge', None, _('merge local changes')),
> >>  ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
> >>  ('r', 'rev', '', _('revision'), _('REV'))
> >>   ] + mergetoolopts,
> >> -_('[-C|-c] [-d DATE] [[-r] REV]'))
> >> +_('[-C|-c|-m] [-d DATE] [[-r] REV]'))
> >>  def update(ui, repo, node=None, rev=None, clean=False, date=None,
> >> check=False,
> >> -   tool=None):
> >> +   merge=None, tool=None):
> >>  """update working directory (or switch revisions)
> >>
> >>  Update the repository's working directory to the specified @@
> >> -6498,7 +6499,7 @@
> >>The following rules apply when the working directory contains
> >>uncommitted changes:
> >>
> >> -  1. If neither -c/--check nor -C/--clean is specified, and if
> >> +  1. If none of -c/--check, -C/--clean, or -m/--merge is
> >> + specified, and if
> >>   the requested changeset is an ancestor or descendant of
> >>   the working directory's parent, the uncommitted changes
> >>   are merged into the requested changeset and the merged @@
> >> -6507,10 +6508,14 @@
> >>   branch), the update is aborted and the uncommitted changes
> >>   are preserved.
> >>
> >> -  2. With the -c/--check option, the update is aborted and the
> >> +  2. With the -m/--merge option, the update is allowed even if the
> >> + requested changeset is not an ancestor or descendant of
> >> + the working directory's parent.
> >> +
> >> +  3. With the -c/--check option, the update is aborted and the
> >>   uncommitted changes are preserved.
> >>
> >> -  3. With the -C/--clean option, uncommitted changes are discarded and
> >> +  4. With the -C/--clean option, uncommitted changes are
> >> + discarded and
> >>   the working directory is updated to the requested changeset.
> >>
> >>  To cancel an uncommitted merge (and lose your changes), use @@
> >> -6535,8 +6540,15 @@
> >>  if date and rev is not None:
> >>  raise error.Abort(_("you can't specify a revision and a
> >> date"))
> >>
> >> -if check and clean:
> >> -raise error.Abort(_("cannot specify both -c/--check and 
> >> -C/--clean"))
> >> +if len([x for x in (check, clean , merge) if x]) > 1:
> >> +raise error.Abort(_("can only specify one of -c/--check, 
> >> -C/--clean, "
> >> +"and -m/merge"))
> >> +
> >> +updatecheck = 'linear'
> >> +if check:
> >> +updatecheck = 'abort'
> >> +elif merge:
> >> +updatecheck = None
> >
> > I don't really like the use of None to indicate "always merge".
> > I would strongly prefer updatecheck = 'merge', with None instead
> > representing a default or "unset" case.
> 
> Makes sense. Since the check that's done is not about merging, I'll call i

Re: [PATCH 4 of 6 V2] update: clarify that -C and -c are mutually exclusive

2017-02-15 Thread Yuya Nishihara
On Tue, 14 Feb 2017 15:08:39 -0800, Martin von Zweigbergk via Mercurial-devel 
wrote:
> # HG changeset patch
> # User Martin von Zweigbergk 
> # Date 1487027086 28800
> #  Mon Feb 13 15:04:46 2017 -0800
> # Node ID f9b2552610a5453bf836d3c7469fbebc59c5ad4b
> # Parent  8a7b145ee159628a0ab5926ef5e4354df3f05ee0
> update: clarify that -C and -c are mutually exclusive

These look good refactoring. Queued up to this, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH stable] make: update .PHONY targets

2017-02-15 Thread Yuya Nishihara
On Wed, 15 Feb 2017 20:14:46 +0800, Anton Shestakov wrote:
> # HG changeset patch
> # User Anton Shestakov 
> # Date 1487141373 -28800
> #  Wed Feb 15 14:49:33 2017 +0800
> # Branch stable
> # Node ID 8e70ce179fc3b418023213ecae804b8825d04331
> # Parent  aa25989b0658dcefbd4c1bce7c389f006f22af30
> make: update .PHONY targets

Sure, queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Yuya Nishihara
On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
> > >> -def updatetotally(ui, repo, checkout, brev, clean=False, check=False):
> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
> > >> +  updatecheck='linear'):
> > >
> > > Please make this updatecheck=None, and set it to 'linear' inside
> > > merge.update() explicitly if None was passed to that function.
> > 
> > Will do.
> > 
> > >
> > > This way, in patch 6, you can red the config option inside
> > > merge.update(), and let other callers (primarily extensions) also
> > automatically follow the config option.
> > 
> > I don't think it's a good idea for the low-level merge.update() to read the
> > config. That function is called e.g. by rebase and graft and they should not
> > have their behavior changed by this config.

I tend to agree with Martin, low-level functions should have less dependency
on config. Instead, maybe we could add a function that builds options from
ui (like patch.diffopts), but I don't know if that's appropriate here.

> I forgot to add, I'm particularly concerned about the "guestrepo" extension,
> which we use extensively at NNG. IIRC in the "grupdate" command, it doesn't
> use commands.update, and so changing the config option causes "update"
> and "grupdate" to behave differently.
> 
> Also, care must be taken about subrepositories. Not sure if our subrepo update
> code calls command.update - if not, we may even end up with a situation
> where "hg update" in a repository with subrepos with ui.updatecheck="merge"
> will do nonlinear updates with a dirty main repo, but not with a dirty 
> subrepo.

IIRC, updating including subrepos isn't a simple cascading operation. Perhaps
users would be asked how to process changes in subrepos?

> In fact, if we introduce a config option, but only use it in 
> commands.update(),
> we should make the lower functions error out or at least warn if called 
> without
> explicit updatecheck, and without other options (e.g. branchmerge) that 
> override
> linearity checks. This way, we at least catch extensions that don't follow the
> config option, but try to rely on merge.update()'s linearity checks.

Good point.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Inconsistent HG_PENDING handling

2017-02-15 Thread FUJIWARA Katsunori
At Mon, 13 Feb 2017 18:19:35 -0500,
Augie Fackler wrote:
> 
> (+foozy, marmoute for transaction musing)
> 
> On Sun, Feb 12, 2017 at 07:06:49PM -0500, timeless wrote:
> > bookmarks.py
> > if 'HG_PENDING' in encoding.environ:
> > try:
> > bkfile = repo.vfs('bookmarks.pending')
> >
> > dirstate.py
> > def _trypending(root, vfs, filename):
> > '''Open  file to be read according to HG_PENDING environment variable
> >
> > This opens '.pending' of specified 'filename' only when HG_PENDING
> > is equal to 'root'.
> >
> > This returns '(fp, is_pending_opened)' tuple.
> > '''
> > if root == encoding.environ.get('HG_PENDING'):
> >
> > localrepo.py
> > if 'HG_PENDING' in encoding.environ:
> > p = encoding.environ['HG_PENDING']
> > if p.startswith(self.root):
> > c.readpending('00changelog.i.a')
> >
> > it /seems/ like the dirstate code is designed so that it shows the
> > dirstate for a given repository based on pending
> > so, if i have a hg hook that deals w/ HG_PENDING
> >
> > and there are 2 hg things triggering pending
> > and thus two repositories running hooks that deal w/ pending
> > and for some reason one of them runs an hg command in the other repository
> > that second repository will afaict not report the pending dirstate,
> > since it checks carefully
> > but will report the pending bookmark, since afaict it checks carelessly
> >
> > the same incorrect behavior appears to be present for phases too
> >
> > but that should mean a nested repo could see a pending something
> >
> > if i have a repo w/ a registered subrepo, and someone does a "push" to
> > my repo, is the subrepo directory modified as part of the step leading
> > to my push-pretxn hook?
> 
> This looks correct to me - there's one easy-to-fix bug in bookmarks,
> and one hard-to-fix bug related to nested repositories. Can I at least
> get you to draft a change for bookmarks to make it more sound?
> 
> Thanks!

I understand:

  - a transaction covers only one repository

  - an external hook with HG_PENDING can't see any pending changes in
other repositories, even if they are outer ones of subrepo nesting

IMHO, making HG_PENDING check in bookmarks.py, phases.py, and
localrepo.py strict is enough.


BTW, I have pending patches to make HG_PENDING check strict by
centralizing "read file in according to HG_PENDING" logic (as a part
of followup for DirstateTransactionPlan), in fact. I'll post them,
soon :-)


> > ___
> > Mercurial-devel mailing list
> > Mercurial-devel@mercurial-scm.org
> > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
> 

-- 
--
[FUJIWARA Katsunori] fo...@lares.dti.ne.jp
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@30959: 18 new changesets

2017-02-15 Thread Mercurial Commits
18 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/65a3b4d67a65
changeset:   30942:65a3b4d67a65
user:Augie Fackler 
date:Mon Feb 06 21:15:35 2017 -0500
summary: pager: add a test of --pager=no functionality

https://www.mercurial-scm.org/repo/hg/rev/a0e4df5a4d5d
changeset:   30943:a0e4df5a4d5d
user:Augie Fackler 
date:Tue Feb 07 17:08:41 2017 -0500
summary: tests: update test-i18n.t to not depend on the pager extension

https://www.mercurial-scm.org/repo/hg/rev/b7e073ae44c4
changeset:   30944:b7e073ae44c4
user:Augie Fackler 
date:Mon Feb 06 23:57:32 2017 -0500
summary: tests: switch "this command isn't paged" example to id

https://www.mercurial-scm.org/repo/hg/rev/8b83b626fb1e
changeset:   30945:8b83b626fb1e
user:Kyle Lippincott 
date:Sun Feb 12 03:06:38 2017 -0800
summary: ui: remove urllib2 from being imported early

https://www.mercurial-scm.org/repo/hg/rev/7103122495e2
changeset:   30946:7103122495e2
user:Pierre-Yves David 
date:Wed Feb 01 17:48:30 2017 +0100
summary: debugcommands: move 'debugpushkey' in the new module

https://www.mercurial-scm.org/repo/hg/rev/3c766ca89377
changeset:   30947:3c766ca89377
user:Pierre-Yves David 
date:Thu Feb 02 09:59:47 2017 +0100
summary: debugcommands: move 'debugpvec' in the new module

https://www.mercurial-scm.org/repo/hg/rev/cc2b537b1966
changeset:   30948:cc2b537b1966
user:Pierre-Yves David 
date:Thu Feb 02 10:00:26 2017 +0100
summary: debugcommands: move 'debugrebuilddirstate' in the new module

https://www.mercurial-scm.org/repo/hg/rev/e7d7335819f4
changeset:   30949:e7d7335819f4
user:Pierre-Yves David 
date:Thu Feb 02 10:01:00 2017 +0100
summary: debugcommands: move 'debugrebuildfncache' in the new module

https://www.mercurial-scm.org/repo/hg/rev/7236f949ce3f
changeset:   30950:7236f949ce3f
user:Pierre-Yves David 
date:Thu Feb 02 10:01:54 2017 +0100
summary: debugcommands: move 'debugrename' in the new module

https://www.mercurial-scm.org/repo/hg/rev/f44b96aef81b
changeset:   30951:f44b96aef81b
user:Pierre-Yves David 
date:Thu Feb 02 10:02:40 2017 +0100
summary: debugcommands: move 'debugrevlog' in the new module

https://www.mercurial-scm.org/repo/hg/rev/85c3c879c43a
changeset:   30952:85c3c879c43a
user:Pierre-Yves David 
date:Thu Feb 02 10:03:31 2017 +0100
summary: debugcommands: move 'debugrevspec' in the new module

https://www.mercurial-scm.org/repo/hg/rev/5b09e9bc0902
changeset:   30953:5b09e9bc0902
user:Pierre-Yves David 
date:Thu Feb 02 10:04:02 2017 +0100
summary: debugcommands: move 'debugsetparents' in the new module

https://www.mercurial-scm.org/repo/hg/rev/dad968920130
changeset:   30954:dad968920130
user:Pierre-Yves David 
date:Thu Feb 02 10:04:34 2017 +0100
summary: debugcommands: move 'debugstate' in the new module

https://www.mercurial-scm.org/repo/hg/rev/8e38fa360a12
changeset:   30955:8e38fa360a12
user:Pierre-Yves David 
date:Thu Feb 02 10:04:55 2017 +0100
summary: debugcommands: move 'debugsub' in the new module

https://www.mercurial-scm.org/repo/hg/rev/db30c6bfeb70
changeset:   30956:db30c6bfeb70
user:Pierre-Yves David 
date:Thu Feb 02 10:05:22 2017 +0100
summary: debugcommands: move 'debugsuccessorssets' in the new module

https://www.mercurial-scm.org/repo/hg/rev/14794735faa8
changeset:   30957:14794735faa8
user:Pierre-Yves David 
date:Thu Feb 02 10:06:01 2017 +0100
summary: debugcommands: move 'debugtemplate' in the new module

https://www.mercurial-scm.org/repo/hg/rev/df73368c87c3
changeset:   30958:df73368c87c3
user:Pierre-Yves David 
date:Thu Feb 02 10:07:28 2017 +0100
summary: debugcommands: move 'debugwalk' in the new module

https://www.mercurial-scm.org/repo/hg/rev/bd5694ce8beb
changeset:   30959:bd5694ce8beb
bookmark:@
tag: tip
user:Pierre-Yves David 
date:Thu Feb 02 10:07:53 2017 +0100
summary: debugcommands: move 'debugwireargs' in the new module

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Inconsistent HG_PENDING handling

2017-02-15 Thread FUJIWARA Katsunori
At Thu, 16 Feb 2017 00:01:05 +0900,
FUJIWARA Katsunori wrote:
> 
> At Mon, 13 Feb 2017 18:19:35 -0500,
> Augie Fackler wrote:
> > 
> > (+foozy, marmoute for transaction musing)
> > 
> > On Sun, Feb 12, 2017 at 07:06:49PM -0500, timeless wrote:
> > > bookmarks.py
> > > if 'HG_PENDING' in encoding.environ:
> > > try:
> > > bkfile = repo.vfs('bookmarks.pending')
> > >
> > > dirstate.py
> > > def _trypending(root, vfs, filename):
> > > '''Open  file to be read according to HG_PENDING environment variable
> > >
> > > This opens '.pending' of specified 'filename' only when HG_PENDING
> > > is equal to 'root'.
> > >
> > > This returns '(fp, is_pending_opened)' tuple.
> > > '''
> > > if root == encoding.environ.get('HG_PENDING'):
> > >
> > > localrepo.py
> > > if 'HG_PENDING' in encoding.environ:
> > > p = encoding.environ['HG_PENDING']
> > > if p.startswith(self.root):
> > > c.readpending('00changelog.i.a')
> > >
> > > it /seems/ like the dirstate code is designed so that it shows the
> > > dirstate for a given repository based on pending
> > > so, if i have a hg hook that deals w/ HG_PENDING
> > >
> > > and there are 2 hg things triggering pending
> > > and thus two repositories running hooks that deal w/ pending
> > > and for some reason one of them runs an hg command in the other repository
> > > that second repository will afaict not report the pending dirstate,
> > > since it checks carefully
> > > but will report the pending bookmark, since afaict it checks carelessly
> > >
> > > the same incorrect behavior appears to be present for phases too
> > >
> > > but that should mean a nested repo could see a pending something
> > >
> > > if i have a repo w/ a registered subrepo, and someone does a "push" to
> > > my repo, is the subrepo directory modified as part of the step leading
> > > to my push-pretxn hook?
> > 
> > This looks correct to me - there's one easy-to-fix bug in bookmarks,
> > and one hard-to-fix bug related to nested repositories. Can I at least
> > get you to draft a change for bookmarks to make it more sound?
> > 
> > Thanks!
> 
> I understand:
> 
>   - a transaction covers only one repository
> 
>   - an external hook with HG_PENDING can't see any pending changes in
> other repositories, even if they are outer ones of subrepo nesting
> 
> IMHO, making HG_PENDING check in bookmarks.py, phases.py, and
> localrepo.py strict is enough.

Oops, I overlooked the case that transactions across repositories (!=
structural nesting) hide pending changes of outer transaction, because
current implementation holds only one repository root in HG_PENDING.

How about steps below to fix issues ?

  1. centralize the logic to strictly read pending file according to
 HG_PENDING

 at this point, only simple "dirty read" issue is fixed.

  2. make the logic above aware of transactions across repositories

 maybe, putting concatenated repo roots into HG_PENDING ?


> BTW, I have pending patches to make HG_PENDING check strict by
> centralizing "read file in according to HG_PENDING" logic (as a part
> of followup for DirstateTransactionPlan), in fact. I'll post them,
> soon :-)
> 
> 
> > > ___
> > > Mercurial-devel mailing list
> > > Mercurial-devel@mercurial-scm.org
> > > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
> > 
> 
> -- 
> --
> [FUJIWARA Katsunori] fo...@lares.dti.ne.jp
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

-- 
--
[FUJIWARA Katsunori] fo...@lares.dti.ne.jp
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@30964: 5 new changesets

2017-02-15 Thread Mercurial Commits
5 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/e4492d55fb66
changeset:   30960:e4492d55fb66
user:Anton Shestakov 
date:Wed Feb 15 14:49:33 2017 +0800
summary: make: update .PHONY targets

https://www.mercurial-scm.org/repo/hg/rev/330fbd515512
changeset:   30961:330fbd515512
user:Martin von Zweigbergk 
date:Thu Feb 09 09:52:32 2017 -0800
summary: destutil: remove duplicate check and leave it to merge.update()

https://www.mercurial-scm.org/repo/hg/rev/11c253997b0e
changeset:   30962:11c253997b0e
user:Martin von Zweigbergk 
date:Mon Feb 13 11:32:09 2017 -0800
summary: destutil: drop now-unused "check" parameter from destupdate()

https://www.mercurial-scm.org/repo/hg/rev/7beb3ec34443
changeset:   30963:7beb3ec34443
user:Martin von Zweigbergk 
date:Mon Feb 13 11:58:02 2017 -0800
summary: update: move check for dirty wdir into hg.updatetotally()

https://www.mercurial-scm.org/repo/hg/rev/afaf3c2b129c
changeset:   30964:afaf3c2b129c
bookmark:@
tag: tip
user:Martin von Zweigbergk 
date:Mon Feb 13 15:04:46 2017 -0800
summary: update: clarify that -C and -c are mutually exclusive

-- 
Repository URL: https://www.mercurial-scm.org/repo/hg
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Inconsistent HG_PENDING handling

2017-02-15 Thread FUJIWARA Katsunori
At Thu, 16 Feb 2017 00:51:11 +0900,
FUJIWARA Katsunori wrote:
> 
> At Thu, 16 Feb 2017 00:01:05 +0900,
> FUJIWARA Katsunori wrote:
> > 
> > At Mon, 13 Feb 2017 18:19:35 -0500,
> > Augie Fackler wrote:
> > > 
> > > (+foozy, marmoute for transaction musing)
> > > 
> > > On Sun, Feb 12, 2017 at 07:06:49PM -0500, timeless wrote:
> > > > bookmarks.py
> > > > if 'HG_PENDING' in encoding.environ:
> > > > try:
> > > > bkfile = repo.vfs('bookmarks.pending')
> > > >
> > > > dirstate.py
> > > > def _trypending(root, vfs, filename):
> > > > '''Open  file to be read according to HG_PENDING environment 
> > > > variable
> > > >
> > > > This opens '.pending' of specified 'filename' only when HG_PENDING
> > > > is equal to 'root'.
> > > >
> > > > This returns '(fp, is_pending_opened)' tuple.
> > > > '''
> > > > if root == encoding.environ.get('HG_PENDING'):
> > > >
> > > > localrepo.py
> > > > if 'HG_PENDING' in encoding.environ:
> > > > p = encoding.environ['HG_PENDING']
> > > > if p.startswith(self.root):
> > > > c.readpending('00changelog.i.a')
> > > >
> > > > it /seems/ like the dirstate code is designed so that it shows the
> > > > dirstate for a given repository based on pending
> > > > so, if i have a hg hook that deals w/ HG_PENDING
> > > >
> > > > and there are 2 hg things triggering pending
> > > > and thus two repositories running hooks that deal w/ pending
> > > > and for some reason one of them runs an hg command in the other 
> > > > repository
> > > > that second repository will afaict not report the pending dirstate,
> > > > since it checks carefully
> > > > but will report the pending bookmark, since afaict it checks carelessly
> > > >
> > > > the same incorrect behavior appears to be present for phases too
> > > >
> > > > but that should mean a nested repo could see a pending something
> > > >
> > > > if i have a repo w/ a registered subrepo, and someone does a "push" to
> > > > my repo, is the subrepo directory modified as part of the step leading
> > > > to my push-pretxn hook?
> > > 
> > > This looks correct to me - there's one easy-to-fix bug in bookmarks,
> > > and one hard-to-fix bug related to nested repositories. Can I at least
> > > get you to draft a change for bookmarks to make it more sound?
> > > 
> > > Thanks!
> > 
> > I understand:
> > 
> >   - a transaction covers only one repository
> > 
> >   - an external hook with HG_PENDING can't see any pending changes in
> > other repositories, even if they are outer ones of subrepo nesting
> > 
> > IMHO, making HG_PENDING check in bookmarks.py, phases.py, and
> > localrepo.py strict is enough.
> 
> Oops, I overlooked the case that transactions across repositories (!=
> structural nesting) hide pending changes of outer transaction, because
> current implementation holds only one repository root in HG_PENDING.
> 
> How about steps below to fix issues ?
> 
>   1. centralize the logic to strictly read pending file according to
>  HG_PENDING
> 
>  at this point, only simple "dirty read" issue is fixed.
> 
>   2. make the logic above aware of transactions across repositories
> 
>  maybe, putting concatenated repo roots into HG_PENDING ?

Let me summarize current implementation and issues.

Mercurial supports transaction nesting below:

  == == ==
  nested in  single process multiple processes
  == == ==
  single repo o (*1) x
  multiple repos  o (*2) (*3)o (*2) (*4)
  == == ==

  (*1) treated as single transaction

  (*2) treated as individual transactions
   (= aborting outer one doesn't rollback already committed inner one)

  (*3) invocation of external hook (via hook.runhooks() API) is bound
   to one of repositories, and pending changes of others are
   invisible to external hook

   (should we fix this invisibility ?)

  (*4) current HG_PENDING handling causes:

   - "dirty read" in unrelated (but transaction running) repositories:
 bookmarks, changelog (of localrepo), phases

   - "invisible pending changes" in repositories of outer transactions:
 changelog (of localrepo), dirstate


> > BTW, I have pending patches to make HG_PENDING check strict by
> > centralizing "read file in according to HG_PENDING" logic (as a part
> > of followup for DirstateTransactionPlan), in fact. I'll post them,
> > soon :-)
> > 
> > 
> > > > ___
> > > > Mercurial-devel mailing list
> > > > Mercurial-devel@mercurial-scm.org
> > > > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
> > > 
> > 
> > -- 
> > --
> > [FUJIWARA Katsunori] fo...@lares.dti.ne.jp
> > ___
> > Mercurial-devel mailing

Re: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
> On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
>> > >> -def updatetotally(ui, repo, checkout, brev, clean=False, check=False):
>> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
>> > >> +  updatecheck='linear'):
>> > >
>> > > Please make this updatecheck=None, and set it to 'linear' inside
>> > > merge.update() explicitly if None was passed to that function.
>> >
>> > Will do.
>> >
>> > >
>> > > This way, in patch 6, you can red the config option inside
>> > > merge.update(), and let other callers (primarily extensions) also
>> > automatically follow the config option.
>> >
>> > I don't think it's a good idea for the low-level merge.update() to read the
>> > config. That function is called e.g. by rebase and graft and they should 
>> > not
>> > have their behavior changed by this config.
>
> I tend to agree with Martin, low-level functions should have less dependency
> on config. Instead, maybe we could add a function that builds options from
> ui (like patch.diffopts), but I don't know if that's appropriate here.
>
>> I forgot to add, I'm particularly concerned about the "guestrepo" extension,
>> which we use extensively at NNG. IIRC in the "grupdate" command, it doesn't
>> use commands.update, and so changing the config option causes "update"
>> and "grupdate" to behave differently.
>>
>> Also, care must be taken about subrepositories. Not sure if our subrepo 
>> update
>> code calls command.update - if not, we may even end up with a situation
>> where "hg update" in a repository with subrepos with ui.updatecheck="merge"
>> will do nonlinear updates with a dirty main repo, but not with a dirty 
>> subrepo.
>
> IIRC, updating including subrepos isn't a simple cascading operation. Perhaps
> users would be asked how to process changes in subrepos?
>
>> In fact, if we introduce a config option, but only use it in 
>> commands.update(),
>> we should make the lower functions error out or at least warn if called 
>> without
>> explicit updatecheck, and without other options (e.g. branchmerge) that 
>> override
>> linearity checks. This way, we at least catch extensions that don't follow 
>> the
>> config option, but try to rely on merge.update()'s linearity checks.
>
> Good point.

Yeah, I agree with that last point. I tried it and there are several
places that fail. For example, clone, rebase, and mq all call
hg.update[repo](). AFAICT, there should never be any changes where
it's being called, so maybe that should be setting force=True to
overwrite. Or maybe we should teach merge.update() to accept
updatecheck='abort' and make these callers pass that value.
Regardless, since what I'm adding is an experimental config, I'd
prefer to make merge.update() default to 'linear' for now and I'll add
a TODO to add the check you mention. I don't have time right now to
clean up all the other callers, and I'd still like to be able to make
progress on this topic.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


RE: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Gábor STEFANIK
> 


--
This message, including its attachments, is confidential. For more information 
please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.


-Original Message-
> From: Martin von Zweigbergk [mailto:martinv...@google.com]
> Sent: Wednesday, February 15, 2017 7:26 PM
> To: Yuya Nishihara 
> Cc: Gábor STEFANIK ; Mercurial-devel
> 
> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
> topological branches (issue5125)
> 
> On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
> > On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
> >> > >> -def updatetotally(ui, repo, checkout, brev, clean=False,
> check=False):
> >> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
> >> > >> +  updatecheck='linear'):
> >> > >
> >> > > Please make this updatecheck=None, and set it to 'linear' inside
> >> > > merge.update() explicitly if None was passed to that function.
> >> >
> >> > Will do.
> >> >
> >> > >
> >> > > This way, in patch 6, you can red the config option inside
> >> > > merge.update(), and let other callers (primarily extensions) also
> >> > automatically follow the config option.
> >> >
> >> > I don't think it's a good idea for the low-level merge.update() to
> >> > read the config. That function is called e.g. by rebase and graft
> >> > and they should not have their behavior changed by this config.
> >
> > I tend to agree with Martin, low-level functions should have less
> > dependency on config. Instead, maybe we could add a function that
> > builds options from ui (like patch.diffopts), but I don't know if that's
> appropriate here.
> >
> >> I forgot to add, I'm particularly concerned about the "guestrepo"
> >> extension, which we use extensively at NNG. IIRC in the "grupdate"
> >> command, it doesn't use commands.update, and so changing the config
> option causes "update"
> >> and "grupdate" to behave differently.
> >>
> >> Also, care must be taken about subrepositories. Not sure if our
> >> subrepo update code calls command.update - if not, we may even end up
> >> with a situation where "hg update" in a repository with subrepos with
> ui.updatecheck="merge"
> >> will do nonlinear updates with a dirty main repo, but not with a dirty
> subrepo.
> >
> > IIRC, updating including subrepos isn't a simple cascading operation.
> > Perhaps users would be asked how to process changes in subrepos?
> >
> >> In fact, if we introduce a config option, but only use it in
> >> commands.update(), we should make the lower functions error out or at
> >> least warn if called without explicit updatecheck, and without other
> >> options (e.g. branchmerge) that override linearity checks. This way,
> >> we at least catch extensions that don't follow the config option, but try 
> >> to
> rely on merge.update()'s linearity checks.
> >
> > Good point.
> 
> Yeah, I agree with that last point. I tried it and there are several places 
> that
> fail. For example, clone, rebase, and mq all call hg.update[repo](). AFAICT,
> there should never be any changes where it's being called, so maybe that
> should be setting force=True to overwrite. Or maybe we should teach
> merge.update() to accept updatecheck='abort' and make these callers pass
> that value.
> Regardless, since what I'm adding is an experimental config, I'd prefer to
> make merge.update() default to 'linear' for now and I'll add a TODO to add
> the check you mention. I don't have time right now to clean up all the other
> callers, and I'd still like to be able to make progress on this topic.

These other callers IIRC call with options that  already disable linearity 
checks.

We should only fail if we are in a normal update scenario with linearity checks
enabled, but no check strategy was provided.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 10:35 AM, Gábor STEFANIK  wrote:
>>
>
>
> --
> This message, including its attachments, is confidential. For more 
> information please read NNG's email policy here:
> http://www.nng.com/emailpolicy/
> By responding to this email you accept the email policy.
>
>
> -Original Message-
>> From: Martin von Zweigbergk [mailto:martinv...@google.com]
>> Sent: Wednesday, February 15, 2017 7:26 PM
>> To: Yuya Nishihara 
>> Cc: Gábor STEFANIK ; Mercurial-devel
>> 
>> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
>> topological branches (issue5125)
>>
>> On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
>> > On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
>> >> > >> -def updatetotally(ui, repo, checkout, brev, clean=False,
>> check=False):
>> >> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
>> >> > >> +  updatecheck='linear'):
>> >> > >
>> >> > > Please make this updatecheck=None, and set it to 'linear' inside
>> >> > > merge.update() explicitly if None was passed to that function.
>> >> >
>> >> > Will do.
>> >> >
>> >> > >
>> >> > > This way, in patch 6, you can red the config option inside
>> >> > > merge.update(), and let other callers (primarily extensions) also
>> >> > automatically follow the config option.
>> >> >
>> >> > I don't think it's a good idea for the low-level merge.update() to
>> >> > read the config. That function is called e.g. by rebase and graft
>> >> > and they should not have their behavior changed by this config.
>> >
>> > I tend to agree with Martin, low-level functions should have less
>> > dependency on config. Instead, maybe we could add a function that
>> > builds options from ui (like patch.diffopts), but I don't know if that's
>> appropriate here.
>> >
>> >> I forgot to add, I'm particularly concerned about the "guestrepo"
>> >> extension, which we use extensively at NNG. IIRC in the "grupdate"
>> >> command, it doesn't use commands.update, and so changing the config
>> option causes "update"
>> >> and "grupdate" to behave differently.
>> >>
>> >> Also, care must be taken about subrepositories. Not sure if our
>> >> subrepo update code calls command.update - if not, we may even end up
>> >> with a situation where "hg update" in a repository with subrepos with
>> ui.updatecheck="merge"
>> >> will do nonlinear updates with a dirty main repo, but not with a dirty
>> subrepo.
>> >
>> > IIRC, updating including subrepos isn't a simple cascading operation.
>> > Perhaps users would be asked how to process changes in subrepos?
>> >
>> >> In fact, if we introduce a config option, but only use it in
>> >> commands.update(), we should make the lower functions error out or at
>> >> least warn if called without explicit updatecheck, and without other
>> >> options (e.g. branchmerge) that override linearity checks. This way,
>> >> we at least catch extensions that don't follow the config option, but try 
>> >> to
>> rely on merge.update()'s linearity checks.
>> >
>> > Good point.
>>
>> Yeah, I agree with that last point. I tried it and there are several places 
>> that
>> fail. For example, clone, rebase, and mq all call hg.update[repo](). AFAICT,
>> there should never be any changes where it's being called, so maybe that
>> should be setting force=True to overwrite. Or maybe we should teach
>> merge.update() to accept updatecheck='abort' and make these callers pass
>> that value.
>> Regardless, since what I'm adding is an experimental config, I'd prefer to
>> make merge.update() default to 'linear' for now and I'll add a TODO to add
>> the check you mention. I don't have time right now to clean up all the other
>> callers, and I'd still like to be able to make progress on this topic.
>
> These other callers IIRC call with options that  already disable linearity 
> checks.
>
> We should only fail if we are in a normal update scenario with linearity 
> checks
> enabled, but no check strategy was provided.

The ones I mention do not disable linearity checks (not in all the
places anyway). Here are some examples:

https://www.mercurial-scm.org/repo/hg/file/tip/mercurial/hg.py#l667
https://www.mercurial-scm.org/repo/hg/file/tip/hgext/rebase.py#l485
https://www.mercurial-scm.org/repo/hg/file/tip/hgext/mq.py#l1423
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 10:40 AM, Martin von Zweigbergk
 wrote:
> On Wed, Feb 15, 2017 at 10:35 AM, Gábor STEFANIK  
> wrote:
>>>
>>
>>
>> --
>> This message, including its attachments, is confidential. For more 
>> information please read NNG's email policy here:
>> http://www.nng.com/emailpolicy/
>> By responding to this email you accept the email policy.
>>
>>
>> -Original Message-
>>> From: Martin von Zweigbergk [mailto:martinv...@google.com]
>>> Sent: Wednesday, February 15, 2017 7:26 PM
>>> To: Yuya Nishihara 
>>> Cc: Gábor STEFANIK ; Mercurial-devel
>>> 
>>> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
>>> topological branches (issue5125)
>>>
>>> On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
>>> > On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
>>> >> > >> -def updatetotally(ui, repo, checkout, brev, clean=False,
>>> check=False):
>>> >> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
>>> >> > >> +  updatecheck='linear'):
>>> >> > >
>>> >> > > Please make this updatecheck=None, and set it to 'linear' inside
>>> >> > > merge.update() explicitly if None was passed to that function.
>>> >> >
>>> >> > Will do.
>>> >> >
>>> >> > >
>>> >> > > This way, in patch 6, you can red the config option inside
>>> >> > > merge.update(), and let other callers (primarily extensions) also
>>> >> > automatically follow the config option.
>>> >> >
>>> >> > I don't think it's a good idea for the low-level merge.update() to
>>> >> > read the config. That function is called e.g. by rebase and graft
>>> >> > and they should not have their behavior changed by this config.
>>> >
>>> > I tend to agree with Martin, low-level functions should have less
>>> > dependency on config. Instead, maybe we could add a function that
>>> > builds options from ui (like patch.diffopts), but I don't know if that's
>>> appropriate here.
>>> >
>>> >> I forgot to add, I'm particularly concerned about the "guestrepo"
>>> >> extension, which we use extensively at NNG. IIRC in the "grupdate"
>>> >> command, it doesn't use commands.update, and so changing the config
>>> option causes "update"
>>> >> and "grupdate" to behave differently.
>>> >>
>>> >> Also, care must be taken about subrepositories. Not sure if our
>>> >> subrepo update code calls command.update - if not, we may even end up
>>> >> with a situation where "hg update" in a repository with subrepos with
>>> ui.updatecheck="merge"
>>> >> will do nonlinear updates with a dirty main repo, but not with a dirty
>>> subrepo.
>>> >
>>> > IIRC, updating including subrepos isn't a simple cascading operation.
>>> > Perhaps users would be asked how to process changes in subrepos?
>>> >
>>> >> In fact, if we introduce a config option, but only use it in
>>> >> commands.update(), we should make the lower functions error out or at
>>> >> least warn if called without explicit updatecheck, and without other
>>> >> options (e.g. branchmerge) that override linearity checks. This way,
>>> >> we at least catch extensions that don't follow the config option, but 
>>> >> try to
>>> rely on merge.update()'s linearity checks.
>>> >
>>> > Good point.
>>>
>>> Yeah, I agree with that last point. I tried it and there are several places 
>>> that
>>> fail. For example, clone, rebase, and mq all call hg.update[repo](). AFAICT,
>>> there should never be any changes where it's being called, so maybe that
>>> should be setting force=True to overwrite. Or maybe we should teach
>>> merge.update() to accept updatecheck='abort' and make these callers pass
>>> that value.
>>> Regardless, since what I'm adding is an experimental config, I'd prefer to
>>> make merge.update() default to 'linear' for now and I'll add a TODO to add
>>> the check you mention. I don't have time right now to clean up all the other
>>> callers, and I'd still like to be able to make progress on this topic.
>>
>> These other callers IIRC call with options that  already disable linearity 
>> checks.
>>
>> We should only fail if we are in a normal update scenario with linearity 
>> checks
>> enabled, but no check strategy was provided.
>
> The ones I mention do not disable linearity checks (not in all the
> places anyway). Here are some examples:
>
> https://www.mercurial-scm.org/repo/hg/file/tip/mercurial/hg.py#l667
> https://www.mercurial-scm.org/repo/hg/file/tip/hgext/rebase.py#l485
> https://www.mercurial-scm.org/repo/hg/file/tip/hgext/mq.py#l1423

And the reason they don't is probably that they have a reason to
assume that the working directory is clean (e.g. a fresh clone should
normally be clean).
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Chrome tracing

2017-02-15 Thread Bryan O'Sullivan
On Tue, Feb 14, 2017 at 7:02 PM, Gregory Szorc 
wrote:

>
> I support having dedicated code for annotating well-defined and important
> Mercurial operations in tracing/profiling logs. I have a hunch that the
> kinds of things we need to annotate shouldn't be called with a high enough
> frequency for probe overhead to matter.
>

Right.


> But if it does, the use of context managers can be beneficial, as those
> are evaluated at module load time and the context manager can be made to
> no-op and return the original function unless tracing is enabled. That's
> *almost* 0 cost.
>

That's exactly what the implementation does :-)


> Something else to consider is the interaction between tracing and progress
> bars. I posit that most places we use progress bars are places we'd want to
> use the proposed tracing.duration() context manager. I reckon we could
> integrate tracing into the progress APIs and kill 2 birds with 1 stone.
>

That's again almost exactly what the implementation does, but it uses the
Chrome trace feature of tracking a numeric quantity instead. It's like you
read my mind ... or the patches!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


RE: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Gábor STEFANIK
> 


--
This message, including its attachments, is confidential. For more information 
please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.


-Original Message-
> From: Martin von Zweigbergk [mailto:martinv...@google.com]
> Sent: Wednesday, February 15, 2017 7:41 PM
> To: Gábor STEFANIK 
> Cc: Yuya Nishihara ; Mercurial-devel  de...@mercurial-scm.org>
> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
> topological branches (issue5125)
> 
> On Wed, Feb 15, 2017 at 10:35 AM, Gábor STEFANIK
>  wrote:
> >>
> >
> >
> > --
> >  This message, including its attachments, is confidential. For
> > more information please read NNG's email policy here:
> > http://www.nng.com/emailpolicy/
> > By responding to this email you accept the email policy.
> >
> >
> > -Original Message-
> >> From: Martin von Zweigbergk [mailto:martinv...@google.com]
> >> Sent: Wednesday, February 15, 2017 7:26 PM
> >> To: Yuya Nishihara 
> >> Cc: Gábor STEFANIK ; Mercurial-devel
> >> 
> >> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging
> >> across topological branches (issue5125)
> >>
> >> On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
> >> > On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
> >> >> > >> -def updatetotally(ui, repo, checkout, brev, clean=False,
> >> check=False):
> >> >> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
> >> >> > >> +  updatecheck='linear'):
> >> >> > >
> >> >> > > Please make this updatecheck=None, and set it to 'linear'
> >> >> > > inside
> >> >> > > merge.update() explicitly if None was passed to that function.
> >> >> >
> >> >> > Will do.
> >> >> >
> >> >> > >
> >> >> > > This way, in patch 6, you can red the config option inside
> >> >> > > merge.update(), and let other callers (primarily extensions)
> >> >> > > also
> >> >> > automatically follow the config option.
> >> >> >
> >> >> > I don't think it's a good idea for the low-level merge.update()
> >> >> > to read the config. That function is called e.g. by rebase and
> >> >> > graft and they should not have their behavior changed by this config.
> >> >
> >> > I tend to agree with Martin, low-level functions should have less
> >> > dependency on config. Instead, maybe we could add a function that
> >> > builds options from ui (like patch.diffopts), but I don't know if
> >> > that's
> >> appropriate here.
> >> >
> >> >> I forgot to add, I'm particularly concerned about the "guestrepo"
> >> >> extension, which we use extensively at NNG. IIRC in the "grupdate"
> >> >> command, it doesn't use commands.update, and so changing the
> >> >> config
> >> option causes "update"
> >> >> and "grupdate" to behave differently.
> >> >>
> >> >> Also, care must be taken about subrepositories. Not sure if our
> >> >> subrepo update code calls command.update - if not, we may even end
> >> >> up with a situation where "hg update" in a repository with
> >> >> subrepos with
> >> ui.updatecheck="merge"
> >> >> will do nonlinear updates with a dirty main repo, but not with a
> >> >> dirty
> >> subrepo.
> >> >
> >> > IIRC, updating including subrepos isn't a simple cascading operation.
> >> > Perhaps users would be asked how to process changes in subrepos?
> >> >
> >> >> In fact, if we introduce a config option, but only use it in
> >> >> commands.update(), we should make the lower functions error out or
> >> >> at least warn if called without explicit updatecheck, and without
> >> >> other options (e.g. branchmerge) that override linearity checks.
> >> >> This way, we at least catch extensions that don't follow the
> >> >> config option, but try to
> >> rely on merge.update()'s linearity checks.
> >> >
> >> > Good point.
> >>
> >> Yeah, I agree with that last point. I tried it and there are several
> >> places that fail. For example, clone, rebase, and mq all call
> >> hg.update[repo](). AFAICT, there should never be any changes where
> >> it's being called, so maybe that should be setting force=True to
> >> overwrite. Or maybe we should teach
> >> merge.update() to accept updatecheck='abort' and make these callers
> >> pass that value.
> >> Regardless, since what I'm adding is an experimental config, I'd
> >> prefer to make merge.update() default to 'linear' for now and I'll
> >> add a TODO to add the check you mention. I don't have time right now
> >> to clean up all the other callers, and I'd still like to be able to make
> progress on this topic.
> >
> > These other callers IIRC call with options that  already disable linearity
> checks.
> >
> > We should only fail if we are in a normal update scenario with
> > linearity checks enabled, but no check strategy was provided.
> 
> The ones I mention do not disable linearity checks (not in all the places
> an

Re: [PATCH 5 of 6] update: learn --merge to allow merging across topological branches (issue5125)

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 11:00 AM, Gábor STEFANIK  wrote:
>>
>
>
> --
> This message, including its attachments, is confidential. For more 
> information please read NNG's email policy here:
> http://www.nng.com/emailpolicy/
> By responding to this email you accept the email policy.
>
>
> -Original Message-
>> From: Martin von Zweigbergk [mailto:martinv...@google.com]
>> Sent: Wednesday, February 15, 2017 7:41 PM
>> To: Gábor STEFANIK 
>> Cc: Yuya Nishihara ; Mercurial-devel > de...@mercurial-scm.org>
>> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging across
>> topological branches (issue5125)
>>
>> On Wed, Feb 15, 2017 at 10:35 AM, Gábor STEFANIK
>>  wrote:
>> >>
>> >
>> >
>> > --
>> >  This message, including its attachments, is confidential. For
>> > more information please read NNG's email policy here:
>> > http://www.nng.com/emailpolicy/
>> > By responding to this email you accept the email policy.
>> >
>> >
>> > -Original Message-
>> >> From: Martin von Zweigbergk [mailto:martinv...@google.com]
>> >> Sent: Wednesday, February 15, 2017 7:26 PM
>> >> To: Yuya Nishihara 
>> >> Cc: Gábor STEFANIK ; Mercurial-devel
>> >> 
>> >> Subject: Re: [PATCH 5 of 6] update: learn --merge to allow merging
>> >> across topological branches (issue5125)
>> >>
>> >> On Wed, Feb 15, 2017 at 6:22 AM, Yuya Nishihara  wrote:
>> >> > On Wed, 15 Feb 2017 13:29:30 +, Gábor STEFANIK wrote:
>> >> >> > >> -def updatetotally(ui, repo, checkout, brev, clean=False,
>> >> check=False):
>> >> >> > >> +def updatetotally(ui, repo, checkout, brev, clean=False,
>> >> >> > >> +  updatecheck='linear'):
>> >> >> > >
>> >> >> > > Please make this updatecheck=None, and set it to 'linear'
>> >> >> > > inside
>> >> >> > > merge.update() explicitly if None was passed to that function.
>> >> >> >
>> >> >> > Will do.
>> >> >> >
>> >> >> > >
>> >> >> > > This way, in patch 6, you can red the config option inside
>> >> >> > > merge.update(), and let other callers (primarily extensions)
>> >> >> > > also
>> >> >> > automatically follow the config option.
>> >> >> >
>> >> >> > I don't think it's a good idea for the low-level merge.update()
>> >> >> > to read the config. That function is called e.g. by rebase and
>> >> >> > graft and they should not have their behavior changed by this config.
>> >> >
>> >> > I tend to agree with Martin, low-level functions should have less
>> >> > dependency on config. Instead, maybe we could add a function that
>> >> > builds options from ui (like patch.diffopts), but I don't know if
>> >> > that's
>> >> appropriate here.
>> >> >
>> >> >> I forgot to add, I'm particularly concerned about the "guestrepo"
>> >> >> extension, which we use extensively at NNG. IIRC in the "grupdate"
>> >> >> command, it doesn't use commands.update, and so changing the
>> >> >> config
>> >> option causes "update"
>> >> >> and "grupdate" to behave differently.
>> >> >>
>> >> >> Also, care must be taken about subrepositories. Not sure if our
>> >> >> subrepo update code calls command.update - if not, we may even end
>> >> >> up with a situation where "hg update" in a repository with
>> >> >> subrepos with
>> >> ui.updatecheck="merge"
>> >> >> will do nonlinear updates with a dirty main repo, but not with a
>> >> >> dirty
>> >> subrepo.
>> >> >
>> >> > IIRC, updating including subrepos isn't a simple cascading operation.
>> >> > Perhaps users would be asked how to process changes in subrepos?
>> >> >
>> >> >> In fact, if we introduce a config option, but only use it in
>> >> >> commands.update(), we should make the lower functions error out or
>> >> >> at least warn if called without explicit updatecheck, and without
>> >> >> other options (e.g. branchmerge) that override linearity checks.
>> >> >> This way, we at least catch extensions that don't follow the
>> >> >> config option, but try to
>> >> rely on merge.update()'s linearity checks.
>> >> >
>> >> > Good point.
>> >>
>> >> Yeah, I agree with that last point. I tried it and there are several
>> >> places that fail. For example, clone, rebase, and mq all call
>> >> hg.update[repo](). AFAICT, there should never be any changes where
>> >> it's being called, so maybe that should be setting force=True to
>> >> overwrite. Or maybe we should teach
>> >> merge.update() to accept updatecheck='abort' and make these callers
>> >> pass that value.
>> >> Regardless, since what I'm adding is an experimental config, I'd
>> >> prefer to make merge.update() default to 'linear' for now and I'll
>> >> add a TODO to add the check you mention. I don't have time right now
>> >> to clean up all the other callers, and I'd still like to be able to make
>> progress on this topic.
>> >
>> > These other callers IIRC call with options that  already disable linearity
>> checks.
>> >
>> > We should only fail if we are in a no

Re: Chrome tracing

2017-02-15 Thread Gregory Szorc
On Wed, Feb 15, 2017 at 10:43 AM, Bryan O'Sullivan 
wrote:

> On Tue, Feb 14, 2017 at 7:02 PM, Gregory Szorc 
> wrote:
>
>>
>> I support having dedicated code for annotating well-defined and important
>> Mercurial operations in tracing/profiling logs. I have a hunch that the
>> kinds of things we need to annotate shouldn't be called with a high enough
>> frequency for probe overhead to matter.
>>
>
> Right.
>
>
>> But if it does, the use of context managers can be beneficial, as those
>> are evaluated at module load time and the context manager can be made to
>> no-op and return the original function unless tracing is enabled. That's
>> *almost* 0 cost.
>>
>
> That's exactly what the implementation does :-)
>
>
>> Something else to consider is the interaction between tracing and
>> progress bars. I posit that most places we use progress bars are places
>> we'd want to use the proposed tracing.duration() context manager. I reckon
>> we could integrate tracing into the progress APIs and kill 2 birds with 1
>> stone.
>>
>
> That's again almost exactly what the implementation does, but it uses the
> Chrome trace feature of tracking a numeric quantity instead. It's like you
> read my mind ... or the patches!
>

OK, you caught me: I only glanced at your patches ;)

I look forward to seeing this feature patchbombed!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] transaction: enable hardlink backups for non-windows systems

2017-02-15 Thread Jeroen Vaelen
Sorry for the delay in reply.

Confidence in stable posix implementations could come from:

- hardlink backups being the default for nearly 10 years before the previously
  mentioned patch disabled them after a series of bug reports coming
  exclusively from Windows users. 
- generally more dependencies on hardlinks on such systems by different
  tools which make cache coherency bugs (theory) like issue 4546 less
  likely.
  
Getting a repro for this bug has been tough. Do you have any ideas for
alternative directions here?

Excerpts from Augie Fackler's message of 2017-02-14 10:39:00 -0500:
> On Tue, Feb 14, 2017 at 01:31:02AM -0800, Jeroen Vaelen wrote:
> > # HG changeset patch
> > # User Jeroen Vaelen 
> > # Date 1487064458 28800
> > #  Tue Feb 14 01:27:38 2017 -0800
> > # Node ID c7fb7ac39a12c8683518bb7db7e1a93346e017e0
> > # Parent  a0e3d808690d57d1c9dff840e0b8ee099526397b
> > transaction: enable hardlink backups for non-windows systems
> >
> > 07a92bbd02e5 disabled hardlink backups entirely because they can cause 
> > trouble
> > with CIFS on Windows (see issue 4546). This changeset limits that 
> > restriction
> > to Windows systems. Ideally we check for CIFS, because e.g. NTFS does 
> > support
> > hardlinks. But this at least gives us cheaper transactional backups for 
> > posix,
> > which is a step forward.
> 
> I'm hesitant to take this because as of 10.12 macOS is pushing people
> towards CIFS instead of AFP, so this issue feels more likely to come
> up there. Also, isn't it possible to mount CIFS volumes in the
> filesystem space on Linux? Do we have any reason for confidence this
> is only a problem in the Windows CIFS client, and not a problem in the
> server?
> 
> Thanks!
> 
> >
> > Note: the test changes were originally introduced in 07a92bbd02e5.
> >
> > diff --git a/mercurial/util.py b/mercurial/util.py
> > --- a/mercurial/util.py
> > +++ b/mercurial/util.py
> > @@ -1084,9 +1084,9 @@
> >  if checkambig:
> >  oldstat = checkambig and filestat(dest)
> >  unlink(dest)
> > -# hardlinks are problematic on CIFS, quietly ignore this flag
> > -# until we find a way to work around it cleanly (issue4546)
> > -if False and hardlink:
> > +# quietly ignore the hardlink flag on Windows due to CIFS limitations
> > +# (see discussion on issue 4546)
> > +if hardlink and pycompat.osname != 'nt':
> >  try:
> >  oslink(src, dest)
> >  return
> > diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t
> > --- a/tests/test-hardlinks.t
> > +++ b/tests/test-hardlinks.t
> > @@ -166,7 +166,7 @@
> >1 r2/.hg/store/00manifest.i
> >1 r2/.hg/store/data/d1/f2.i
> >2 r2/.hg/store/data/f1.i
> > -  1 r2/.hg/store/fncache
> > +  2 r2/.hg/store/fncache
> >
> >$ hg -R r2 verify
> >checking changesets
> > @@ -191,7 +191,7 @@
> >1 r2/.hg/store/00manifest.i
> >1 r2/.hg/store/data/d1/f2.i
> >1 r2/.hg/store/data/f1.i
> > -  1 r2/.hg/store/fncache
> > +  2 r2/.hg/store/fncache
> >
> >
> >$ cd r3
> > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 8 simple] color: spread '_effect' values for readability

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 3:06 AM, Pierre-Yves David
 wrote:
> # HG changeset patch
> # User Pierre-Yves David 
> # Date 1479491019 -3600
> #  Fri Nov 18 18:43:39 2016 +0100
> # Node ID 42d4b49b39d6879065209ea3ca71f1e3fa88fcbc
> # Parent  354020079723e02ad6db68f58ef26eb7ebd005a8
> # EXP-Topic color
> color: spread '_effect' values for readability
>
> We move to our "usual" one value per line style.

Nit: the even more usual style (by a factor 2-2.5, it seems) is to put
the values on separate lines from the curly braces. But I won't let
that stop the patch, of course.

>
> diff -r 354020079723 -r 42d4b49b39d6 hgext/color.py
> --- a/hgext/color.pyTue Feb 07 17:33:35 2017 +0100
> +++ b/hgext/color.pyFri Nov 18 18:43:39 2016 +0100
> @@ -187,13 +187,28 @@ command = cmdutil.command(cmdtable)
>  testedwith = 'ships-with-hg-core'
>
>  # start and stop parameters for effects
> -_effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
> -'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
> -'italic': 3, 'underline': 4, 'inverse': 7, 'dim': 2,
> -'black_background': 40, 'red_background': 41,
> -'green_background': 42, 'yellow_background': 43,
> -'blue_background': 44, 'purple_background': 45,
> -'cyan_background': 46, 'white_background': 47}
> +_effects = {'none': 0,
> +'black': 30,
> +'red': 31,
> +'green': 32,
> +'yellow': 33,
> +'blue': 34,
> +'magenta': 35,
> +'cyan': 36,
> +'white': 37,
> +'bold': 1,
> +'italic': 3,
> +'underline': 4,
> +'inverse': 7,
> +'dim': 2,
> +'black_background': 40,
> +'red_background': 41,
> +'green_background': 42,
> +'yellow_background': 43,
> +'blue_background': 44,
> +'purple_background': 45,
> +'cyan_background': 46,
> +'white_background': 47}
>
>  def _terminfosetup(ui, mode):
>  '''Initialize terminfo data and the terminal if we're in terminfo 
> mode.'''
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4 V3] update: accept --merge to allow merging across topo branches (issue5125)

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1487019517 28800
#  Mon Feb 13 12:58:37 2017 -0800
# Node ID aeb2aca1361d20c12985404b87030abf3ea22f3c
# Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
update: accept --merge to allow merging across topo branches (issue5125)

diff -r afaf3c2b129c -r aeb2aca1361d mercurial/commands.py
--- a/mercurial/commands.py Mon Feb 13 15:04:46 2017 -0800
+++ b/mercurial/commands.py Mon Feb 13 12:58:37 2017 -0800
@@ -5286,12 +5286,13 @@
 @command('^update|up|checkout|co',
 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
 ('c', 'check', None, _('require clean working directory')),
+('m', 'merge', None, _('merge local changes')),
 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
 ('r', 'rev', '', _('revision'), _('REV'))
  ] + mergetoolopts,
-_('[-C|-c] [-d DATE] [[-r] REV]'))
+_('[-C|-c|-m] [-d DATE] [[-r] REV]'))
 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
-   tool=None):
+   merge=None, tool=None):
 """update working directory (or switch revisions)
 
 Update the repository's working directory to the specified
@@ -5310,8 +5311,8 @@
 
 .. container:: verbose
 
-  The -C/--clean and -c/--check options control what happens if the
-  working directory contains uncommitted changes.
+  The -C/--clean, -c/--check, and -m/--merge options control what
+  happens if the working directory contains uncommitted changes.
   At most of one of them can be specified.
 
   1. If no option is specified, and if
@@ -5323,10 +5324,14 @@
  branch), the update is aborted and the uncommitted changes
  are preserved.
 
-  2. With the -c/--check option, the update is aborted and the
+  2. With the -m/--merge option, the update is allowed even if the
+ requested changeset is not an ancestor or descendant of
+ the working directory's parent.
+
+  3. With the -c/--check option, the update is aborted and the
  uncommitted changes are preserved.
 
-  3. With the -C/--clean option, uncommitted changes are discarded and
+  4. With the -C/--clean option, uncommitted changes are discarded and
  the working directory is updated to the requested changeset.
 
 To cancel an uncommitted merge (and lose your changes), use
@@ -5351,8 +5356,15 @@
 if date and rev is not None:
 raise error.Abort(_("you can't specify a revision and a date"))
 
-if check and clean:
-raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
+if len([x for x in (clean, check, merge) if x]) > 1:
+raise error.Abort(_("can only specify one of -C/--clean, -c/--check, "
+"or -m/merge"))
+
+updatecheck = None
+if check:
+updatecheck = 'abort'
+elif merge:
+updatecheck = 'none'
 
 with repo.wlock():
 cmdutil.clearunfinished(repo)
@@ -5366,7 +5378,8 @@
 
 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
 
-return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
+return hg.updatetotally(ui, repo, rev, brev, clean=clean,
+updatecheck=updatecheck)
 
 @command('verify', [])
 def verify(ui, repo):
diff -r afaf3c2b129c -r aeb2aca1361d mercurial/hg.py
--- a/mercurial/hg.py   Mon Feb 13 15:04:46 2017 -0800
+++ b/mercurial/hg.py   Mon Feb 13 12:58:37 2017 -0800
@@ -681,18 +681,19 @@
 repo.ui.status(_("%d files updated, %d files merged, "
  "%d files removed, %d files unresolved\n") % stats)
 
-def updaterepo(repo, node, overwrite):
+def updaterepo(repo, node, overwrite, updatecheck=None):
 """Update the working directory to node.
 
 When overwrite is set, changes are clobbered, merged else
 
 returns stats (see pydoc mercurial.merge.applyupdates)"""
 return mergemod.update(repo, node, False, overwrite,
-   labels=['working copy', 'destination'])
+   labels=['working copy', 'destination'],
+   updatecheck=updatecheck)
 
-def update(repo, node, quietempty=False):
-"""update the working directory to node, merging linear changes"""
-stats = updaterepo(repo, node, False)
+def update(repo, node, quietempty=False, updatecheck=None):
+"""update the working directory to node"""
+stats = updaterepo(repo, node, False, updatecheck=updatecheck)
 _showstats(repo, stats, quietempty)
 if stats[3]:
 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
@@ -712,7 +713,7 @@
 # naming conflict in updatetotally()
 _clean = clean
 
-def updatetotally(ui, repo, checkout, brev, clean=False, check=False):
+def updatetotally(ui, repo, checkout, brev, clean=False, updatecheck=None):
 """Update the working directory with extra care for non-file components
 
 This takes care of 

[PATCH 3 of 4 V3] update: also suggest --merge when non-linear update is aborted

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1487140898 28800
#  Tue Feb 14 22:41:38 2017 -0800
# Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
# Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
update: also suggest --merge when non-linear update is aborted

diff -r 542a99ede6c3 -r c6cd58d272ae mercurial/merge.py
--- a/mercurial/merge.pyMon Feb 13 16:03:05 2017 -0800
+++ b/mercurial/merge.pyTue Feb 14 22:41:38 2017 -0800
@@ -1570,7 +1570,8 @@
 pass # allow updating to successors
 else:
 msg = _("uncommitted changes")
-hint = _("commit or update --clean to discard changes")
+hint = _("commit, or use --clean to discard changes, "
+ "or use --merge to allow update")
 raise error.UpdateAbort(msg, hint=hint)
 else:
 # Allow jumping branches if clean and specific rev given
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-merge5.t
--- a/tests/test-merge5.t   Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-merge5.t   Tue Feb 14 22:41:38 2017 -0800
@@ -26,7 +26,7 @@
 
   $ hg update 1
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
   $ mv c a
 
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-subrepo-svn.t
--- a/tests/test-subrepo-svn.t  Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-subrepo-svn.t  Tue Feb 14 22:41:38 2017 -0800
@@ -472,7 +472,7 @@
   $ echo "updating should (maybe) fail" > obstruct/other
   $ hg co tip
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
 
 Point to a Subversion branch which has since been deleted and recreated
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-update-branches.t
--- a/tests/test-update-branches.t  Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-update-branches.t  Tue Feb 14 22:41:38 2017 -0800
@@ -123,19 +123,19 @@
 
   $ revtest 'none dirty same'   dirty 2 3
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=2
   M foo
 
   $ revtest 'none dirtysub same'   dirtysub 2 3
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=2
   M sub/suba
 
   $ revtest 'none dirty cross'  dirty 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M foo
 
@@ -147,7 +147,7 @@
 
   $ revtest 'none dirtysub cross'  dirtysub 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M sub/suba
 
@@ -258,7 +258,7 @@
 
   $ revtest 'dirty cross'  dirty 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M foo
 
@@ -476,7 +476,7 @@
   $ hg up --quiet 2
   $ hg up 5
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
 
 Test that we don't crash when updating from a pruned changeset (i.e. has no
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4 V3] update: add experimental config for default way of handling dirty wdir

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1487030585 28800
#  Mon Feb 13 16:03:05 2017 -0800
# Node ID 542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
# Parent  aeb2aca1361d20c12985404b87030abf3ea22f3c
update: add experimental config for default way of handling dirty wdir

This allows the user to set e.g. experimental.updatecheck=abort to
abort update if the working directory is dirty, but still be able to
override the behavior with e.g. --merge when needed.

I considered adding a --mergelinear option to get back the old
behavior even when experimental.updatecheck=abort is set, but I
couldn't see why anyone would prefer that over --merge.

The default is read in hg.updatetotally(), which means it also applies
to "hg update -u" and "hg unbundle -u".

diff -r aeb2aca1361d -r 542a99ede6c3 mercurial/hg.py
--- a/mercurial/hg.py   Mon Feb 13 12:58:37 2017 -0800
+++ b/mercurial/hg.py   Mon Feb 13 16:03:05 2017 -0800
@@ -737,7 +737,10 @@
 This returns whether conflict is detected at updating or not.
 """
 if updatecheck is None:
-updatecheck = 'linear'
+updatecheck = ui.config('experimental', 'updatecheck')
+if updatecheck not in ('abort', 'none', 'linear'):
+# If not configured, or invalid value configured
+updatecheck = 'linear'
 with repo.wlock():
 movemarkfrom = None
 warndest = False
diff -r aeb2aca1361d -r 542a99ede6c3 tests/test-pull-update.t
--- a/tests/test-pull-update.t  Mon Feb 13 12:58:37 2017 -0800
+++ b/tests/test-pull-update.t  Mon Feb 13 16:03:05 2017 -0800
@@ -16,6 +16,21 @@
   $ echo 1.2 > foo
   $ hg ci -Am m
 
+Should respect config to disable dirty update
+  $ hg co -qC 0
+  $ echo 2 > foo
+  $ hg --config experimental.updatecheck=abort pull -u ../tt
+  pulling from ../tt
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  abort: uncommitted changes
+  [255]
+  $ hg --config extensions.strip= strip --no-backup tip
+  $ hg co -qC tip
+
 Should not update to the other topological branch:
 
   $ hg pull -u ../tt
diff -r aeb2aca1361d -r 542a99ede6c3 tests/test-update-branches.t
--- a/tests/test-update-branches.t  Mon Feb 13 12:58:37 2017 -0800
+++ b/tests/test-update-branches.t  Mon Feb 13 16:03:05 2017 -0800
@@ -195,6 +195,79 @@
   parent=1
   M foo
 
+  $ echo '[experimental]' >> .hg/hgrc
+  $ echo 'updatecheck = abort' >> .hg/hgrc
+
+  $ revtest 'none dirty linear' dirty 1 2
+  abort: uncommitted changes
+  parent=1
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -c
+  abort: uncommitted changes
+  parent=1
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -C
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=2
+
+  $ echo 'updatecheck = none' >> .hg/hgrc
+
+  $ revtest 'none dirty cross'  dirty 3 4
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=4
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=2
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -c
+  abort: uncommitted changes
+  parent=1
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -C
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=2
+
+  $ hg co -qC 3
+  $ echo dirty >> a
+  $ hg co 4
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges
+  [1]
+  $ hg st
+  M a
+  ? a.orig
+  $ cat a
+  <<< working copy: 6efa171f091b - test: 3
+  three
+  dirty
+  ===
+  four
+  >>> destination:  d047485b3896 b1 - test: 4
+  $ rm a.orig
+
+Uses default value of "linear" when value is misspelled
+  $ echo 'updatecheck = linyar' >> .hg/hgrc
+
+  $ revtest 'dirty cross'  dirty 3 4
+  abort: uncommitted changes
+  (commit or update --clean to discard changes)
+  parent=3
+  M foo
+
+Setup for later tests
+  $ revtest 'none dirty linear' dirty 1 2 -c
+  abort: uncommitted changes
+  parent=1
+  M foo
+
   $ cd ..
 
 Test updating to null revision
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4 V3] update: allow setting default update check to "noconflict"

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1486973155 28800
#  Mon Feb 13 00:05:55 2017 -0800
# Node ID afae5920ae4d9116b33f8d43e1266a642518e265
# Parent  c6cd58d272aee6633fbad5eacdad742e2f9909cd
update: allow setting default update check to "noconflict"

The new value allows update (linear or not) as long as they don't
result in file merges.

I'm hoping that this value can some day become the default.

diff -r c6cd58d272ae -r afae5920ae4d mercurial/hg.py
--- a/mercurial/hg.py   Tue Feb 14 22:41:38 2017 -0800
+++ b/mercurial/hg.py   Mon Feb 13 00:05:55 2017 -0800
@@ -733,12 +733,13 @@
  * none: don't check (merge working directory changes into destination)
  * linear: check that update is linear before merging working directory
changes into destination
+ * noconflict: check that the update does not result in file merges
 
 This returns whether conflict is detected at updating or not.
 """
 if updatecheck is None:
 updatecheck = ui.config('experimental', 'updatecheck')
-if updatecheck not in ('abort', 'none', 'linear'):
+if updatecheck not in ('abort', 'none', 'linear', 'noconflict'):
 # If not configured, or invalid value configured
 updatecheck = 'linear'
 with repo.wlock():
diff -r c6cd58d272ae -r afae5920ae4d mercurial/merge.py
--- a/mercurial/merge.pyTue Feb 14 22:41:38 2017 -0800
+++ b/mercurial/merge.pyMon Feb 13 00:05:55 2017 -0800
@@ -1501,7 +1501,7 @@
 # updatecheck='abort' to better suppport some of these callers.
 if updatecheck is None:
 updatecheck = 'linear'
-assert updatecheck in ('none', 'linear')
+assert updatecheck in ('none', 'linear', 'noconflict')
 # If we're doing a partial update, we need to skip updating
 # the dirstate, so make a note of any partial-ness to the
 # update here.
@@ -1596,6 +1596,13 @@
 repo, wc, p2, pas, branchmerge, force, mergeancestor,
 followcopies, matcher=matcher, mergeforce=mergeforce)
 
+if updatecheck == 'noconflict':
+for f, (m, args, msg) in actionbyfile.iteritems():
+if m not in ('g', 'k', 'r'):
+msg = _("uncommitted changes")
+hint = _("commit or update --merge to allow merge")
+raise error.Abort(msg, hint=hint)
+
 # Prompt and create actions. Most of this is in the resolve phase
 # already, but we can't handle .hgsubstate in filemerge or
 # subrepo.submerge yet so we have to keep prompting for it.
diff -r c6cd58d272ae -r afae5920ae4d tests/test-update-branches.t
--- a/tests/test-update-branches.t  Tue Feb 14 22:41:38 2017 -0800
+++ b/tests/test-update-branches.t  Mon Feb 13 00:05:55 2017 -0800
@@ -253,6 +253,65 @@
   >>> destination:  d047485b3896 b1 - test: 4
   $ rm a.orig
 
+  $ echo 'updatecheck = noconflict' >> .hg/hgrc
+
+  $ revtest 'none dirty cross'  dirty 3 4
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=4
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=2
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -c
+  abort: uncommitted changes
+  parent=1
+  M foo
+
+  $ revtest 'none dirty linear' dirty 1 2 -C
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  parent=2
+
+Locally added file is allowed
+  $ hg up -qC 3
+  $ echo a > bar
+  $ hg add bar
+  $ hg up -q 4
+  $ hg st
+  A bar
+  $ hg forget bar
+  $ rm bar
+
+Locally removed file is allowed
+  $ hg up -qC 3
+  $ hg rm a
+  $ hg up -q 4
+  abort: uncommitted changes
+  (commit or update --merge to allow merge)
+  [255]
+
+File conflict is not allowed
+  $ hg up -qC 3
+  $ echo dirty >> a
+  $ hg up -q 4
+  abort: uncommitted changes
+  (commit or update --merge to allow merge)
+  [255]
+  $ hg up -m 4
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges
+  [1]
+  $ rm a.orig
+
+Change/delete conflict is not allowed
+  $ hg up -qC 3
+  $ hg rm foo
+  $ hg up -q 4
+
 Uses default value of "linear" when value is misspelled
   $ echo 'updatecheck = linyar' >> .hg/hgrc
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 10 v5] util: introduce timer()

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487188439 28800
#  Wed Feb 15 11:53:59 2017 -0800
# Node ID 36ad17f00656ef853e0bd7b79e9cd98b58c92a16
# Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
util: introduce timer()

As documented for timeit.default_timer, there are better timers available for
performance measures on some platforms. These timers don't have a set epoch,
and thus are only useful for interval measurements, but have higher
resolution, and thus get you a better measurement overall.

Use the same selection logic as Python's timeit.default_timer. This is a
platform clock on Python 2 and early Python 3, and time.perf_counter on Python
3.3 and later (where time.perf_counter is introduced as the best timer to use).

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1203,8 +1203,13 @@
 
 if pycompat.osname == 'nt':
 checkosfilename = checkwinfilename
+timer = time.clock
 else:
 checkosfilename = platform.checkosfilename
+timer = time.time
+
+if safehasattr(time, "perf_counter"):
+timer = time.perf_counter
 
 def makelock(info, pathname):
 try:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 10 v5] mercurial: switch to util.timer for all interval timings

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487193459 28800
#  Wed Feb 15 13:17:39 2017 -0800
# Node ID 1c71bddbe01e76c1c48b5479ff67d47645afd7b6
# Parent  36ad17f00656ef853e0bd7b79e9cd98b58c92a16
mercurial: switch to util.timer for all interval timings

util.timer is now the best available interval timer, at the expense of not
having a known epoch. Let's use it whenever the epoch is irrelevant.

diff --git a/contrib/hgperf b/contrib/hgperf
old mode 100644
new mode 100755
--- a/contrib/hgperf
+++ b/contrib/hgperf
@@ -55,17 +55,15 @@
 import mercurial.util
 import mercurial.dispatch
 
-import time
-
 def timer(func, title=None):
 results = []
-begin = time.time()
+begin = mercurial.util.timer()
 count = 0
 while True:
 ostart = os.times()
-cstart = time.time()
+cstart = mercurial.util.timer()
 r = func()
-cstop = time.time()
+cstop = mercurial.util.timer()
 ostop = os.times()
 count += 1
 a, b = ostart, ostop
diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -190,13 +190,13 @@
 
 def _timer(fm, func, title=None):
 results = []
-begin = time.time()
+begin = util.timer()
 count = 0
 while True:
 ostart = os.times()
-cstart = time.time()
+cstart = util.timer()
 r = func()
-cstop = time.time()
+cstop = util.timer()
 ostop = os.times()
 count += 1
 a, b = ostart, ostop
diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -9,7 +9,6 @@
 
 import array
 import struct
-import time
 
 from .node import (
 bin,
@@ -21,6 +20,7 @@
 encoding,
 error,
 scmutil,
+util,
 )
 
 array = array.array
@@ -261,7 +261,7 @@
 missing heads, and a generator of nodes that are strictly a superset of
 heads missing, this function updates self to be correct.
 """
-starttime = time.time()
+starttime = util.timer()
 cl = repo.changelog
 # collect new branch entries
 newbranches = {}
@@ -314,7 +314,7 @@
 self.tiprev = tiprev
 self.filteredhash = scmutil.filteredhash(repo, self.tiprev)
 
-duration = time.time() - starttime
+duration = util.timer() - starttime
 repo.ui.log('branchcache', 'updated %s branch cache in %.4f seconds\n',
 repo.filtername, duration)
 
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -123,7 +123,7 @@
 return -1
 
 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
-starttime = time.time()
+starttime = util.timer()
 ret = None
 try:
 ret = _runcatch(req)
@@ -135,7 +135,7 @@
 raise
 ret = -1
 finally:
-duration = time.time() - starttime
+duration = util.timer() - starttime
 req.ui.flush()
 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
msg, ret or 0, duration)
diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -9,7 +9,6 @@
 
 import os
 import sys
-import time
 
 from .i18n import _
 from . import (
@@ -88,7 +87,7 @@
 % (hname, funcname))
 
 ui.note(_("calling hook %s: %s\n") % (hname, funcname))
-starttime = time.time()
+starttime = util.timer()
 
 try:
 r = obj(ui=ui, repo=repo, hooktype=name, **args)
@@ -106,7 +105,7 @@
 ui.traceback()
 return True, True
 finally:
-duration = time.time() - starttime
+duration = util.timer() - starttime
 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n',
name, funcname, duration)
 if r:
@@ -118,7 +117,7 @@
 def _exthook(ui, repo, name, cmd, args, throw):
 ui.note(_("running hook %s: %s\n") % (name, cmd))
 
-starttime = time.time()
+starttime = util.timer()
 env = {}
 
 # make in-memory changes visible to external process
@@ -145,7 +144,7 @@
 cwd = pycompat.getcwd()
 r = ui.system(cmd, environ=env, cwd=cwd)
 
-duration = time.time() - starttime
+duration = util.timer() - starttime
 ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n',
name, cmd, duration)
 if r:
diff --git a/mercurial/profiling.py b/mercurial/profiling.py
--- a/mercurial/profiling.py
+++ b/mercurial/profiling.py
@@ -8,7 +8,6 @@
 from __future__ import absolute_import, print_function
 
 import contextlib
-import time
 
 from .i18n import _
 from . import (
@@ -66,7 +65,7 @@
 collapse_recursion = True
 thread = flamegraph.ProfileThread(fp, 1.0 / freq,
   filter_, collapse_recursion)
-start_time = time.clock()
+start_time = util.timer()
 try:
 thread.sta

[PATCH 04 of 10 v5] contrib: add a write microbenchmark to perf.py

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487192846 28800
#  Wed Feb 15 13:07:26 2017 -0800
# Node ID 4d0b19ca8a56341fe2a77fd243232185ab4bf5e0
# Parent  f3a219226ba0658f72801329d07c1ba516152b70
contrib: add a write microbenchmark to perf.py

I'm adding some performance logging to ui.write - this benchmark lets us
confirm that the cost of that logging is acceptably low.

At this point, the microbenchmark on Linux over SSH shows:

! wall 3.213560 comb 0.41 user 0.35 sys 0.06 (best of 4)

while on the Mac locally, it shows:

! wall 0.342325 comb 0.18 user 0.11 sys 0.07 (best of 20)

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -1269,6 +1269,17 @@
 timer(fn, title=title)
 fm.end()
 
+@command('perfwrite', formatteropts)
+def perfwrite(ui, repo, **opts):
+"""microbenchmark ui.write
+"""
+timer, fm = gettimer(ui, opts)
+def write():
+for i in range(10):
+ui.write(('Testing write performance\n'))
+timer(write)
+fm.end()
+
 def uisetup(ui):
 if (util.safehasattr(cmdutil, 'openrevlog') and
 not util.safehasattr(commands, 'debugrevlogopts')):
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -109,6 +109,7 @@
perfvolatilesets
  benchmark the computation of various volatile set
perfwalk  (no help text available)
+   perfwrite microbenchmark ui.write
   
   (use 'hg help -v perfstatusext' to show built-in aliases and global options)
   $ hg perfaddremove
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 10 v5] ui: time calls to ui.system

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487194152 28800
#  Wed Feb 15 13:29:12 2017 -0800
# Node ID 1ae8bc5565b680008d82e93bee9455432b6ba0b2
# Parent  1487dd34f44315371738b13519cc4af1c81a7b07
ui: time calls to ui.system

We want to know when we're blocked on ui.system, and why. Allow the user to
supply a tag - otherwise we record on an unspecific tag derived from cmd.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -35,6 +35,9 @@
 
 urlreq = util.urlreq
 
+# for use with str.translate(None, _keepalnum), to keep just alphanumerics
+_keepalnum = ''.join(c for c in map(chr, range(256)) if not c.isalnum())
+
 samplehgrcs = {
 'user':
 """# example user config (see 'hg help config' for more info)
@@ -1146,15 +1149,19 @@
 
 return t
 
-def system(self, cmd, environ=None, cwd=None, onerr=None, errprefix=None):
+def system(self, cmd, environ=None, cwd=None, onerr=None, errprefix=None,
+   blockedtag=None):
 '''execute shell command with appropriate output stream. command
 output will be redirected if fout is not stdout.
 '''
+if blockedtag is None:
+blockedtag = 'unknown_system_' + cmd.translate(None, _keepalnum)
 out = self.fout
 if any(s[1] for s in self._bufferstates):
 out = self
-return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
-   errprefix=errprefix, out=out)
+with self.timeblockedsection(blockedtag):
+return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
+   errprefix=errprefix, out=out)
 
 def traceback(self, exc=None, force=False):
 '''print exception traceback if traceback printing enabled or forced.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 10 v5] ui: provide a mechanism to track and log blocked time

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487193465 28800
#  Wed Feb 15 13:17:45 2017 -0800
# Node ID f3a219226ba0658f72801329d07c1ba516152b70
# Parent  1c71bddbe01e76c1c48b5479ff67d47645afd7b6
ui: provide a mechanism to track and log blocked time

We want to log the time Mercurial spends trapped in things outside
programmatic control. Provide a mechanism to give us both command runtime
and as many different sources of blocking as we deem useful.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -137,6 +137,9 @@
 finally:
 duration = util.timer() - starttime
 req.ui.flush()
+if req.ui.logblockedtimes:
+req.ui._blockedtimes['command_duration'] = duration * 1000
+req.ui.log('uiblocked', 'ui blocked ms', **req.ui._blockedtimes)
 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
msg, ret or 0, duration)
 return ret
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -7,6 +7,7 @@
 
 from __future__ import absolute_import
 
+import collections
 import contextlib
 import errno
 import getpass
@@ -138,6 +139,8 @@
 self.callhooks = True
 # Insecure server connections requested.
 self.insecureconnections = False
+# Blocked time
+self.logblockedtimes = False
 
 if src:
 self.fout = src.fout
@@ -155,6 +158,7 @@
 self.fixconfig()
 
 self.httppasswordmgrdb = src.httppasswordmgrdb
+self._blockedtimes = src._blockedtimes
 else:
 self.fout = util.stdout
 self.ferr = util.stderr
@@ -164,6 +168,7 @@
 self.environ = encoding.environ
 
 self.httppasswordmgrdb = httppasswordmgrdbproxy()
+self._blockedtimes = collections.defaultdict(int)
 
 allowed = self.configlist('experimental', 'exportableenviron')
 if '*' in allowed:
@@ -192,6 +197,15 @@
 self._progbar.resetstate()  # reset last-print time of progress bar
 self.httppasswordmgrdb = httppasswordmgrdbproxy()
 
+@contextlib.contextmanager
+def timeblockedsection(self, key):
+starttime = util.timer()
+try:
+yield
+finally:
+self._blockedtimes[key + '_blocked'] += \
+(util.timer() - starttime) * 1000
+
 def formatter(self, topic, opts):
 return formatter.formatter(self, topic, opts)
 
@@ -295,6 +309,7 @@
 self._reportuntrusted = self.debugflag or self.configbool("ui",
 "report_untrusted", True)
 self.tracebackflag = self.configbool('ui', 'traceback', False)
+self.logblockedtimes = self.configbool('ui', 'logblockedtimes')
 
 if section in (None, 'trusted'):
 # update trust information
diff --git a/tests/test-logtoprocess.t b/tests/test-logtoprocess.t
--- a/tests/test-logtoprocess.t
+++ b/tests/test-logtoprocess.t
@@ -10,6 +10,7 @@
   > def foo(ui, repo):
   > ui.log('foo', 'a message: %(bar)s\n', bar='spam')
   > EOF
+  $ cp $HGRCPATH $HGRCPATH.bak
   $ cat >> $HGRCPATH << EOF
   > [extensions]
   > logtoprocess=
@@ -52,3 +53,18 @@
   logtoprocess commandfinish output:
   logtoprocess foo output:
   spam
+
+Confirm that logging blocked time catches stdio properly:
+  $ cp $HGRCPATH.bak $HGRCPATH
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > logtoprocess=
+  > pager=
+  > [logtoprocess]
+  > uiblocked=echo "\$EVENT command \$OPT_COMMAND_DURATION ms"
+  > [ui]
+  > logblockedtimes=True
+  > EOF
+
+  $ hg log
+  uiblocked command [0-9]+.[0-9]* ms (re)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 10 v5] ui: log time spent blocked on stdio

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487195406 28800
#  Wed Feb 15 13:50:06 2017 -0800
# Node ID 1487dd34f44315371738b13519cc4af1c81a7b07
# Parent  4d0b19ca8a56341fe2a77fd243232185ab4bf5e0
ui: log time spent blocked on stdio

We use a wrapper around Mercurial at Facebook that logs key statistics (like
elpased time) to our standard performance tooling.

This is less useful than it could be, because we currently can't tell when a
command is slow because we need to fix Mercurial versus when a command is
slow because the user isn't interacting quickly.

Teach Mercurial to log the time it spends blocked, so that our tooling can
pick it up and submit it with the elapsed time - we can then do the math in
our tooling to see if Mercurial is slow, or if the user simply failed to
interact.

Combining this with the command duration log means that we can ensure that
we concentrate performance efforts on the things that bite Facebook users.

The perfwrite microbenchmark shifts from:
Linux:
! wall 3.213560 comb 0.41 user 0.35 sys 0.06 (best of 4)
Mac:
! wall 0.342325 comb 0.18 user 0.11 sys 0.07 (best of 20)

before this change to:
! wall 3.478070 comb 0.50 user 0.42 sys 0.08 (best of 3)
Mac:
! wall 0.218112 comb 0.22 user 0.15 sys 0.07 (best of 15)

showing a small hit in comb time, but firmly in the noise on wall time.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -199,6 +199,7 @@
 
 @contextlib.contextmanager
 def timeblockedsection(self, key):
+# this is open-coded below - search for timeblockedsection to find them
 starttime = util.timer()
 try:
 yield
@@ -776,31 +777,44 @@
 self._buffers[-1].extend(a for a in args)
 else:
 self._progclear()
-for a in args:
-self.fout.write(a)
+# opencode timeblockedsection because this is a critical path
+starttime = util.timer()
+try:
+for a in args:
+self.fout.write(a)
+finally:
+self._blockedtimes['stdio_blocked'] += \
+(util.timer() - starttime) * 1000
 
 def write_err(self, *args, **opts):
 self._progclear()
 try:
 if self._bufferstates and self._bufferstates[-1][0]:
 return self.write(*args, **opts)
-if not getattr(self.fout, 'closed', False):
-self.fout.flush()
-for a in args:
-self.ferr.write(a)
-# stderr may be buffered under win32 when redirected to files,
-# including stdout.
-if not getattr(self.ferr, 'closed', False):
-self.ferr.flush()
+with self.timeblockedsection('stdio'):
+if not getattr(self.fout, 'closed', False):
+self.fout.flush()
+for a in args:
+self.ferr.write(a)
+# stderr may be buffered under win32 when redirected to files,
+# including stdout.
+if not getattr(self.ferr, 'closed', False):
+self.ferr.flush()
 except IOError as inst:
 if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
 raise
 
 def flush(self):
-try: self.fout.flush()
-except (IOError, ValueError): pass
-try: self.ferr.flush()
-except (IOError, ValueError): pass
+# opencode timeblockedsection because this is a critical path
+starttime = util.timer()
+try:
+try: self.fout.flush()
+except (IOError, ValueError): pass
+try: self.ferr.flush()
+except (IOError, ValueError): pass
+finally:
+self._blockedtimes['stdio_blocked'] += \
+(util.timer() - starttime) * 1000
 
 def _isatty(self, fh):
 if self.configbool('ui', 'nontty', False):
@@ -962,7 +976,8 @@
 sys.stdout = self.fout
 # prompt ' ' must exist; otherwise readline may delete entire line
 # - http://bugs.python.org/issue12833
-line = raw_input(' ')
+with self.timeblockedsection('stdio'):
+line = raw_input(' ')
 sys.stdin = oldin
 sys.stdout = oldout
 
@@ -1042,13 +1057,14 @@
 self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
 # disable getpass() only if explicitly specified. it's still valid
 # to interact with tty even if fin is not a tty.
-if self.configbool('ui', 'nontty'):
-l = self.fin.readline()
-if not l:
-raise EOFError
-return l.rstrip('\n')
-else:
-return getpass.getpass('')
+with self.timeblockedsection('stdio'):
+if self.configbool('ui', 'nontt

[PATCH 08 of 10 v5] crecord: log blocked time waiting for curses input

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487194446 28800
#  Wed Feb 15 13:34:06 2017 -0800
# Node ID 124f329bc78f53abce06a1e8e6244fcdcc551e34
# Parent  ce6e773a6719fab87fa098021aac72b42709aa33
crecord: log blocked time waiting for curses input

We want to know when we're blocked waiting for the user - log the time spent
waiting in the curses keyboard handlers

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -1375,7 +1375,8 @@
 pass
 helpwin.refresh()
 try:
-helpwin.getkey()
+with self.ui.timeblockedsection('crecord'):
+helpwin.getkey()
 except curses.error:
 pass
 
@@ -1392,7 +1393,8 @@
 self.stdscr.refresh()
 confirmwin.refresh()
 try:
-response = chr(self.stdscr.getch())
+with self.ui.timeblockedsection('crecord'):
+response = chr(self.stdscr.getch())
 except ValueError:
 response = None
 
@@ -1412,7 +1414,8 @@
 
 are you sure you want to review/edit and confirm the selected changes [yn]?
 """)
-response = self.confirmationwindow(confirmtext)
+with self.ui.timeblockedsection('crecord'):
+response = self.confirmationwindow(confirmtext)
 if response is None:
 response = "n"
 if response.lower().startswith("y"):
@@ -1655,7 +1658,8 @@
 while True:
 self.updatescreen()
 try:
-keypressed = self.statuswin.getkey()
+with self.ui.timeblockedsection('crecord'):
+keypressed = self.statuswin.getkey()
 if self.errorstr is not None:
 self.errorstr = None
 continue
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 10 v5] histedit: log the time taken to read in the commands list

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487194446 28800
#  Wed Feb 15 13:34:06 2017 -0800
# Node ID b9cf9ffdf15f67b42e87272e2fb328102e8284ba
# Parent  c17e5f194dca47819ca2d636a3c9cfdf02733ba7
histedit: log the time taken to read in the commands list

If we're being fed an external command list from stdin (histedit --commands -),
then the time spent reading stdin is outside our control. Log it.

diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -992,7 +992,8 @@
 
 def _readfile(ui, path):
 if path == '-':
-return ui.fin.read()
+with ui.timeblockedsection('histedit'):
+return ui.fin.read()
 else:
 with open(path, 'rb') as f:
 return f.read()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 10 v5] extdiff: log time spent in external diff program

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487194446 28800
#  Wed Feb 15 13:34:06 2017 -0800
# Node ID c17e5f194dca47819ca2d636a3c9cfdf02733ba7
# Parent  124f329bc78f53abce06a1e8e6244fcdcc551e34
extdiff: log time spent in external diff program

We can't fix the time external diff programs take to run. Log that duration
for us to remove from any stats we gather

diff --git a/hgext/extdiff.py b/hgext/extdiff.py
--- a/hgext/extdiff.py
+++ b/hgext/extdiff.py
@@ -273,7 +273,7 @@
 cmdline = re.sub(regex, quote, cmdline)
 
 ui.debug('running %r in %s\n' % (cmdline, tmproot))
-ui.system(cmdline, cwd=tmproot)
+ui.system(cmdline, cwd=tmproot, blockedtag='extdiff')
 
 for copy_fn, working_fn, mtime in fns_and_mtime:
 if os.lstat(copy_fn).st_mtime != mtime:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 10 v5] ui: give editor() a tag of its own

2017-02-15 Thread Simon Farnsworth
# HG changeset patch
# User Simon Farnsworth 
# Date 1487194680 28800
#  Wed Feb 15 13:38:00 2017 -0800
# Node ID ce6e773a6719fab87fa098021aac72b42709aa33
# Parent  1ae8bc5565b680008d82e93bee9455432b6ba0b2
ui: give editor() a tag of its own

We know that calls to ui.editor() always block on the user's configured editor.
Use a blocking tag that ensures that we don't see a huge variety of editor
options in our logging.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1139,7 +1139,8 @@
 
 self.system("%s \"%s\"" % (editor, name),
 environ=environ,
-onerr=error.Abort, errprefix=_("edit failed"))
+onerr=error.Abort, errprefix=_("edit failed"),
+blockedtag='editor')
 
 f = open(name)
 t = f.read()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 8 of 8 simple] color: move the '_render_effects' function to the core module

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 3:06 AM, Pierre-Yves David
 wrote:
> # HG changeset patch
> # User Pierre-Yves David 
> # Date 1482370733 -3600
> #  Thu Dec 22 02:38:53 2016 +0100
> # Node ID f0f04ac8d4b17345b5375e4b11d895e7c22eb6ab
> # Parent  93e658cd6e685593ddc94d2b46ba596b1bb0d143
> # EXP-Topic color
> color: move the '_render_effects' function to the core module

Queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 4 V3] update: also suggest --merge when non-linear update is aborted

2017-02-15 Thread Augie Fackler
On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via 
Mercurial-devel wrote:
> # HG changeset patch
> # User Martin von Zweigbergk 
> # Date 1487140898 28800
> #  Tue Feb 14 22:41:38 2017 -0800
> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
> update: also suggest --merge when non-linear update is aborted

This makes me a touch nervous, since the merge can leave the user in
an state that's hard to recover from.

Series LG otherwise, but I won't land it since I'm also enthusiastic
about the feature added in patch 4.

>
> diff -r 542a99ede6c3 -r c6cd58d272ae mercurial/merge.py
> --- a/mercurial/merge.py  Mon Feb 13 16:03:05 2017 -0800
> +++ b/mercurial/merge.py  Tue Feb 14 22:41:38 2017 -0800
> @@ -1570,7 +1570,8 @@
>  pass # allow updating to successors
>  else:
>  msg = _("uncommitted changes")
> -hint = _("commit or update --clean to discard 
> changes")
> +hint = _("commit, or use --clean to discard changes, 
> "
> + "or use --merge to allow update")
>  raise error.UpdateAbort(msg, hint=hint)
>  else:
>  # Allow jumping branches if clean and specific rev given
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-merge5.t
> --- a/tests/test-merge5.t Mon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-merge5.t Tue Feb 14 22:41:38 2017 -0800
> @@ -26,7 +26,7 @@
>
>$ hg update 1
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>[255]
>$ mv c a
>
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-subrepo-svn.t
> --- a/tests/test-subrepo-svn.tMon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-subrepo-svn.tTue Feb 14 22:41:38 2017 -0800
> @@ -472,7 +472,7 @@
>$ echo "updating should (maybe) fail" > obstruct/other
>$ hg co tip
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>[255]
>
>  Point to a Subversion branch which has since been deleted and recreated
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-update-branches.t
> --- a/tests/test-update-branches.tMon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-update-branches.tTue Feb 14 22:41:38 2017 -0800
> @@ -123,19 +123,19 @@
>
>$ revtest 'none dirty same'   dirty 2 3
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>parent=2
>M foo
>
>$ revtest 'none dirtysub same'   dirtysub 2 3
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>parent=2
>M sub/suba
>
>$ revtest 'none dirty cross'  dirty 3 4
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>parent=3
>M foo
>
> @@ -147,7 +147,7 @@
>
>$ revtest 'none dirtysub cross'  dirtysub 3 4
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>parent=3
>M sub/suba
>
> @@ -258,7 +258,7 @@
>
>$ revtest 'dirty cross'  dirty 3 4
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>parent=3
>M foo
>
> @@ -476,7 +476,7 @@
>$ hg up --quiet 2
>$ hg up 5
>abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>[255]
>
>  Test that we don't crash when updating from a pruned changeset (i.e. has no
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 10 of 10 v5] histedit: log the time taken to read in the commands list

2017-02-15 Thread Bryan O'Sullivan
On Wed, Feb 15, 2017 at 2:07 PM, Simon Farnsworth  wrote:

> histedit: log the time taken to read in the commands list
>

Series looks great. Ship it!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


help: I broke test-gendoc-ro.t and I have no idea how

2017-02-15 Thread Augie Fackler
With my pager-modernization work applied, I've got one test failure that is 
blocking me from mailing:
augie% make test-gendoc-ro.t
cd tests && python run-tests.py -j16 test-gendoc-ro.t
--- /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t
+++ /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t.err
@@ -2,3 +2,5 @@
 
   $ $TESTDIR/check-gendoc ro
   checking for parse errors
+  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
start-string without end-string.
+  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
start-string without end-string.
ERROR: test-gendoc-ro.t output changed

This is caused by something I did in 
https://hg.durin42.com/hg-wip/rev/b7285db7c604, but I have no idea what. Can 
anyone help me figure out this last problem?

Thanks!
Augie

(If it helps to have those together, I also pasted them here as part of asking 
for advice on irc https://bitbucket.org/snippets/durin42/yeqMp)


___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] runtests: checkportisavailable should only check one family

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487204542 28800
#  Wed Feb 15 16:22:22 2017 -0800
# Node ID d223c3d57e14f22c18030166b83e2da9143fdf67
# Parent  a70fa1e0fcdb11980338d72dde33dfe047bda7c2
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r d223c3d57e14
runtests: checkportisavailable should only check one family

As explained by the previous patch, checkportisavailable() should only check
the preferred family - either IPv4 or IPv6, not both.

This patch makes it so.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -138,8 +138,9 @@ useipv6 = checkipv6available()
 def checkportisavailable(port):
 """return true if a port seems free to bind on localhost"""
-families = [getattr(socket, i, None)
-for i in ('AF_INET', 'AF_INET6')
-if getattr(socket, i, None) is not None]
-for family in families:
+if useipv6:
+family = socket.AF_INET6
+else:
+family = socket.AF_INET
+if True:
 try:
 s = socket.socket(family, socket.SOCK_STREAM)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] runtests: unindent an "if True" block

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487204998 28800
#  Wed Feb 15 16:29:58 2017 -0800
# Node ID c5bdb942d324dcd732d277457d11eff7dc6aacc3
# Parent  bacc5256a49b34d07616c1e60e119a74ac721b7a
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r c5bdb942d324
runtests: unindent an "if True" block

The block was left to make review easier. This patch unindents it.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -142,14 +142,13 @@ def checkportisavailable(port):
 else:
 family = socket.AF_INET
-if True:
-try:
-s = socket.socket(family, socket.SOCK_STREAM)
-s.bind(('localhost', port))
-s.close()
-return True
-except socket.error as exc:
-if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
- errno.EPROTONOSUPPORT):
-raise
+try:
+s = socket.socket(family, socket.SOCK_STREAM)
+s.bind(('localhost', port))
+s.close()
+return True
+except socket.error as exc:
+if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
+ errno.EPROTONOSUPPORT):
+raise
 return False
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487204311 28800
#  Wed Feb 15 16:18:31 2017 -0800
# Node ID a70fa1e0fcdb11980338d72dde33dfe047bda7c2
# Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r a70fa1e0fcdb
runtests: add a function to test if IPv6 is available

Previously, checkportisavailable returns True if the port is free either on
IPv4 or IPv6, but the hg server only uses IPv4 by default. That leads to
issues when IPv4 port is not free but the IPv6 one is.

To address that, run-tests should stick with either IPv4 or IPv6. This patch
adds a function similar to checkportisavailable to test if IPv6 is
available, and assigns the result to a variable.

The new function was tested in a Linux system script with the following
steps:

  1. Run "ip addr del ::1/128 dev lo" to delete lo's IPv6 address,
 Confirm checkipv6available() returns False.
  2. Run "ip addr add ::1/128 dev lo" to add back lo's IPv6 address.
 Confirm checkipv6available() returns True.
  3. Start a web server taking the 8000 port.
 Confirm checkipv6available(8000) is still True.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -113,4 +113,27 @@ else:
 wifexited = getattr(os, "WIFEXITED", lambda x: False)
 
+# Whether to use IPv6
+def checkipv6available(port=20058):
+"""return true if we can listen on localhost's IPv6 ports"""
+family = getattr(socket, 'AF_INET6', None)
+if family is None:
+return False
+try:
+s = socket.socket(family, socket.SOCK_STREAM)
+s.bind(('localhost', port))
+s.close()
+return True
+except socket.error as exc:
+if exc.errno == errno.EADDRINUSE:
+return True
+elif exc.errno in (errno.EADDRNOTAVAIL, errno.EPROTONOSUPPORT):
+return False
+else:
+raise
+else:
+return False
+
+useipv6 = checkipv6available()
+
 def checkportisavailable(port):
 """return true if a port seems free to bind on localhost"""
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] runtests: set web.ipv6 if we use IPv6

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487205807 28800
#  Wed Feb 15 16:43:27 2017 -0800
# Node ID bacc5256a49b34d07616c1e60e119a74ac721b7a
# Parent  d223c3d57e14f22c18030166b83e2da9143fdf67
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r bacc5256a49b
runtests: set web.ipv6 if we use IPv6

As explained by the previous patch, we need to set "web.ipv6=True" if we
decide to use IPv6. Otherwise "hg serve" will still try to listen on IPv4.

This patch makes it so by appending web.ipv6 to "extra configs".

This patch was tested in a Linux system with IPv6, by the following steps:

  1. Change hgweb/server.py temporarily to write a file if
 IPv6HTTPServer.__init__ is called.
  2. run-tests.py -l --keep-tmpdir test-serve.t
  3. Check the generated .hgrc, make sure it sets web.ipv6=1.
  4. Check the log file to make sure IPv6HTTPServer.__init__ is called.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -536,5 +536,6 @@ class Test(unittest.TestCase):
  startport=defaults['port'], extraconfigopts=None,
  py3kwarnings=False, shell=None, hgcommand=None,
- slowtimeout=defaults['slowtimeout'], usechg=False):
+ slowtimeout=defaults['slowtimeout'], usechg=False,
+ useipv6=False):
 """Create a test from parameters.
 
@@ -594,4 +595,9 @@ class Test(unittest.TestCase):
 self._chgsockdir = None
 
+# If IPv6 is used, set web.ipv6=1 in hgrc so servers will use IPv6
+if useipv6:
+self._extraconfigopts = list(self._extraconfigopts)
+self._extraconfigopts.append('web.ipv6 = True')
+
 # If we're not in --debug mode and reference output file exists,
 # check test output against it.
@@ -2318,5 +2324,6 @@ class TestRunner(object):
 shell=self.options.shell,
 hgcommand=self._hgcommand,
-usechg=bool(self.options.with_chg or self.options.chg))
+usechg=bool(self.options.with_chg or self.options.chg),
+useipv6=useipv6)
 t.should_reload = True
 return t
diff --git a/tests/test-basic.t b/tests/test-basic.t
--- a/tests/test-basic.t
+++ b/tests/test-basic.t
@@ -12,4 +12,5 @@ Create a repository:
   ui.mergemarkers=detailed
   ui.promptecho=True
+  web.ipv6=True (?)
   $ hg init t
   $ cd t
diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t
--- a/tests/test-commandserver.t
+++ b/tests/test-commandserver.t
@@ -200,4 +200,5 @@ check that local configs for the cached 
   ui.foo=bar
   ui.nontty=true
+  web.ipv6=True (?)
   *** runcommand init foo
   *** runcommand -R foo showconfig ui defaults
diff --git a/tests/test-config.t b/tests/test-config.t
--- a/tests/test-config.t
+++ b/tests/test-config.t
@@ -59,10 +59,10 @@ Test case sensitive configuration
{
 "name": "Section.KeY",
-"source": "*.hgrc:16", (glob)
+"source": "*.hgrc:*", (glob)
 "value": "Case Sensitive"
},
{
 "name": "Section.key",
-"source": "*.hgrc:17", (glob)
+"source": "*.hgrc:*", (glob)
 "value": "lower case"
}
@@ -72,5 +72,5 @@ Test case sensitive configuration
{
 "name": "Section.KeY",
-"source": "*.hgrc:16", (glob)
+"source": "*.hgrc:*", (glob)
 "value": "Case Sensitive"
}
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: help: I broke test-gendoc-ro.t and I have no idea how

2017-02-15 Thread Simon Farnsworth

On 16/02/2017 00:21, Augie Fackler wrote:

With my pager-modernization work applied, I've got one test failure that is 
blocking me from mailing:
augie% make test-gendoc-ro.t
cd tests && python run-tests.py -j16 test-gendoc-ro.t
--- /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t
+++ /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t.err
@@ -2,3 +2,5 @@

   $ $TESTDIR/check-gendoc ro
   checking for parse errors
+  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
start-string without end-string.
+  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
start-string without end-string.
ERROR: test-gendoc-ro.t output changed

This is caused by something I did in 
https://urldefense.proofpoint.com/v2/url?u=https-3A__hg.durin42.com_hg-2Dwip_rev_b7285db7c604&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mEgSWILcY4c4W3zjApBQLA&m=ChpAFOjlEYfm475yHPTI0tuFVtHpxkiVGexL5vsOh_I&s=-92RK09HMha8EYY79jfb7CRI0zekREVBhPPhmvIUYg0&e=
 , but I have no idea what. Can anyone help me figure out this last problem?



It looks to me like a consequence of moving pager into core, combined 
with a marginally iffy decision by the Romanian translator.


When pager is an extension, test-gendoc-ro.t will not test the Romanian 
translation of _("when to paginate (boolean, always, auto, or never)") - 
it's not in the source English text, so won't end up in the translated 
output.


You move _("when to paginate (boolean, always, auto, or never)") from 
pager.py to commands.py, which results in the source English text 
containing that phrase.


The Romanian translator has translated  _("when to paginate (boolean, 
always, auto, or never)") as "când să se pagineze (boolean, 
`always`=întotdeauna, auto, sau `never`=niciodată)". runrst then 
attempts to interpret `always`=întotdeauna and `never`=niciodată as 
references, and throws up this warning.


I can hunt round the office tomorrow for a friendly Romanian who can 
come up with a better way to indicate the relationship between the 
Romanian words and the English arguments - or you could decide to accept 
this warning for now until the Romanian translation is updated.

--
Simon Farnsworth
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: help: I broke test-gendoc-ro.t and I have no idea how

2017-02-15 Thread Augie Fackler

> On Feb 15, 2017, at 8:02 PM, Simon Farnsworth  wrote:
> 
> On 16/02/2017 00:21, Augie Fackler wrote:
>> With my pager-modernization work applied, I've got one test failure that is 
>> blocking me from mailing:
>> augie% make test-gendoc-ro.t
>> cd tests && python run-tests.py -j16 test-gendoc-ro.t
>> --- /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t
>> +++ 
>> /usr/local/google/home/augie/Programming/hg/crew/tests/test-gendoc-ro.t.err
>> @@ -2,3 +2,5 @@
>> 
>>   $ $TESTDIR/check-gendoc ro
>>   checking for parse errors
>> +  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
>> start-string without end-string.
>> +  gendoc.txt:55: (WARNING/2) Inline interpreted text or phrase reference 
>> start-string without end-string.
>> ERROR: test-gendoc-ro.t output changed
>> 
>> This is caused by something I did in 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__hg.durin42.com_hg-2Dwip_rev_b7285db7c604&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=mEgSWILcY4c4W3zjApBQLA&m=ChpAFOjlEYfm475yHPTI0tuFVtHpxkiVGexL5vsOh_I&s=-92RK09HMha8EYY79jfb7CRI0zekREVBhPPhmvIUYg0&e=
>>  , but I have no idea what. Can anyone help me figure out this last problem?
>> 
> 
> It looks to me like a consequence of moving pager into core, combined with a 
> marginally iffy decision by the Romanian translator.
> 
> When pager is an extension, test-gendoc-ro.t will not test the Romanian 
> translation of _("when to paginate (boolean, always, auto, or never)") - it's 
> not in the source English text, so won't end up in the translated output.
> 
> You move _("when to paginate (boolean, always, auto, or never)") from 
> pager.py to commands.py, which results in the source English text containing 
> that phrase.
> 
> The Romanian translator has translated  _("when to paginate (boolean, always, 
> auto, or never)") as "când să se pagineze (boolean, `always`=întotdeauna, 
> auto, sau `never`=niciodată)". runrst then attempts to interpret 
> `always`=întotdeauna and `never`=niciodată as references, and throws up this 
> warning.
> 
> I can hunt round the office tomorrow for a friendly Romanian who can come up 
> with a better way to indicate the relationship between the Romanian words and 
> the English arguments - or you could decide to accept this warning for now 
> until the Romanian translation is updated.

Neat. I’ll update the test for now with a note about what’s going on so I can 
mail this. Thanks!

> -- 
> Simon Farnsworth

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] minirst: dynamically compile admonitions regexp

2017-02-15 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1487188034 28800
#  Wed Feb 15 11:47:14 2017 -0800
# Node ID 197ba3e5885366038d453b9b22fa2910a0792988
# Parent  dd90d5f7dc1908d9b69e6a4b8165a73757d1c84b
minirst: dynamically compile admonitions regexp

Currently, parsing admonitions uses a static regular expression created
from a pre-defined list of admonitions. A future patch will introduce a
feature that needs to parse custom admonitions. Prepare for this by
compiling the admonitions regular expression during each function
invocation.

Strictly speaking, there is a slight performance loss here. But we only
run this code as part of displaying help text. I don't think the loss
will be noticeable and I don't think we care if it were.

diff --git a/mercurial/minirst.py b/mercurial/minirst.py
--- a/mercurial/minirst.py
+++ b/mercurial/minirst.py
@@ -411,18 +411,31 @@ def prunecomments(blocks):
 i += 1
 return blocks
 
-_admonitionre = re.compile(r"\.\. (admonition|attention|caution|danger|"
-   r"error|hint|important|note|tip|warning)::",
-   flags=re.IGNORECASE)
+
+_admonitions = set([
+'admonition',
+'attention',
+'caution',
+'danger',
+'error',
+'hint',
+'important',
+'note',
+'tip',
+'warning',
+])
 
 def findadmonitions(blocks):
 """
 Makes the type of the block an admonition block if
 the first line is an admonition directive
 """
+admonitionre = re.compile(r'\.\. (%s)::' % '|'.join(sorted(_admonitions)),
+  flags=re.IGNORECASE)
+
 i = 0
 while i < len(blocks):
-m = _admonitionre.match(blocks[i]['lines'][0])
+m = admonitionre.match(blocks[i]['lines'][0])
 if m:
 blocks[i]['type'] = 'admonition'
 admonitiontitle = blocks[i]['lines'][0][3:m.end() - 2].lower()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] minirst: detect bullet lists using asterisks

2017-02-15 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1487205737 28800
#  Wed Feb 15 16:42:17 2017 -0800
# Node ID dd90d5f7dc1908d9b69e6a4b8165a73757d1c84b
# Parent  afaf3c2b129c8940387fd9928ae4fdc28259d13c
minirst: detect bullet lists using asterisks

Previously, the "bullet" regular expression excluded the asterisk
('*') as a character denoting a bulleted list. Why I'm not sure
because the asterisk seems to be the canonical bullet character
in reST these days.

This patch makes asterisk-prefixed lines parse as bulleted lists.

diff --git a/mercurial/minirst.py b/mercurial/minirst.py
--- a/mercurial/minirst.py
+++ b/mercurial/minirst.py
@@ -138,7 +138,7 @@ def findliteralblocks(blocks):
 i += 1
 return blocks
 
-_bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
+_bulletre = re.compile(r'(\*|-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
 _optionre = re.compile(r'^(-([a-zA-Z0-9]), )?(--[a-z0-9-]+)'
r'((.*)  +)(.*)$')
 _fieldre = re.compile(r':(?![: ])([^:]*)(? This is the first line.   The line continues here.
   This is the second line.
 
+
+Bullet lists are also detected:
+
+
+  This is the first bullet
+  This is the second bullet   It has 2 lines
+  This is the third bullet
+
 --
 
 == options ==
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] [RFC] releasenotes: command to manage release notes files

2017-02-15 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1487210192 28800
#  Wed Feb 15 17:56:32 2017 -0800
# Node ID 9ab96e9d989c0b722ce0eedcb357e449c7bd5553
# Parent  9ab3ad4934aedc649d28f74dd70207c6c6e88596
[RFC] releasenotes: command to manage release notes files

Per discussion on the mailing list, we want better release notes
for Mercurial.

This patch introduces an extension that provides a command for
producing release notes files. Functionality is implemented
as an extension because it could be useful outside of the
Mercurial project and because there is some code (like rst
parsing) that already exists in Mercurial and it doesn't make
sense to reinvent the wheel.

The general idea with the extension is that changeset authors
declare release notes in commit messages using rst directives.
Periodically (such as at publishing or release time), a project
maintainer runs `hg releasenotes` to extract release notes
fragments from commit messages and format them to an auto-generated
release notes file. More details are explained inline in docstrings.

There are several things that need addressed before this is ready
for prime time:

* Moar tests
* Interactive merge mode
* Implement similarity detection for individual notes items
* Support customizing section names/titles
* Parsing improvements for bullet lists and paragraphs
* Document which rst primitives can be parsed
* Retain arbitrary content (e.g. header section/paragraphs)
  from existing release notes file
* Better error messages (line numbers, hints, etc)

diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py
new file mode 100644
--- /dev/null
+++ b/hgext/releasenotes.py
@@ -0,0 +1,435 @@
+# Copyright 2017-present Gregory Szorc 
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+"""generate release notes from commit messages (EXPERIMENTAL)
+
+It is common to maintain files detailing changes in a project between
+releases. Maintaining these files can be difficult and time consuming.
+The :hg:`releasenotes` command provided by this extension makes the
+process simpler by automating it.
+"""
+
+from __future__ import absolute_import
+
+import errno
+import re
+import sys
+import textwrap
+
+from mercurial.i18n import _
+from mercurial import (
+cmdutil,
+error,
+minirst,
+scmutil,
+)
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
+# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
+# be specifying the version(s) of Mercurial they are tested with, or
+# leave the attribute unspecified.
+testedwith = 'ships-with-hg-core'
+
+DEFAULT_SECTIONS = [
+('feature', _('New Features')),
+('bc', _('Backwards Compatibility Changes')),
+('fix', _('Bug Fixes')),
+('perf', _('Performance Improvements')),
+('api', _('API Changes')),
+]
+
+RE_DIRECTIVE = re.compile('^\.\. ([a-zA-Z0-9_]+)::\s*([^$]+)?$')
+
+BULLET_SECTION = _('Other Changes')
+
+class parsedreleasenotes(object):
+def __init__(self):
+self.sections = {}
+
+def __contains__(self, section):
+return section in self.sections
+
+def __iter__(self):
+return iter(sorted(self.sections))
+
+def addtitleditem(self, section, title, paragraphs):
+"""Add a titled release note entry."""
+self.sections.setdefault(section, ([], []))
+self.sections[section][0].append((title, paragraphs))
+
+def addnontitleditem(self, section, paragraphs):
+"""Adds a non-titled release note entry.
+
+Will be rendered as a bullet point.
+"""
+self.sections.setdefault(section, ([], []))
+self.sections[section][1].append(paragraphs)
+
+def titledforsection(self, section):
+"""Returns titled entries in a section.
+
+Returns a list of (title, paragraphs) tuples describing sub-sections.
+"""
+return self.sections.get(section, ([], []))[0]
+
+def nontitledforsection(self, section):
+"""Returns non-titled, bulleted paragraphs in a section."""
+return self.sections.get(section, ([], []))[1]
+
+def hastitledinsection(self, section, title):
+return any(t[0] == title for t in self.titledforsection(section))
+
+def merge(self, ui, other):
+"""Merge another instance into this one.
+
+This is used to combine multiple sources of release notes together.
+"""
+for section in other:
+for title, paragraphs in other.titledforsection(section):
+if self.hastitledinsection(section, title):
+# TODO prompt for resolution if different and running in
+# interactive mode.
+ui.write('%s already exists in %s section; ignoring\n' %
+ (title, section))
+continue
+
+# TODO perfo

[PATCH 3 of 4] minirst: support passing admonitions into findadmonitions() and parse()

2017-02-15 Thread Gregory Szorc
# HG changeset patch
# User Gregory Szorc 
# Date 1487188152 28800
#  Wed Feb 15 11:49:12 2017 -0800
# Node ID 9ab3ad4934aedc649d28f74dd70207c6c6e88596
# Parent  197ba3e5885366038d453b9b22fa2910a0792988
minirst: support passing admonitions into findadmonitions() and parse()

This will allow consumers to declare a custom list of admonitions
to parse. Without this patch, custom admonitions would get removed
when prunecomments() is run. We could add an argument controlling
whether prunecomments() is run. However, it is better to convert
the "paragraph" block to an "admonition" block so consumers don't
have to parse for custom admonitions.

diff --git a/mercurial/minirst.py b/mercurial/minirst.py
--- a/mercurial/minirst.py
+++ b/mercurial/minirst.py
@@ -425,12 +425,14 @@ def prunecomments(blocks):
 'warning',
 ])
 
-def findadmonitions(blocks):
+def findadmonitions(blocks, admonitions=None):
 """
 Makes the type of the block an admonition block if
 the first line is an admonition directive
 """
-admonitionre = re.compile(r'\.\. (%s)::' % '|'.join(sorted(_admonitions)),
+admonitions = admonitions or _admonitions
+
+admonitionre = re.compile(r'\.\. (%s)::' % '|'.join(sorted(admonitions)),
   flags=re.IGNORECASE)
 
 i = 0
@@ -642,7 +644,7 @@ def formathtml(blocks):
 
 return ''.join(out)
 
-def parse(text, indent=0, keep=None):
+def parse(text, indent=0, keep=None, admonitions=None):
 """Parse text into a list of blocks"""
 pruned = []
 blocks = findblocks(text)
@@ -657,7 +659,7 @@ def parse(text, indent=0, keep=None):
 blocks = splitparagraphs(blocks)
 blocks = updatefieldlists(blocks)
 blocks = updateoptionlists(blocks)
-blocks = findadmonitions(blocks)
+blocks = findadmonitions(blocks, admonitions=admonitions)
 blocks = addmargins(blocks)
 blocks = prunecomments(blocks)
 return blocks, pruned
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 4] [RFC] releasenotes: command to manage release notes files

2017-02-15 Thread Gregory Szorc
On Wed, Feb 15, 2017 at 5:59 PM, Gregory Szorc 
wrote:

> # HG changeset patch
> # User Gregory Szorc 
> # Date 1487210192 28800
> #  Wed Feb 15 17:56:32 2017 -0800
> # Node ID 9ab96e9d989c0b722ce0eedcb357e449c7bd5553
> # Parent  9ab3ad4934aedc649d28f74dd70207c6c6e88596
> [RFC] releasenotes: command to manage release notes files
>

I think this extension/command addresses the feedback and concerns people
had with the previous RFC approach (which was a simple script). The
approach in this commit is much more robust. It still isn't complete. But
at least you should be able to see where I'm going and how I intend to
solve problems like preserving changes to the release notes file made
outside of commit messages.

The previous 3 minirst patches are needed to make this extension work. The
bullet list change can stand on its own and can be queued if a reviewer
finds it appropriate. The 2 for admonitions parsing are only needed if we
want to move forward with the approach in this extension.

I'll be AFK for the next several days (possibly a week or two) and won't
have time to iterate on this. If someone else wants to pick it up and try
to get it queued, go for it!


>
> Per discussion on the mailing list, we want better release notes
> for Mercurial.
>
> This patch introduces an extension that provides a command for
> producing release notes files. Functionality is implemented
> as an extension because it could be useful outside of the
> Mercurial project and because there is some code (like rst
> parsing) that already exists in Mercurial and it doesn't make
> sense to reinvent the wheel.
>
> The general idea with the extension is that changeset authors
> declare release notes in commit messages using rst directives.
> Periodically (such as at publishing or release time), a project
> maintainer runs `hg releasenotes` to extract release notes
> fragments from commit messages and format them to an auto-generated
> release notes file. More details are explained inline in docstrings.
>
> There are several things that need addressed before this is ready
> for prime time:
>
> * Moar tests
> * Interactive merge mode
> * Implement similarity detection for individual notes items
> * Support customizing section names/titles
> * Parsing improvements for bullet lists and paragraphs
> * Document which rst primitives can be parsed
> * Retain arbitrary content (e.g. header section/paragraphs)
>   from existing release notes file
> * Better error messages (line numbers, hints, etc)
>
> diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py
> new file mode 100644
> --- /dev/null
> +++ b/hgext/releasenotes.py
> @@ -0,0 +1,435 @@
> +# Copyright 2017-present Gregory Szorc 
> +#
> +# This software may be used and distributed according to the terms of the
> +# GNU General Public License version 2 or any later version.
> +
> +"""generate release notes from commit messages (EXPERIMENTAL)
> +
> +It is common to maintain files detailing changes in a project between
> +releases. Maintaining these files can be difficult and time consuming.
> +The :hg:`releasenotes` command provided by this extension makes the
> +process simpler by automating it.
> +"""
> +
> +from __future__ import absolute_import
> +
> +import errno
> +import re
> +import sys
> +import textwrap
> +
> +from mercurial.i18n import _
> +from mercurial import (
> +cmdutil,
> +error,
> +minirst,
> +scmutil,
> +)
> +
> +cmdtable = {}
> +command = cmdutil.command(cmdtable)
> +
> +# Note for extension authors: ONLY specify testedwith =
> 'ships-with-hg-core' for
> +# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
> +# be specifying the version(s) of Mercurial they are tested with, or
> +# leave the attribute unspecified.
> +testedwith = 'ships-with-hg-core'
> +
> +DEFAULT_SECTIONS = [
> +('feature', _('New Features')),
> +('bc', _('Backwards Compatibility Changes')),
> +('fix', _('Bug Fixes')),
> +('perf', _('Performance Improvements')),
> +('api', _('API Changes')),
> +]
> +
> +RE_DIRECTIVE = re.compile('^\.\. ([a-zA-Z0-9_]+)::\s*([^$]+)?$')
> +
> +BULLET_SECTION = _('Other Changes')
> +
> +class parsedreleasenotes(object):
> +def __init__(self):
> +self.sections = {}
> +
> +def __contains__(self, section):
> +return section in self.sections
> +
> +def __iter__(self):
> +return iter(sorted(self.sections))
> +
> +def addtitleditem(self, section, title, paragraphs):
> +"""Add a titled release note entry."""
> +self.sections.setdefault(section, ([], []))
> +self.sections[section][0].append((title, paragraphs))
> +
> +def addnontitleditem(self, section, paragraphs):
> +"""Adds a non-titled release note entry.
> +
> +Will be rendered as a bullet point.
> +"""
> +self.sections.setdefault(section, ([], []))
> +self.sections[section][1].append(paragraphs)
> +
> +def titledforsection(self, section):
> +"""R

[PATCH 5 of 9 pager] tests: clean up a bunch of pager testing that is about to be invalidated

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486442730 18000
#  Mon Feb 06 23:45:30 2017 -0500
# Node ID 78410f8a924623287609eacf70bd4912b17a01bf
# Parent  1a671cd4d4aff343040e7764fcc4402725fb5a0d
tests: clean up a bunch of pager testing that is about to be invalidated

All this attend logic and potential bugs just no longer make sense to test.

diff --git a/tests/test-pager.t b/tests/test-pager.t
--- a/tests/test-pager.t
+++ b/tests/test-pager.t
@@ -58,7 +58,8 @@ We can enable the pager on id:
   $ hg --config pager.attend-id=yes id
   paged! '46106edeeb38 tip\n'
 
-If we completely change the attend list that's respected:
+Setting attend-$COMMAND to a false value works, even with pager in
+core:
 
   $ hg --config pager.attend-diff=no diff -c 2
   diff -r f4be7687d414 -r bce265549556 a
@@ -69,15 +70,6 @@ If we completely change the attend list 
a 1
   +a 2
 
-  $ hg --config pager.attend=summary diff -c 2
-  diff -r f4be7687d414 -r bce265549556 a
-  --- a/a  Thu Jan 01 00:00:00 1970 +
-  +++ b/a  Thu Jan 01 00:00:00 1970 +
-  @@ -1,2 +1,3 @@
-   a
-   a 1
-  +a 2
-
 If 'log' is in attend, then 'history' should also be paged:
   $ hg history --limit 2 --config pager.attend=log
   paged! 'changeset:   10:46106edeeb38\n'
@@ -92,56 +84,6 @@ If 'log' is in attend, then 'history' sh
   paged! 'summary: modify a 9\n'
   paged! '\n'
 
-Possible bug: history is explicitly ignored in pager config, but
-because log is in the attend list it still gets pager treatment.
-
-  $ hg history --limit 2 --config pager.attend=log \
-  >   --config pager.ignore=history
-  paged! 'changeset:   10:46106edeeb38\n'
-  paged! 'tag: tip\n'
-  paged! 'user:test\n'
-  paged! 'date:Thu Jan 01 00:00:00 1970 +\n'
-  paged! 'summary: modify a 10\n'
-  paged! '\n'
-  paged! 'changeset:   9:6dd8ea7dd621\n'
-  paged! 'user:test\n'
-  paged! 'date:Thu Jan 01 00:00:00 1970 +\n'
-  paged! 'summary: modify a 9\n'
-  paged! '\n'
-
-Possible bug: history is explicitly marked as attend-history=no, but
-it doesn't fail to get paged because log is still in the attend list.
-
-  $ hg history --limit 2 --config pager.attend-history=no
-  paged! 'changeset:   10:46106edeeb38\n'
-  paged! 'tag: tip\n'
-  paged! 'user:test\n'
-  paged! 'date:Thu Jan 01 00:00:00 1970 +\n'
-  paged! 'summary: modify a 10\n'
-  paged! '\n'
-  paged! 'changeset:   9:6dd8ea7dd621\n'
-  paged! 'user:test\n'
-  paged! 'date:Thu Jan 01 00:00:00 1970 +\n'
-  paged! 'summary: modify a 9\n'
-  paged! '\n'
-
-Possible bug: disabling pager for log but enabling it for history
-doesn't result in history being paged.
-
-  $ hg history --limit 2 --config pager.attend-log=no \
-  > --config pager.attend-history=yes
-  changeset:   10:46106edeeb38
-  tag: tip
-  user:test
-  date:Thu Jan 01 00:00:00 1970 +
-  summary: modify a 10
-  
-  changeset:   9:6dd8ea7dd621
-  user:test
-  date:Thu Jan 01 00:00:00 1970 +
-  summary: modify a 9
-  
-
 Pager should not start if stdout is not a tty.
 
   $ hg log -l1 -q --config ui.formatted=False
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 9 pager] pager: move more behavior into core

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1487198877 18000
#  Wed Feb 15 17:47:57 2017 -0500
# Node ID cafe46e7d79c59567edc185979cf6568367def93
# Parent  675643abfdb6adbdfd8bddfbc263701c9caca539
pager: move more behavior into core

This moves the global flag and the --pager=yes logic into core. Only
functionality change is that users now always get a --pager flag and
can enable the pager via the flag without the extension active.

Moving the flag into core exposes a defect in the ro localization,
which will have to be corrected later.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -60,13 +60,11 @@ you can use --pager=::
 '''
 from __future__ import absolute_import
 
-from mercurial.i18n import _
 from mercurial import (
 cmdutil,
 commands,
 dispatch,
 extensions,
-util,
 )
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
@@ -78,15 +76,9 @@ testedwith = 'ships-with-hg-core'
 def uisetup(ui):
 
 def pagecmd(orig, ui, options, cmd, cmdfunc):
-usepager = False
-always = util.parsebool(options['pager'])
 auto = options['pager'] == 'auto'
-
-if always:
-usepager = True
-elif not auto:
+if auto and not ui.pageractive:
 usepager = False
-else:
 attend = ui.configlist('pager', 'attend', attended)
 ignore = ui.configlist('pager', 'ignore')
 cmds, _ = cmdutil.findcmd(cmd, commands.table)
@@ -101,8 +93,8 @@ def uisetup(ui):
 usepager = True
 break
 
-if usepager:
-ui.pager('extension-via-attend-' + cmd)
+if usepager:
+ui.pager('extension-via-attend-' + cmd)
 return orig(ui, options, cmd, cmdfunc)
 
 # Wrap dispatch._runcommand after color is loaded so color can see
@@ -112,10 +104,4 @@ def uisetup(ui):
 extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
 extensions.afterloaded('color', afterloaded)
 
-def extsetup(ui):
-commands.globalopts.append(
-('', 'pager', 'auto',
- _("when to paginate (boolean, always, auto, or never)"),
- _('TYPE')))
-
 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -93,6 +93,8 @@ globalopts = [
 ('', 'version', None, _('output version information and exit')),
 ('h', 'help', None, _('display help and exit')),
 ('', 'hidden', False, _('consider hidden changesets')),
+('', 'pager', 'auto',
+ _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
 ]
 
 dryrunopts = [('n', 'dry-run', None,
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -816,6 +816,8 @@ def _dispatch(req):
 
 def _runcommand(ui, options, cmd, cmdfunc):
 """Run a command function, possibly with profiling enabled."""
+if util.parsebool(options['pager']):
+ui.pager('internal-always-' + cmd)
 try:
 return cmdfunc()
 except error.SignatureError:
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -138,6 +138,7 @@ Show the global options
   --help
   --hidden
   --noninteractive
+  --pager
   --profile
   --quiet
   --repository
@@ -171,6 +172,7 @@ Show the options for the "serve" command
   --ipv6
   --name
   --noninteractive
+  --pager
   --pid-file
   --port
   --prefix
diff --git a/tests/test-extension.t b/tests/test-extension.t
--- a/tests/test-extension.t
+++ b/tests/test-extension.t
@@ -543,6 +543,8 @@ hide outer repo
   --version   output version information and exit
-h --help  display help and exit
   --hiddenconsider hidden changesets
+  --pager TYPEwhen to paginate (boolean, always, auto, or never)
+  (default: auto)
 
 
 
@@ -578,6 +580,8 @@ hide outer repo
   --version   output version information and exit
-h --help  display help and exit
   --hiddenconsider hidden changesets
+  --pager TYPEwhen to paginate (boolean, always, auto, or never)
+  (default: auto)
 
 
 
@@ -856,6 +860,8 @@ extension help itself
   --version   output version information and exit
-h --help  display help and exit
   --hiddenconsider hidden changesets
+  --pager TYPEwhen to paginate (boolean, always, auto, or never)
+  (default: auto)
 
 Make sure that single '-v' option shows help and built-ins only for 'dodo' 
command
   $ hg help -v dodo
@@ -889,6 +895,8 @@ Make sure that single '-v' option shows 
   --version   output version information and exit
-h --help  

[PATCH 4 of 9 pager] ui: add ignore-single-command functionality

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486441305 18000
#  Mon Feb 06 23:21:45 2017 -0500
# Node ID 1a671cd4d4aff343040e7764fcc4402725fb5a0d
# Parent  8695f290ba7c1a7f6c1b93ba344fbbe1193ab1a5
ui: add ignore-single-command functionality

This closes the last feature gap other than the attend list from the
extension. For now, I'm leaving the attend list in the extension,
because I'm unsure it has merit in a world where commands have been
updated to take advantage of the modern API.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -94,6 +94,12 @@ def uisetup(ui):
 break
 
 if usepager:
+# Slight hack: the attend list is supposed to override
+# the ignore list for the pager extension, but the
+# core code doesn't know about attend, so we have to
+# lobotomize the ignore list so that the extension's
+# behavior is preserved.
+ui.setconfig('pager', 'ignore', '', 'pager')
 ui.pager('extension-via-attend-' + cmd)
 return orig(ui, options, cmd, cmdfunc)
 
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -817,6 +817,7 @@ class ui(object):
 """
 if (self._neverpager
 or self.pageractive
+or command in self.configlist('pager', 'ignore')
 # TODO: if we want to allow HGPLAINEXCEPT=pager,
 # formatted() will need some adjustment.
 or not self.formatted()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9 pager] pager: move pager-initiating code into core

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1487198871 18000
#  Wed Feb 15 17:47:51 2017 -0500
# Node ID 675643abfdb6adbdfd8bddfbc263701c9caca539
# Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
pager: move pager-initiating code into core

No functionality change.

A previous version of this API had a category argument on
ui.pager(). As I migrated the commands in core, I couldn't come up
with good enough consistency in any categorization scheme so I just
scrapped the whole idea. It may be worth revisiting in the future.

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -60,19 +60,11 @@ you can use --pager=::
 '''
 from __future__ import absolute_import
 
-import atexit
-import os
-import signal
-import subprocess
-import sys
-
 from mercurial.i18n import _
 from mercurial import (
 cmdutil,
 commands,
 dispatch,
-encoding,
-error,
 extensions,
 util,
 )
@@ -83,48 +75,14 @@ from mercurial import (
 # leave the attribute unspecified.
 testedwith = 'ships-with-hg-core'
 
-def _runpager(ui, p):
-pager = subprocess.Popen(p, shell=True, bufsize=-1,
- close_fds=util.closefds, stdin=subprocess.PIPE,
- stdout=util.stdout, stderr=util.stderr)
-
-# back up original file descriptors
-stdoutfd = os.dup(util.stdout.fileno())
-stderrfd = os.dup(util.stderr.fileno())
-
-os.dup2(pager.stdin.fileno(), util.stdout.fileno())
-if ui._isatty(util.stderr):
-os.dup2(pager.stdin.fileno(), util.stderr.fileno())
-
-@atexit.register
-def killpager():
-if util.safehasattr(signal, "SIGINT"):
-signal.signal(signal.SIGINT, signal.SIG_IGN)
-# restore original fds, closing pager.stdin copies in the process
-os.dup2(stdoutfd, util.stdout.fileno())
-os.dup2(stderrfd, util.stderr.fileno())
-pager.stdin.close()
-pager.wait()
-
-def catchterm(*args):
-raise error.SignalInterrupt
-
 def uisetup(ui):
-class pagerui(ui.__class__):
-def _runpager(self, pagercmd):
-_runpager(self, pagercmd)
-
-ui.__class__ = pagerui
 
 def pagecmd(orig, ui, options, cmd, cmdfunc):
-p = ui.config("pager", "pager", encoding.environ.get("PAGER"))
 usepager = False
 always = util.parsebool(options['pager'])
 auto = options['pager'] == 'auto'
 
-if not p or '--debugger' in sys.argv or not ui.formatted():
-pass
-elif always:
+if always:
 usepager = True
 elif not auto:
 usepager = False
@@ -143,14 +101,8 @@ def uisetup(ui):
 usepager = True
 break
 
-setattr(ui, 'pageractive', usepager)
-
 if usepager:
-ui.setconfig('ui', 'formatted', ui.formatted(), 'pager')
-ui.setconfig('ui', 'interactive', False, 'pager')
-if util.safehasattr(signal, "SIGPIPE"):
-signal.signal(signal.SIGPIPE, catchterm)
-ui._runpager(p)
+ui.pager('extension-via-attend-' + cmd)
 return orig(ui, options, cmd, cmdfunc)
 
 # Wrap dispatch._runcommand after color is loaded so color can see
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -7,13 +7,16 @@
 
 from __future__ import absolute_import
 
+import atexit
 import contextlib
 import errno
 import getpass
 import inspect
 import os
 import re
+import signal
 import socket
+import subprocess
 import sys
 import tempfile
 import traceback
@@ -143,6 +146,7 @@ class ui(object):
 self.fout = src.fout
 self.ferr = src.ferr
 self.fin = src.fin
+self.pageractive = src.pageractive
 
 self._tcfg = src._tcfg.copy()
 self._ucfg = src._ucfg.copy()
@@ -159,6 +163,7 @@ class ui(object):
 self.fout = util.stdout
 self.ferr = util.stderr
 self.fin = util.stdin
+self.pageractive = False
 
 # shared read-only environment
 self.environ = encoding.environ
@@ -792,6 +797,75 @@ class ui(object):
 return False
 return util.isatty(fh)
 
+def pager(self, command):
+"""Start a pager for subsequent command output.
+
+Commands which produce a long stream of output should call
+this function to activate the user's preferred pagination
+mechanism (which may be no pager). Calling this function
+precludes any future use of interactive functionality, such as
+prompting the user or activating curses.
+
+Args:
+  command: The full, non-aliased name of the command. That is, "log"
+   not "history, "summary" not "summ", etc.
+"""
+if (self.pageractive
+# TODO: if we want to allow HGPLAINEXCEPT=pager,
+# formatted() will need some adjustment.
+  

[PATCH 9 of 9 pager] tests: prove that ignore works

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486441324 18000
#  Mon Feb 06 23:22:04 2017 -0500
# Node ID bce80a4789de7a273102a5e61a0ad6b13e8cbef8
# Parent  074b3f1ed66b41062e809eeabd4eb05b5554c680
tests: prove that ignore works

diff --git a/tests/test-pager.t b/tests/test-pager.t
--- a/tests/test-pager.t
+++ b/tests/test-pager.t
@@ -204,3 +204,21 @@ explicit flags work too:
8: a 8
9: a 9
   10: a 10
+
+Put annotate in the ignore list for pager:
+  $ cat >> $HGRCPATH < [pager]
+  > ignore = annotate
+  > EOF
+  $ hg blame a
+   0: a
+   1: a 1
+   2: a 2
+   3: a 3
+   4: a 4
+   5: a 5
+   6: a 6
+   7: a 7
+   8: a 8
+   9: a 9
+  10: a 10
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 9 pager] annotate: migrate to modern pager API

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486439567 18000
#  Mon Feb 06 22:52:47 2017 -0500
# Node ID 074b3f1ed66b41062e809eeabd4eb05b5554c680
# Parent  277dab1428ca0e37b649b9cd980b1467cdfc85d0
annotate: migrate to modern pager API

diff --git a/hgext/pager.py b/hgext/pager.py
--- a/hgext/pager.py
+++ b/hgext/pager.py
@@ -110,4 +110,4 @@ def uisetup(ui):
 extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
 extensions.afterloaded('color', afterloaded)
 
-attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
+attended = ['cat', 'diff', 'export', 'glog', 'log', 'qdiff']
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -361,6 +361,7 @@ def annotate(ui, repo, *pats, **opts):
 
 Returns 0 on success.
 """
+ui.pager('annotate')
 if not pats:
 raise error.Abort(_('at least one filename or pattern is required'))
 
diff --git a/tests/test-pager.t b/tests/test-pager.t
--- a/tests/test-pager.t
+++ b/tests/test-pager.t
@@ -164,3 +164,43 @@ Pager should not override the exit code 
   $ hg fortytwo --pager=on
   paged! '42\n'
   [42]
+
+A command that asks for paging using ui.pager() directly works:
+  $ hg blame a
+  paged! ' 0: a\n'
+  paged! ' 1: a 1\n'
+  paged! ' 2: a 2\n'
+  paged! ' 3: a 3\n'
+  paged! ' 4: a 4\n'
+  paged! ' 5: a 5\n'
+  paged! ' 6: a 6\n'
+  paged! ' 7: a 7\n'
+  paged! ' 8: a 8\n'
+  paged! ' 9: a 9\n'
+  paged! '10: a 10\n'
+but not with HGPLAIN
+  $ HGPLAIN=1 hg blame a
+   0: a
+   1: a 1
+   2: a 2
+   3: a 3
+   4: a 4
+   5: a 5
+   6: a 6
+   7: a 7
+   8: a 8
+   9: a 9
+  10: a 10
+explicit flags work too:
+  $ hg blame --pager=no a
+   0: a
+   1: a 1
+   2: a 2
+   3: a 3
+   4: a 4
+   5: a 5
+   6: a 6
+   7: a 7
+   8: a 8
+   9: a 9
+  10: a 10
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 9 pager] ui: respect historic pager.attend-$COMMAND=no

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486442524 18000
#  Mon Feb 06 23:42:04 2017 -0500
# Node ID cfa569ed77883c41aecb3eaaa42876a5b0b7c52a
# Parent  78410f8a924623287609eacf70bd4912b17a01bf
ui: respect historic pager.attend-$COMMAND=no

I'm on the fence about this behavior, but the user's intent was pretty
specific and it's not expensive to support this case.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -818,6 +818,7 @@ class ui(object):
 if (self._neverpager
 or self.pageractive
 or command in self.configlist('pager', 'ignore')
+or not self.configbool('pager', 'attend-' + command, True)
 # TODO: if we want to allow HGPLAINEXCEPT=pager,
 # formatted() will need some adjustment.
 or not self.formatted()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9 pager] ui: introduce neverpager() call

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1487198883 18000
#  Wed Feb 15 17:48:03 2017 -0500
# Node ID 8695f290ba7c1a7f6c1b93ba344fbbe1193ab1a5
# Parent  cafe46e7d79c59567edc185979cf6568367def93
ui: introduce neverpager() call

I'm about to add direct paging support to some commands, and as a
result we need a way to communicate from the higher layers of dispatch
that paging is explicitly disabled.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -746,6 +746,9 @@ def _dispatch(req):
 for ui_ in uis:
 ui_.setconfig('ui', 'interactive', 'off', '-y')
 
+if options['pager'] != 'auto' and not util.parsebool(options['pager']):
+ui.neverpager()
+
 if cmdoptions.get('insecure', False):
 for ui_ in uis:
 ui_.insecureconnections = True
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -147,6 +147,7 @@ class ui(object):
 self.ferr = src.ferr
 self.fin = src.fin
 self.pageractive = src.pageractive
+self._neverpager = src._neverpager
 
 self._tcfg = src._tcfg.copy()
 self._ucfg = src._ucfg.copy()
@@ -164,6 +165,7 @@ class ui(object):
 self.ferr = util.stderr
 self.fin = util.stdin
 self.pageractive = False
+self._neverpager = False
 
 # shared read-only environment
 self.environ = encoding.environ
@@ -797,6 +799,9 @@ class ui(object):
 return False
 return util.isatty(fh)
 
+def neverpager(self):
+self._neverpager = True
+
 def pager(self, command):
 """Start a pager for subsequent command output.
 
@@ -810,7 +815,8 @@ class ui(object):
   command: The full, non-aliased name of the command. That is, "log"
not "history, "summary" not "summ", etc.
 """
-if (self.pageractive
+if (self._neverpager
+or self.pageractive
 # TODO: if we want to allow HGPLAINEXCEPT=pager,
 # formatted() will need some adjustment.
 or not self.formatted()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9 pager] ui: add a debug print right before we start the pager

2017-02-15 Thread Augie Fackler
# HG changeset patch
# User Augie Fackler 
# Date 1486443354 18000
#  Mon Feb 06 23:55:54 2017 -0500
# Node ID 277dab1428ca0e37b649b9cd980b1467cdfc85d0
# Parent  cfa569ed77883c41aecb3eaaa42876a5b0b7c52a
ui: add a debug print right before we start the pager

This makes it easier to figure out why a command is getting paginated.

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -829,6 +829,7 @@ class ui(object):
 # interactive, the user didn't say HGPLAIN or
 # HGPLAINEXCEPT=pager, and the user didn't specify --debug.
 return
+self.debug('starting pager for command %r\n' % command)
 
 # TODO: add a "system defaults" config section so this default
 # of more(1) can be easily replaced with a global
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 9 pager] pager: move pager-initiating code into core

2017-02-15 Thread Augie Fackler

> On Feb 15, 2017, at 9:12 PM, Augie Fackler  wrote:
> 
> # HG changeset patch
> # User Augie Fackler 
> # Date 1487198871 18000
> #  Wed Feb 15 17:47:51 2017 -0500
> # Node ID 675643abfdb6adbdfd8bddfbc263701c9caca539
> # Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
> pager: move pager-initiating code into core

These 9 patches represent most of the functionally interesting bits of my 
pager-in-core series. The rest of the stack is visible at 
https://hg.durin42.com/hg-wip/graph/pager - the majority of the patches beyond 
this point are one-line “turn on pager” commits. I expect to send the remaining 
21 patches in two batches: one wave of 19 trivial “turn it on” patches, and 
then 2 patches that rearrange some docs and mark the pager extension as 
deprecated.

> 
> No functionality change.
> 
> A previous version of this API had a category argument on
> ui.pager(). As I migrated the commands in core, I couldn't come up
> with good enough consistency in any categorization scheme so I just
> scrapped the whole idea. It may be worth revisiting in the future.
> 
> diff --git a/hgext/pager.py b/hgext/pager.py
> --- a/hgext/pager.py
> +++ b/hgext/pager.py
> @@ -60,19 +60,11 @@ you can use --pager=::
> '''
> from __future__ import absolute_import
> 
> -import atexit
> -import os
> -import signal
> -import subprocess
> -import sys
> -
> from mercurial.i18n import _
> from mercurial import (
> cmdutil,
> commands,
> dispatch,
> -encoding,
> -error,
> extensions,
> util,
> )
> @@ -83,48 +75,14 @@ from mercurial import (
> # leave the attribute unspecified.
> testedwith = 'ships-with-hg-core'
> 
> -def _runpager(ui, p):
> -pager = subprocess.Popen(p, shell=True, bufsize=-1,
> - close_fds=util.closefds, stdin=subprocess.PIPE,
> - stdout=util.stdout, stderr=util.stderr)
> -
> -# back up original file descriptors
> -stdoutfd = os.dup(util.stdout.fileno())
> -stderrfd = os.dup(util.stderr.fileno())
> -
> -os.dup2(pager.stdin.fileno(), util.stdout.fileno())
> -if ui._isatty(util.stderr):
> -os.dup2(pager.stdin.fileno(), util.stderr.fileno())
> -
> -@atexit.register
> -def killpager():
> -if util.safehasattr(signal, "SIGINT"):
> -signal.signal(signal.SIGINT, signal.SIG_IGN)
> -# restore original fds, closing pager.stdin copies in the process
> -os.dup2(stdoutfd, util.stdout.fileno())
> -os.dup2(stderrfd, util.stderr.fileno())
> -pager.stdin.close()
> -pager.wait()
> -
> -def catchterm(*args):
> -raise error.SignalInterrupt
> -
> def uisetup(ui):
> -class pagerui(ui.__class__):
> -def _runpager(self, pagercmd):
> -_runpager(self, pagercmd)
> -
> -ui.__class__ = pagerui
> 
> def pagecmd(orig, ui, options, cmd, cmdfunc):
> -p = ui.config("pager", "pager", encoding.environ.get("PAGER"))
> usepager = False
> always = util.parsebool(options['pager'])
> auto = options['pager'] == 'auto'
> 
> -if not p or '--debugger' in sys.argv or not ui.formatted():
> -pass
> -elif always:
> +if always:
> usepager = True
> elif not auto:
> usepager = False
> @@ -143,14 +101,8 @@ def uisetup(ui):
> usepager = True
> break
> 
> -setattr(ui, 'pageractive', usepager)
> -
> if usepager:
> -ui.setconfig('ui', 'formatted', ui.formatted(), 'pager')
> -ui.setconfig('ui', 'interactive', False, 'pager')
> -if util.safehasattr(signal, "SIGPIPE"):
> -signal.signal(signal.SIGPIPE, catchterm)
> -ui._runpager(p)
> +ui.pager('extension-via-attend-' + cmd)
> return orig(ui, options, cmd, cmdfunc)
> 
> # Wrap dispatch._runcommand after color is loaded so color can see
> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -7,13 +7,16 @@
> 
> from __future__ import absolute_import
> 
> +import atexit
> import contextlib
> import errno
> import getpass
> import inspect
> import os
> import re
> +import signal
> import socket
> +import subprocess
> import sys
> import tempfile
> import traceback
> @@ -143,6 +146,7 @@ class ui(object):
> self.fout = src.fout
> self.ferr = src.ferr
> self.fin = src.fin
> +self.pageractive = src.pageractive
> 
> self._tcfg = src._tcfg.copy()
> self._ucfg = src._ucfg.copy()
> @@ -159,6 +163,7 @@ class ui(object):
> self.fout = util.stdout
> self.ferr = util.stderr
> self.fin = util.stdin
> +self.pageractive = False
> 
> # shared read-only environment
> self.environ = encoding.environ
> @@ -792,6 +797,75 @@ class ui(object):
> return False
> return util.isatty(f

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Augie Fackler
On Wed, Feb 15, 2017 at 04:50:14PM -0800, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu 
> # Date 1487204311 28800
> #  Wed Feb 15 16:18:31 2017 -0800
> # Node ID a70fa1e0fcdb11980338d72dde33dfe047bda7c2
> # Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
> a70fa1e0fcdb
> runtests: add a function to test if IPv6 is available
>
> Previously, checkportisavailable returns True if the port is free either on
> IPv4 or IPv6, but the hg server only uses IPv4 by default. That leads to
> issues when IPv4 port is not free but the IPv6 one is.
>
> To address that, run-tests should stick with either IPv4 or IPv6. This patch
> adds a function similar to checkportisavailable to test if IPv6 is
> available, and assigns the result to a variable.
>
> The new function was tested in a Linux system script with the following
> steps:
>
>   1. Run "ip addr del ::1/128 dev lo" to delete lo's IPv6 address,
>  Confirm checkipv6available() returns False.
>   2. Run "ip addr add ::1/128 dev lo" to add back lo's IPv6 address.
>  Confirm checkipv6available() returns True.
>   3. Start a web server taking the 8000 port.
>  Confirm checkipv6available(8000) is still True.
>
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -113,4 +113,27 @@ else:
>  wifexited = getattr(os, "WIFEXITED", lambda x: False)
>
> +# Whether to use IPv6
> +def checkipv6available(port=20058):
> +"""return true if we can listen on localhost's IPv6 ports"""
> +family = getattr(socket, 'AF_INET6', None)
> +if family is None:
> +return False
> +try:
> +s = socket.socket(family, socket.SOCK_STREAM)
> +s.bind(('localhost', port))
> +s.close()
> +return True
> +except socket.error as exc:
> +if exc.errno == errno.EADDRINUSE:
> +return True
> +elif exc.errno in (errno.EADDRNOTAVAIL, errno.EPROTONOSUPPORT):
> +return False
> +else:
> +raise
> +else:
> +return False
> +
> +useipv6 = checkipv6available()

I'm not overjoyed at the static default. Is there a reason to use the
static default instead of checking HGPORT, so that multiple users on a
single box (such as the big compile farm machine several of us favor)
can run the tests without risk of stomping each other?

> +
>  def checkportisavailable(port):
>  """return true if a port seems free to bind on localhost"""
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 4] runtests: unindent an "if True" block

2017-02-15 Thread Augie Fackler
On Wed, Feb 15, 2017 at 04:50:17PM -0800, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu 
> # Date 1487204998 28800
> #  Wed Feb 15 16:29:58 2017 -0800
> # Node ID c5bdb942d324dcd732d277457d11eff7dc6aacc3
> # Parent  bacc5256a49b34d07616c1e60e119a74ac721b7a
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
> c5bdb942d324
> runtests: unindent an "if True" block

Series looks fine, other than patch 1.

>
> The block was left to make review easier. This patch unindents it.
>
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -142,14 +142,13 @@ def checkportisavailable(port):
>  else:
>  family = socket.AF_INET
> -if True:
> -try:
> -s = socket.socket(family, socket.SOCK_STREAM)
> -s.bind(('localhost', port))
> -s.close()
> -return True
> -except socket.error as exc:
> -if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
> - errno.EPROTONOSUPPORT):
> -raise
> +try:
> +s = socket.socket(family, socket.SOCK_STREAM)
> +s.bind(('localhost', port))
> +s.close()
> +return True
> +except socket.error as exc:
> +if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
> + errno.EPROTONOSUPPORT):
> +raise
>  return False
>
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Jun Wu
Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> I'm not overjoyed at the static default. Is there a reason to use the
> static default instead of checking HGPORT, so that multiple users on a
> single box (such as the big compile farm machine several of us favor)
> can run the tests without risk of stomping each other?

That's just a random default which must > 1024. If multiple users run this
in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
that's considered "IPv6 is available".

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Augie Fackler
On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > I'm not overjoyed at the static default. Is there a reason to use the
> > static default instead of checking HGPORT, so that multiple users on a
> > single box (such as the big compile farm machine several of us favor)
> > can run the tests without risk of stomping each other?
>
> That's just a random default which must > 1024. If multiple users run this
> in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
> that's considered "IPv6 is available".

Oh, I misunderstood. This function is *only* for checking that IPv6 is
available, not also for checking if a specific port is available with
IPv6. Is that (revised) understanding correct on my part?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] bookmarks: fix HG_PENDING handling

2017-02-15 Thread Augie Fackler
foozy, how does this (and timeless' other patch in the same basic
area) relate to the patches you said you've got coming?

Thanks!
Augie

On Tue, Feb 14, 2017 at 04:19:45PM +, timeless wrote:
> # HG changeset patch
> # User timeless 
> # Date 1487089111 0
> #  Tue Feb 14 16:18:31 2017 +
> # Node ID 54804162d8b35ceff3bd22f05b515fc716705ce2
> # Parent  f2ad0d8047009e6e58ab1fa34ae7107714f5dc30
> # Available At https://bitbucket.org/timeless/mercurial-crew
> #  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
> 54804162d8b3
> bookmarks: fix HG_PENDING handling
>
> HG_PENDING is supposed to point to a specific repo when
> called as part of a hook, without this, any command in an
> unrelated repository would read the pending version of
> bookmark state instead of the version that is appropriate.
>
> diff -r f2ad0d804700 -r 54804162d8b3 mercurial/bookmarks.py
> --- a/mercurial/bookmarks.py  Tue Feb 14 01:52:16 2017 +0530
> +++ b/mercurial/bookmarks.py  Tue Feb 14 16:18:31 2017 +
> @@ -30,7 +30,7 @@
>  may need to tweak this behavior further.
>  """
>  bkfile = None
> -if 'HG_PENDING' in encoding.environ:
> +if encoding.environ.get('HG_PENDING') == repo.root:
>  try:
>  bkfile = repo.vfs('bookmarks.pending')
>  except IOError as inst:
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] chgserver: move comments in config example

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487212221 28800
#  Wed Feb 15 18:30:21 2017 -0800
# Node ID 894c348d49abb67613b156a2f7c60a840818bc39
# Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r 894c348d49ab
chgserver: move comments in config example

"#" must be the first character of a line to mark the text as comments.
So let's change the docstring.

diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py
--- a/mercurial/chgserver.py
+++ b/mercurial/chgserver.py
@@ -32,6 +32,9 @@ Config
 
   [chgserver]
-  idletimeout = 3600 # seconds, after which an idle server will exit
-  skiphash = False   # whether to skip config or env change checks
+  # how long (in seconds) should an idle chg server exit
+  idletimeout = 3600
+
+  # whether to skip config or env change checks
+  skiphash = False
 """
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Jun Wu
Excerpts from Augie Fackler's message of 2017-02-15 21:32:38 -0500:
> On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> > Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > > I'm not overjoyed at the static default. Is there a reason to use the
> > > static default instead of checking HGPORT, so that multiple users on a
> > > single box (such as the big compile farm machine several of us favor)
> > > can run the tests without risk of stomping each other?
> >
> > That's just a random default which must > 1024. If multiple users run this
> > in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
> > that's considered "IPv6 is available".
> 
> Oh, I misunderstood. This function is *only* for checking that IPv6 is
> available, not also for checking if a specific port is available with
> IPv6. Is that (revised) understanding correct on my part?

Correct. run-tests.py will first decide whether to use IPv6 or not globally
by calling this function. If IPv6 is available, then all port checks will
be IPv6-only. Otherwise, they will be IPv4-only.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

2017-02-15 Thread Augie Fackler
On Wed, Feb 15, 2017 at 06:57:37PM -0800, Jun Wu wrote:
> Excerpts from Augie Fackler's message of 2017-02-15 21:32:38 -0500:
> > On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> > > Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > > > I'm not overjoyed at the static default. Is there a reason to use the
> > > > static default instead of checking HGPORT, so that multiple users on a
> > > > single box (such as the big compile farm machine several of us favor)
> > > > can run the tests without risk of stomping each other?
> > >
> > > That's just a random default which must > 1024. If multiple users run this
> > > in parallel - it'd be fine - one of them will get the error EADDRINUSE, 
> > > and
> > > that's considered "IPv6 is available".
> >
> > Oh, I misunderstood. This function is *only* for checking that IPv6 is
> > available, not also for checking if a specific port is available with
> > IPv6. Is that (revised) understanding correct on my part?
>
> Correct. run-tests.py will first decide whether to use IPv6 or not globally
> by calling this function. If IPv6 is available, then all port checks will
> be IPv6-only. Otherwise, they will be IPv4-only.

Okay, sure. Queued.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] localrepo: move extension loading to a separate method

2017-02-15 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1487216474 28800
#  Wed Feb 15 19:41:14 2017 -0800
# Node ID dda2ebe89f50fcf3bf5a9b8d2266aa2dd5b106ea
# Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r dda2ebe89f50
localrepo: move extension loading to a separate method

The stateful chg plan [1] requires a special repo object, where ideally all
side effects caused by loading the repo object could be reverted by just
dropping (gabbage collect) the loaded repo object.

Currently, that is impossible because repo.__init__ calls
"extensions.loadall", which may have unpredictable side-effects that cannot
be reverted by dropping the repo object.

This patch moves "extensions.loadall" to a separate method, so chg could
subclass localrepository and make extensions loading a no-op.

[1]: mercurial-scm.org/pipermail/mercurial-devel/2017-February/092547.html

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -271,5 +271,5 @@ class localrepository(object):
 try:
 self.ui.readconfig(self.join("hgrc"), self.root)
-extensions.loadall(self.ui)
+self._loadextensions()
 except IOError:
 pass
@@ -372,4 +372,7 @@ class localrepository(object):
 self._writecaches()
 
+def _loadextensions(self):
+extensions.loadall(self.ui)
+
 def _writecaches(self):
 if self._revbranchcache:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] runtests: check ports on IPv6 address

2017-02-15 Thread Augie Fackler

> On Feb 9, 2017, at 8:59 AM, Jun Wu  wrote:
> 
> # HG changeset patch
> # User Jun Wu 
> # Date 1486648674 28800
> #  Thu Feb 09 05:57:54 2017 -0800
> # Node ID 93e23f7b87a4ab456053b6ba573615be16c6c4b0
> # Parent  a68510b69f413545722c086eaeb840dd5e8305b4
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
> 93e23f7b87a4
> runtests: check ports on IPv6 address

This has made test-bundle2-remote-changegroup.t flaky when run in parallel with 
other tests. I was able to bisect with this:

cd tests && python run-tests.py -j 100 --runs-per-test 400 
test-bundle2-remote-changegroup.t

fails in about 70 out of the 400 runs. I also see it periodically when running 
the tests with -j120 on gcc112 from the gcc compile farm, which is a POWER8 
machine with 160 hardware threads. I suspect you can reproduce it with a lower 
-j if you run the test enough times, but I’m up later than I should be already, 
so I didn’t bother logging in to a smaller linux machine to confirm.

Can you take a look?

Thanks!
Augie

> Previously, checkportisavailable only checks ports on the IPv4 address. This
> patch makes it check IPv6 as well. It'll be useful if "localhost" does not
> have an IPv4 address, or its IPv4 address does not exist somehow.
> 
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -115,13 +115,17 @@ wifexited = getattr(os, "WIFEXITED", lam
> def checkportisavailable(port):
> """return true if a port seems free to bind on localhost"""
> -try:
> -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> -s.bind(('localhost', port))
> -s.close()
> -return True
> -except socket.error as exc:
> -if not exc.errno == errno.EADDRINUSE:
> -raise
> -return False
> +families = [getattr(socket, i, None)
> +for i in ('AF_INET', 'AF_INET6')
> +if getattr(socket, i, None) is not None]
> +for family in families:
> +try:
> +s = socket.socket(family, socket.SOCK_STREAM)
> +s.bind(('localhost', port))
> +s.close()
> +return True
> +except socket.error as exc:
> +if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL):
> +raise
> +return False
> 
> closefds = os.name == 'posix'
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] runtests: check ports on IPv6 address

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 8:12 PM, Augie Fackler  wrote:
>
>> On Feb 9, 2017, at 8:59 AM, Jun Wu  wrote:
>>
>> # HG changeset patch
>> # User Jun Wu 
>> # Date 1486648674 28800
>> #  Thu Feb 09 05:57:54 2017 -0800
>> # Node ID 93e23f7b87a4ab456053b6ba573615be16c6c4b0
>> # Parent  a68510b69f413545722c086eaeb840dd5e8305b4
>> # Available At https://bitbucket.org/quark-zju/hg-draft
>> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
>> 93e23f7b87a4
>> runtests: check ports on IPv6 address
>
> This has made test-bundle2-remote-changegroup.t flaky when run in parallel 
> with other tests. I was able to bisect with this:
>
> cd tests && python run-tests.py -j 100 --runs-per-test 400 
> test-bundle2-remote-changegroup.t
>
> fails in about 70 out of the 400 runs. I also see it periodically when 
> running the tests with -j120 on gcc112 from the gcc compile farm, which is a 
> POWER8 machine with 160 hardware threads. I suspect you can reproduce it with 
> a lower -j if you run the test enough times, but I’m up later than I should 
> be already, so I didn’t bother logging in to a smaller linux machine to 
> confirm.
>
> Can you take a look?

Heh, I reported the flakiness on #mercurial earlier today. That's why
Jun sent a series of patches maybe 2 hours ago that you then queued.
Have you tested with those patches applied? I have not had time to
look at his patches, but maybe he should have explained their
motivation better if this is indeed the same problem that I reported.

>
> Thanks!
> Augie
>
>> Previously, checkportisavailable only checks ports on the IPv4 address. This
>> patch makes it check IPv6 as well. It'll be useful if "localhost" does not
>> have an IPv4 address, or its IPv4 address does not exist somehow.
>>
>> diff --git a/tests/run-tests.py b/tests/run-tests.py
>> --- a/tests/run-tests.py
>> +++ b/tests/run-tests.py
>> @@ -115,13 +115,17 @@ wifexited = getattr(os, "WIFEXITED", lam
>> def checkportisavailable(port):
>> """return true if a port seems free to bind on localhost"""
>> -try:
>> -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>> -s.bind(('localhost', port))
>> -s.close()
>> -return True
>> -except socket.error as exc:
>> -if not exc.errno == errno.EADDRINUSE:
>> -raise
>> -return False
>> +families = [getattr(socket, i, None)
>> +for i in ('AF_INET', 'AF_INET6')
>> +if getattr(socket, i, None) is not None]
>> +for family in families:
>> +try:
>> +s = socket.socket(family, socket.SOCK_STREAM)
>> +s.bind(('localhost', port))
>> +s.close()
>> +return True
>> +except socket.error as exc:
>> +if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL):
>> +raise
>> +return False
>>
>> closefds = os.name == 'posix'
>> ___
>> Mercurial-devel mailing list
>> Mercurial-devel@mercurial-scm.org
>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
> ___
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] runtests: check ports on IPv6 address

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 8:23 PM, Martin von Zweigbergk
 wrote:
> On Wed, Feb 15, 2017 at 8:12 PM, Augie Fackler  wrote:
>>
>>> On Feb 9, 2017, at 8:59 AM, Jun Wu  wrote:
>>>
>>> # HG changeset patch
>>> # User Jun Wu 
>>> # Date 1486648674 28800
>>> #  Thu Feb 09 05:57:54 2017 -0800
>>> # Node ID 93e23f7b87a4ab456053b6ba573615be16c6c4b0
>>> # Parent  a68510b69f413545722c086eaeb840dd5e8305b4
>>> # Available At https://bitbucket.org/quark-zju/hg-draft
>>> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
>>> 93e23f7b87a4
>>> runtests: check ports on IPv6 address
>>
>> This has made test-bundle2-remote-changegroup.t flaky when run in parallel 
>> with other tests. I was able to bisect with this:
>>
>> cd tests && python run-tests.py -j 100 --runs-per-test 400 
>> test-bundle2-remote-changegroup.t
>>
>> fails in about 70 out of the 400 runs. I also see it periodically when 
>> running the tests with -j120 on gcc112 from the gcc compile farm, which is a 
>> POWER8 machine with 160 hardware threads. I suspect you can reproduce it 
>> with a lower -j if you run the test enough times, but I’m up later than I 
>> should be already, so I didn’t bother logging in to a smaller linux machine 
>> to confirm.
>>
>> Can you take a look?
>
> Heh, I reported the flakiness on #mercurial earlier today. That's why
> Jun sent a series of patches maybe 2 hours ago that you then queued.
> Have you tested with those patches applied? I have not had time to
> look at his patches, but maybe he should have explained their
> motivation better if this is indeed the same problem that I reported.

Or maybe I just incorrectly assumed that the problems I reported with
ports not being available had the same root cause as the flaky
test-bundle2-remote-changegroup.t?

>
>>
>> Thanks!
>> Augie
>>
>>> Previously, checkportisavailable only checks ports on the IPv4 address. This
>>> patch makes it check IPv6 as well. It'll be useful if "localhost" does not
>>> have an IPv4 address, or its IPv4 address does not exist somehow.
>>>
>>> diff --git a/tests/run-tests.py b/tests/run-tests.py
>>> --- a/tests/run-tests.py
>>> +++ b/tests/run-tests.py
>>> @@ -115,13 +115,17 @@ wifexited = getattr(os, "WIFEXITED", lam
>>> def checkportisavailable(port):
>>> """return true if a port seems free to bind on localhost"""
>>> -try:
>>> -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> -s.bind(('localhost', port))
>>> -s.close()
>>> -return True
>>> -except socket.error as exc:
>>> -if not exc.errno == errno.EADDRINUSE:
>>> -raise
>>> -return False
>>> +families = [getattr(socket, i, None)
>>> +for i in ('AF_INET', 'AF_INET6')
>>> +if getattr(socket, i, None) is not None]
>>> +for family in families:
>>> +try:
>>> +s = socket.socket(family, socket.SOCK_STREAM)
>>> +s.bind(('localhost', port))
>>> +s.close()
>>> +return True
>>> +except socket.error as exc:
>>> +if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL):
>>> +raise
>>> +return False
>>>
>>> closefds = os.name == 'posix'
>>> ___
>>> Mercurial-devel mailing list
>>> Mercurial-devel@mercurial-scm.org
>>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>>
>> ___
>> Mercurial-devel mailing list
>> Mercurial-devel@mercurial-scm.org
>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] runtests: check ports on IPv6 address

2017-02-15 Thread Augie Fackler

> On Feb 15, 2017, at 11:24 PM, Martin von Zweigbergk  
> wrote:
> 
> On Wed, Feb 15, 2017 at 8:23 PM, Martin von Zweigbergk
>  wrote:
>> On Wed, Feb 15, 2017 at 8:12 PM, Augie Fackler  wrote:
>>> 
 On Feb 9, 2017, at 8:59 AM, Jun Wu  wrote:
 
 # HG changeset patch
 # User Jun Wu 
 # Date 1486648674 28800
 #  Thu Feb 09 05:57:54 2017 -0800
 # Node ID 93e23f7b87a4ab456053b6ba573615be16c6c4b0
 # Parent  a68510b69f413545722c086eaeb840dd5e8305b4
 # Available At https://bitbucket.org/quark-zju/hg-draft
 #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
 93e23f7b87a4
 runtests: check ports on IPv6 address
>>> 
>>> This has made test-bundle2-remote-changegroup.t flaky when run in parallel 
>>> with other tests. I was able to bisect with this:
>>> 
>>> cd tests && python run-tests.py -j 100 --runs-per-test 400 
>>> test-bundle2-remote-changegroup.t
>>> 
>>> fails in about 70 out of the 400 runs. I also see it periodically when 
>>> running the tests with -j120 on gcc112 from the gcc compile farm, which is 
>>> a POWER8 machine with 160 hardware threads. I suspect you can reproduce it 
>>> with a lower -j if you run the test enough times, but I’m up later than I 
>>> should be already, so I didn’t bother logging in to a smaller linux machine 
>>> to confirm.
>>> 
>>> Can you take a look?
>> 
>> Heh, I reported the flakiness on #mercurial earlier today. That's why
>> Jun sent a series of patches maybe 2 hours ago that you then queued.
>> Have you tested with those patches applied? I have not had time to
>> look at his patches, but maybe he should have explained their
>> motivation better if this is indeed the same problem that I reported.
> 
> Or maybe I just incorrectly assumed that the problems I reported with
> ports not being available had the same root cause as the flaky
> test-bundle2-remote-changegroup.t?

test-bundle2-remote-changegroup.t is still flaky for me at 1ee68, which I 
believe includes the series you mentioned :/


> 
>> 
>>> 
>>> Thanks!
>>> Augie
>>> 
 Previously, checkportisavailable only checks ports on the IPv4 address. 
 This
 patch makes it check IPv6 as well. It'll be useful if "localhost" does not
 have an IPv4 address, or its IPv4 address does not exist somehow.
 
 diff --git a/tests/run-tests.py b/tests/run-tests.py
 --- a/tests/run-tests.py
 +++ b/tests/run-tests.py
 @@ -115,13 +115,17 @@ wifexited = getattr(os, "WIFEXITED", lam
 def checkportisavailable(port):
"""return true if a port seems free to bind on localhost"""
 -try:
 -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 -s.bind(('localhost', port))
 -s.close()
 -return True
 -except socket.error as exc:
 -if not exc.errno == errno.EADDRINUSE:
 -raise
 -return False
 +families = [getattr(socket, i, None)
 +for i in ('AF_INET', 'AF_INET6')
 +if getattr(socket, i, None) is not None]
 +for family in families:
 +try:
 +s = socket.socket(family, socket.SOCK_STREAM)
 +s.bind(('localhost', port))
 +s.close()
 +return True
 +except socket.error as exc:
 +if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL):
 +raise
 +return False
 
 closefds = os.name == 'posix'
 ___
 Mercurial-devel mailing list
 Mercurial-devel@mercurial-scm.org
 https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>>> 
>>> ___
>>> Mercurial-devel mailing list
>>> Mercurial-devel@mercurial-scm.org
>>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] runtests: check ports on IPv6 address

2017-02-15 Thread Jun Wu
Excerpts from Augie Fackler's message of 2017-02-15 23:27:23 -0500:
> >> Heh, I reported the flakiness on #mercurial earlier today. That's why
> >> Jun sent a series of patches maybe 2 hours ago that you then queued.
> >> Have you tested with those patches applied? I have not had time to
> >> look at his patches, but maybe he should have explained their
> >> motivation better if this is indeed the same problem that I reported.
> > 
> > Or maybe I just incorrectly assumed that the problems I reported with
> > ports not being available had the same root cause as the flaky
> > test-bundle2-remote-changegroup.t?
> 
> test-bundle2-remote-changegroup.t is still flaky for me at 1ee68, which I
> believe includes the series you mentioned :/

I will investigate on gcc112. Sorry for the breakage.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[Bug 5486] New: Mercurial+evolve sometimes segfaults on pull

2017-02-15 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5486

Bug ID: 5486
   Summary: Mercurial+evolve sometimes segfaults on pull
   Product: Mercurial
   Version: 4.1
  Hardware: PC
OS: Linux
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: Mercurial
  Assignee: bugzi...@mercurial-scm.org
  Reporter: a...@dwimlabs.net
CC: mercurial-de...@selenic.com,
pierre-yves.da...@ens-lyon.org

I have a box that mirrors some repos, including Mercurial's main, once a day by
cron and occasionally, very rarely, hg pull segfaults on that repo. It's the
only repo that uses evolve and the only that has ever failed a pull. hg version
is 4.1 (installed from the ppa), evolve summary is:

parent: 1803:54120614e9e5 
 Update  tag 5.6.0 for changeset e7b6e9c4a5d4
branch: stable
bookmarks: @
commit: (clean)
update: (current)

The very rare segfaults have been happening before, but I used to have hg pull
--quiet in the cron job to not get too much mail. Here is a recent segfault
with `hg pull --verbose`:

pulling from https://www.mercurial-scm.org/repo/hg/
searching for changes
all local heads known remotely
sampling from both directions
sampling from both directions
adding changesets
adding manifests
adding file changes
added 23 changesets with 41 changes to 10 files
Segmentation fault

Now the repo has an abandoned transaction.

For comparison, here's the output from a day before, when it worked fine:

pulling from https://www.mercurial-scm.org/repo/hg/
searching for changes
all local heads known remotely
sampling from both directions
sampling from both directions
adding changesets
adding manifests
adding file changes
added 27 changesets with 54 changes to 32 files
111 new obsolescence markers
updating bookmark @
(run 'hg update' to get a working copy)

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[Bug 5487] New: Cannot restore merge commit after rebase

2017-02-15 Thread mercurial-bugs
https://bz.mercurial-scm.org/show_bug.cgi?id=5487

Bug ID: 5487
   Summary: Cannot restore merge commit after rebase
   Product: Mercurial
   Version: 4.0.2
  Hardware: PC
OS: Windows
Status: UNCONFIRMED
  Severity: bug
  Priority: wish
 Component: evolution
  Assignee: bugzi...@mercurial-scm.org
  Reporter: abcz2.upr...@gmail.com
CC: mercurial-de...@selenic.com,
pierre-yves.da...@ens-lyon.org

I've done a rebase of a merge commit. I was not satisfied with it, so I'd like
to restore previous version and strip current. But I have evolution enabled, so
no backup was generated.

Here is my changeset

$ hg.exe --hidden log -r "obsolete()"
changeset:   4433:05cee9113122
parent:  4427:f16ee9507a9b
parent:  4432:4d1ecbeabed5
user:danbst
date:Thu Feb 16 06:29:11 2017 +0200
summary: Merge with release-test

When I try to recover it (using hg touch), I get:

$ hg.exe --hidden touch -r 4433
[4433] Merge with release-test
reviving this changeset will create divergence unless you make a duplicate.
(a)llow divergence or (d)uplicate the changeset?  a
abort: cannot amend merge changesets

But if I try duplicate:

$ hg.exe --hidden touch -D -r 4433
abort: cannot amend merge changesets

So, no way to recover it, and no backups

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] run-tests: drop unused "useipv6" parameter from Test class

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1487225871 28800
#  Wed Feb 15 22:17:51 2017 -0800
# Node ID b01c29d1eaff7875380b964da46b357d3a4445b5
# Parent  1ee685defe80117cf6aafea1ede6c33c478abceb
run-tests: drop unused "useipv6" parameter from Test class

The global parameter is used instead, so the constructor parameter
ended up being unused.

diff -r 1ee685defe80 -r b01c29d1eaff tests/run-tests.py
--- a/tests/run-tests.pyWed Feb 15 16:29:58 2017 -0800
+++ b/tests/run-tests.pyWed Feb 15 22:17:51 2017 -0800
@@ -534,8 +534,7 @@
  timeout=defaults['timeout'],
  startport=defaults['port'], extraconfigopts=None,
  py3kwarnings=False, shell=None, hgcommand=None,
- slowtimeout=defaults['slowtimeout'], usechg=False,
- useipv6=False):
+ slowtimeout=defaults['slowtimeout'], usechg=False):
 """Create a test from parameters.
 
 path is the full path to the file defining the test.
@@ -2322,8 +2321,7 @@
 py3kwarnings=self.options.py3k_warnings,
 shell=self.options.shell,
 hgcommand=self._hgcommand,
-usechg=bool(self.options.with_chg or self.options.chg),
-useipv6=useipv6)
+usechg=bool(self.options.with_chg or self.options.chg))
 t.should_reload = True
 return t
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] run-tests: drop unused "useipv6" parameter from Test class

2017-02-15 Thread Jun Wu
Looks good to me. I was trying to make the test class "self-contained"
without accessing global variables, as some people have strong opinion on
global variables. So it was intentional. But removing the parameter leads to
shorter code. I'm fine with either way.

Excerpts from Martin von Zweigbergk's message of 2017-02-15 22:20:28 -0800:
> # HG changeset patch
> # User Martin von Zweigbergk 
> # Date 1487225871 28800
> #  Wed Feb 15 22:17:51 2017 -0800
> # Node ID b01c29d1eaff7875380b964da46b357d3a4445b5
> # Parent  1ee685defe80117cf6aafea1ede6c33c478abceb
> run-tests: drop unused "useipv6" parameter from Test class
> 
> The global parameter is used instead, so the constructor parameter
> ended up being unused.
> 
> diff -r 1ee685defe80 -r b01c29d1eaff tests/run-tests.py
> --- a/tests/run-tests.pyWed Feb 15 16:29:58 2017 -0800
> +++ b/tests/run-tests.pyWed Feb 15 22:17:51 2017 -0800
> @@ -534,8 +534,7 @@
>   timeout=defaults['timeout'],
>   startport=defaults['port'], extraconfigopts=None,
>   py3kwarnings=False, shell=None, hgcommand=None,
> - slowtimeout=defaults['slowtimeout'], usechg=False,
> - useipv6=False):
> + slowtimeout=defaults['slowtimeout'], usechg=False):
>  """Create a test from parameters.
>  
>  path is the full path to the file defining the test.
> @@ -2322,8 +2321,7 @@
>  py3kwarnings=self.options.py3k_warnings,
>  shell=self.options.shell,
>  hgcommand=self._hgcommand,
> -usechg=bool(self.options.with_chg or self.options.chg),
> -useipv6=useipv6)
> +usechg=bool(self.options.with_chg or self.options.chg))
>  t.should_reload = True
>  return t
>  
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] run-tests: drop unused "useipv6" parameter from Test class

2017-02-15 Thread Martin von Zweigbergk via Mercurial-devel
On Wed, Feb 15, 2017 at 10:28 PM, Jun Wu  wrote:
> Looks good to me. I was trying to make the test class "self-contained"
> without accessing global variables, as some people have strong opinion on
> global variables. So it was intentional. But removing the parameter leads to
> shorter code. I'm fine with either way.

Oh, I'm sorry. I didn't realize it was shadowing the global one. I'm
still not sure which I prefer, but since my patch wasn't just dropping
an unused parameter as I thought it did, let's just drop my patch.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel