[PATCH 2 of 8 simple] color: move '_effect' mapping into core
# 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
# 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
# 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
# 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
# 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
# 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'
# 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
# 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
# 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
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)
> -- 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)
> -- 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
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
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)
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
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
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
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
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
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)
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)
> -- 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)
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)
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
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)
> -- 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)
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
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
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
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)
# 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
# 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
# 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"
# 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()
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
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
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
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
# 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
# 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
# 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
# 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
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
> 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
# 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
# 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
# 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()
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
> 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
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
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
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
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
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
# 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
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
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
# 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
> 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
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
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
> 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
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
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
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
# 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
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
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