D368: releasenotes: add check flag for use of admonitions and its validity
rishabhmadan96 added a comment. Sorry I just edited the revision string. Will that work? Or should I update it again with "Differential Revision: https://phab.mercurial-scm.org/D368; at the end. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D368 To: rishabhmadan96, #hg-reviewers, durin42 Cc: quark, durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D368: Differential Revision: https://phab.mercurial-scm.org/D368releasenotes: add check flag for use of admonitions and its validity
quark added a comment. Did you add "Differential Revision: https://phab.mercurial-scm.org/D368; to the first line of your commit message? Could you try moving it to the last line? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D368 To: rishabhmadan96, #hg-reviewers, durin42 Cc: quark, durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D368: Differential Revision: https://phab.mercurial-scm.org/D368releasenotes: add check flag for use of admonitions and its validity
rishabhmadan96 updated this revision to Diff 973. rishabhmadan96 retitled this revision from "releasenotes: add check flag for use of admonitions and its validity" to "Differential Revision: https://phab.mercurial-scm.org/D368 releasenotes: add check flag for use of admonitions and its validity". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D368?vs=846=973 REVISION DETAIL https://phab.mercurial-scm.org/D368 AFFECTED FILES hgext/releasenotes.py tests/test-releasenotes-formatting.t CHANGE DETAILS diff --git a/tests/test-releasenotes-formatting.t b/tests/test-releasenotes-formatting.t --- a/tests/test-releasenotes-formatting.t +++ b/tests/test-releasenotes-formatting.t @@ -378,3 +378,32 @@ * Adds a new feature. + $ cd .. + +Testing output for the --check (-c) flag + + $ hg init check-flag + $ cd check-flag + + $ touch a + $ hg -q commit -A -l - << EOF + > .. asf:: + > + >First paragraph under this admonition. + > EOF + +Suggest similar admonition in place of the invalid one. + + $ hg releasenotes -r . -c + Invalid admonition 'asf' present in changeset 4026fe9e1c20 + + $ touch b + $ hg -q commit -A -l - << EOF + > .. fixes:: + > + >First paragraph under this admonition. + > EOF + + $ hg releasenotes -r . -c + Invalid admonition 'fixes' present in changeset 0e7130d2705c + (did you mean fix?) diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py --- a/hgext/releasenotes.py +++ b/hgext/releasenotes.py @@ -13,6 +13,7 @@ from __future__ import absolute_import +import difflib import errno import re import sys @@ -242,6 +243,39 @@ read('.hgreleasenotes') return p['sections'] +def checkadmonitions(ui, repo, directives, revs): +""" +Checks the commit messages for admonitions and their validity. + +.. abcd:: + + First paragraph under this admonition + +For this commit message, using `hg releasenotes -r . --check` +returns: Invalid admonition 'abcd' present in changeset 3ea92981e103 + +As admonition 'abcd' is neither present in default nor custom admonitions +""" +for rev in revs: +ctx = repo[rev] +admonition = re.search(RE_DIRECTIVE, ctx.description()) +if admonition: +if admonition.group(1) in directives: +continue +else: +ui.write(_("Invalid admonition '%s' present in changeset %s" + "\n") % (admonition.group(1), ctx.hex()[:12])) +sim = lambda x: difflib.SequenceMatcher(None, +admonition.group(1), x).ratio() + +similar = [s for s in directives if sim(s) > 0.6] +if len(similar) == 1: +ui.write(_("(did you mean %s?)\n") % similar[0]) +elif similar: +ss = ", ".join(sorted(similar)) +ui.write(_("(did you mean one of %s?)\n") % ss) + + def parsenotesfromrevisions(repo, directives, revs): notes = parsedreleasenotes() @@ -432,9 +466,11 @@ return '\n'.join(lines) @command('releasenotes', -[('r', 'rev', '', _('revisions to process for release notes'), _('REV'))], -_('[-r REV] FILE')) -def releasenotes(ui, repo, file_, rev=None): +[('r', 'rev', '', _('revisions to process for release notes'), _('REV')), +('c', 'check', False, _('checks for validity of admonitions (if any)'), +_('REV'))], +_('hg releasenotes [-r REV] [-c] FILE')) +def releasenotes(ui, repo, file_=None, **opts): """parse release notes from commit messages into an output file Given an output file and set of revisions, this command will parse commit @@ -511,8 +547,12 @@ release note after it has been added to the release notes file. """ sections = releasenotessections(ui, repo) +rev = opts.get('rev') revs = scmutil.revrange(repo, [rev or 'not public()']) +if opts.get('check'): +return checkadmonitions(ui, repo, sections.names(), revs) + incoming = parsenotesfromrevisions(repo, sections.names(), revs) try: To: rishabhmadan96, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2] py3: select input or raw_input by pycompat
# HG changeset patch # User Yuya Nishihara# Date 1502859264 -32400 # Wed Aug 16 13:54:24 2017 +0900 # Node ID 2c44ad89954bf0a04392775e7444f1ba2fc0b2e9 # Parent 63c4583c7fa0f989f225488273614f3a0aa88002 py3: select input or raw_input by pycompat This seems slightly cleaner. diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -63,6 +63,7 @@ if ispy3: sysexecutable = os.fsencode(sysexecutable) stringio = io.BytesIO maplist = lambda *args: list(map(*args)) +rawinput = input # TODO: .buffer might not exist if std streams were replaced; we'll need # a silly wrapper to make a bytes stream backed by a unicode one. @@ -312,6 +313,7 @@ else: shlexsplit = shlex.split stringio = cStringIO.StringIO maplist = map +rawinput = raw_input class _pycompatstub(object): def __init__(self): diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -176,10 +176,7 @@ def bytesinput(fin, fout, *args, **kwarg sin, sout = sys.stdin, sys.stdout try: sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) -if pycompat.ispy3: -return encoding.strtolocal(input(*args, **kwargs)) -else: -return raw_input(*args, **kwargs) +return encoding.strtolocal(pycompat.rawinput(*args, **kwargs)) finally: sys.stdin, sys.stdout = sin, sout ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2] py3: make encoding.strio() an identity function on Python 2
# HG changeset patch # User Yuya Nishihara# Date 1502859011 -32400 # Wed Aug 16 13:50:11 2017 +0900 # Node ID 63c4583c7fa0f989f225488273614f3a0aa88002 # Parent 627cb36b537f7f0ffe2ea7e38a9415b6c4c499e3 py3: make encoding.strio() an identity function on Python 2 It's the convention the other encoding.str*() functions follow. To make things simple, this also drops kwargs from the strio() constructor. diff --git a/mercurial/encoding.py b/mercurial/encoding.py --- a/mercurial/encoding.py +++ b/mercurial/encoding.py @@ -575,15 +575,17 @@ def fromutf8b(s): r += c return r -class strio(io.TextIOWrapper): -"""Wrapper around TextIOWrapper that respects hg's encoding assumptions. +if pycompat.ispy3: +class strio(io.TextIOWrapper): +"""Wrapper around TextIOWrapper that respects hg's encoding assumptions. -Also works around Python closing streams. -""" +Also works around Python closing streams. +""" -def __init__(self, buffer, **kwargs): -kwargs[r'encoding'] = _sysstr(encoding) -super(strio, self).__init__(buffer, **kwargs) +def __init__(self, buffer): +super(strio, self).__init__(buffer, encoding=_sysstr(encoding)) -def __del__(self): -"""Override __del__ so it doesn't close the underlying stream.""" +def __del__(self): +"""Override __del__ so it doesn't close the underlying stream.""" +else: +strio = pycompat.identity diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -175,11 +175,10 @@ def safehasattr(thing, attr): def bytesinput(fin, fout, *args, **kwargs): sin, sout = sys.stdin, sys.stdout try: +sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) if pycompat.ispy3: -sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) return encoding.strtolocal(input(*args, **kwargs)) else: -sys.stdin, sys.stdout = fin, fout return raw_input(*args, **kwargs) finally: sys.stdin, sys.stdout = sin, sout ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2] templatekw: rename termwidth() per convention
# HG changeset patch # User Yuya Nishihara# Date 1502859439 -32400 # Wed Aug 16 13:57:19 2017 +0900 # Node ID 6cd0eafbd52b4e0efcad037876dc9bdf6c9bbfbb # Parent 2c44ad89954bf0a04392775e7444f1ba2fc0b2e9 templatekw: rename termwidth() per convention diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -760,7 +760,7 @@ def loadkeyword(ui, extname, registrarob keywords[name] = func @templatekeyword('termwidth') -def termwidth(repo, ctx, templ, **args): +def showtermwidth(repo, ctx, templ, **args): """Integer. The width of the current terminal.""" return repo.ui.termwidth() ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2] templatekw: specify plural form of instability
# HG changeset patch # User Yuya Nishihara# Date 1502601148 -32400 # Sun Aug 13 14:12:28 2017 +0900 # Node ID 50723ff5912ecde3f8e43bea4b84db03bae7f1f0 # Parent 6cd0eafbd52b4e0efcad037876dc9bdf6c9bbfbb templatekw: specify plural form of instability Follows up 40739aef97f7. diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -783,7 +783,8 @@ def showinstabilities(**args): (EXPERIMENTAL) """ args = pycompat.byteskwargs(args) -return showlist('instability', args['ctx'].instabilities(), args) +return showlist('instability', args['ctx'].instabilities(), args, +plural='instabilities') # tell hggettext to extract docstrings from these functions: i18nfunctions = keywords.values() ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D299: py3: introduce a wrapper for __builtins__.{raw_,}input()
yuja added inline comments. INLINE COMMENTS > encoding.py:585 > +def __init__(self, buffer, **kwargs): > +kwargs[r'encoding'] = encoding > +super(strio, self).__init__(buffer, **kwargs) Fixed as `s/encoding/_sysstr(encoding)/`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D299 To: durin42, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D340: rebase: prefer choosing merge base with successor in destination
martinvonz added a comment. In https://phab.mercurial-scm.org/D340#6330, @quark wrote: > Since the "unwanted" warning "covers" the case this patch handles. The behavior is still "correct" (since the warning is printed) without this patch. I'm leaning towards dropping this patch. > > For errors vs warnings, I still think it's better to give power users a chance to proceed. How do you think about this approach? > > - If there are multiple merge base candidates, calculate "unwanted" revsets for both, and if only one of them is empty, pick that one automatically and proceed. > - If both merge base candidates have "unwanted" revsets, raise `error.InterventionRequired` so power users could still have a chance to proceed fixing them manually. Sounds good to me. Thanks! The test cases still seem useful, so maybe you can keep that part of the patch? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D340 To: quark, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D353: extensions: don't give AttributeError bytes message on Python 3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG0646608368a9: extensions: don't give AttributeError bytes message on Python 3 (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D353?vs=946=969 REVISION DETAIL https://phab.mercurial-scm.org/D353 AFFECTED FILES mercurial/extensions.py CHANGE DETAILS diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -396,8 +396,8 @@ break if currcls is object: -raise AttributeError( -_("type '%s' has no property '%s'") % (cls, propname)) +raise AttributeError(r"type '%s' has no property '%s'" % ( +cls, propname)) def wrapfunction(container, funcname, wrapper): '''Wrap the function named funcname in container To: durin42, #hg-reviewers, yuja Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D296: extensions: if on py3 and propname is a bytestr, convert to sysstr
This revision was automatically updated to reflect the committed changes. Closed by commit rHG38a3767975a7: extensions: if on py3 and propname is a bytestr, convert to sysstr (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D296?vs=945=968 REVISION DETAIL https://phab.mercurial-scm.org/D296 AFFECTED FILES mercurial/extensions.py CHANGE DETAILS diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -384,6 +384,7 @@ These can't be wrapped using the normal wrapfunction. """ +propname = pycompat.sysstr(propname) assert callable(wrapper) for currcls in cls.__mro__: if propname in currcls.__dict__: To: durin42, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D299: py3: introduce a wrapper for __builtins__.{raw_,}input()
This revision was automatically updated to reflect the committed changes. durin42 marked an inline comment as done. Closed by commit rHGd390726b575d: py3: introduce a wrapper for __builtins__.{raw_,}input() (authored by durin42). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D299?vs=948=971#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D299?vs=948=971 REVISION DETAIL https://phab.mercurial-scm.org/D299 AFFECTED FILES hgext/hgk.py mercurial/encoding.py mercurial/ui.py mercurial/util.py CHANGE DETAILS diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -172,6 +172,18 @@ def safehasattr(thing, attr): return getattr(thing, attr, _notset) is not _notset +def bytesinput(fin, fout, *args, **kwargs): +sin, sout = sys.stdin, sys.stdout +try: +if pycompat.ispy3: +sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) +return encoding.strtolocal(input(*args, **kwargs)) +else: +sys.stdin, sys.stdout = fin, fout +return raw_input(*args, **kwargs) +finally: +sys.stdin, sys.stdout = sin, sout + def bitsfrom(container): bits = 0 for bit in container: diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1217,18 +1217,10 @@ self.write(prompt, prompt=True) self.flush() -# instead of trying to emulate raw_input, swap (self.fin, -# self.fout) with (sys.stdin, sys.stdout) -oldin = sys.stdin -oldout = sys.stdout -sys.stdin = self.fin -sys.stdout = self.fout # prompt ' ' must exist; otherwise readline may delete entire line # - http://bugs.python.org/issue12833 with self.timeblockedsection('stdio'): -line = raw_input(' ') -sys.stdin = oldin -sys.stdout = oldout +line = util.bytesinput(self.fin, self.fout, r' ') # When stdin is in binary mode on Windows, it can cause # raw_input() to emit an extra trailing carriage return diff --git a/mercurial/encoding.py b/mercurial/encoding.py --- a/mercurial/encoding.py +++ b/mercurial/encoding.py @@ -8,6 +8,7 @@ from __future__ import absolute_import import array +import io import locale import os import unicodedata @@ -573,3 +574,16 @@ c = chr(ord(c.decode("utf-8")) & 0xff) r += c return r + +class strio(io.TextIOWrapper): +"""Wrapper around TextIOWrapper that respects hg's encoding assumptions. + +Also works around Python closing streams. +""" + +def __init__(self, buffer, **kwargs): +kwargs[r'encoding'] = encoding +super(strio, self).__init__(buffer, **kwargs) + +def __del__(self): +"""Override __del__ so it doesn't close the underlying stream.""" diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -50,6 +50,7 @@ patch, registrar, scmutil, +util, ) cmdtable = {} @@ -96,7 +97,7 @@ while True: if opts['stdin']: try: -line = raw_input().split(' ') +line = util.bytesinput(ui.fin, ui.fout).split(' ') node1 = line[0] if len(line) > 1: node2 = line[1] @@ -177,7 +178,7 @@ prefix = "" if opts['stdin']: try: -(type, r) = raw_input().split(' ') +(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') prefix = "" except EOFError: return @@ -195,7 +196,7 @@ catcommit(ui, repo, n, prefix) if opts['stdin']: try: -(type, r) = raw_input().split(' ') +(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') except EOFError: break else: To: durin42, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D298: python3: whitelist four more passing tests
This revision was automatically updated to reflect the committed changes. Closed by commit rHG48f3e87ce650: python3: whitelist four more passing tests (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D298?vs=947=970 REVISION DETAIL https://phab.mercurial-scm.org/D298 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -15,19 +15,23 @@ test-diff-subdir.t test-dirstate-nonnormalset.t test-doctest.py +test-duplicateoptions.py test-empty-dir.t test-excessive-merge.t +test-hghave.t test-issue1089.t test-issue1993.t test-issue842.t test-locate.t test-lrucachedict.py test-manifest.py +test-match.py test-merge-default.t test-merge2.t test-merge5.t test-revlog-packentry.t test-run-tests.py +test-terse-status.t test-unified-test.t test-update-reverse.t test-xdg.t To: durin42, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D302: python3: whitelist another *13* tests that now pass
This revision was automatically updated to reflect the committed changes. Closed by commit rHG470e2c7ee34f: python3: whitelist another *13* tests that now pass (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D302?vs=685=972 REVISION DETAIL https://phab.mercurial-scm.org/D302 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -17,6 +17,7 @@ test-doctest.py test-duplicateoptions.py test-empty-dir.t +test-empty.t test-excessive-merge.t test-hghave.t test-issue1089.t @@ -29,9 +30,21 @@ test-merge-default.t test-merge2.t test-merge5.t +test-push-checkheads-pruned-B1.t +test-push-checkheads-pruned-B6.t +test-push-checkheads-pruned-B7.t +test-push-checkheads-superceed-A1.t +test-push-checkheads-superceed-A4.t +test-push-checkheads-superceed-A5.t +test-push-checkheads-superceed-A8.t +test-push-checkheads-unpushed-D1.t +test-push-checkheads-unpushed-D6.t +test-push-checkheads-unpushed-D7.t +test-rename.t test-revlog-packentry.t test-run-tests.py test-terse-status.t test-unified-test.t +test-update-dest.t test-update-reverse.t test-xdg.t To: durin42, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D350: demandimport: test whether to enable or not in hg script
quark abandoned this revision. quark added a comment. > So there's no point to duplicate the HGDEMANDIMPORT check? Hmm... I cannot remember why I did this at the first place. Just checking chg alone should be enough. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D350 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D360: log: add a "graphwidth" template variable
yuja added inline comments. INLINE COMMENTS > cmdutil.py:2557 > displayer.flush(ctx) > -edges = edgefn(type, char, lines, state, rev, parents) > -for type, char, lines, coldata in edges: > +for type, char, width, coldata in itertools.chain([firstedge], > edges): > graphmod.ascii(ui, state, type, char, lines, coldata) Just a nit. Is there any practical benefit to compute edges lazy? I think `edges` can be simply converted to a list. > hooper wrote in templatekw.py:768 > Can you explain why it should be renamed? I thought it should mirror > termwidth. They both return an integer for computations in templates. That's just a convention of templatekw. `termwidth` should be renamed too. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D360 To: hooper, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D351: demandimport: disable by default if chg is being used
quark added a comment. > That seems less bad since the hg script doesn't have to know the chg stuff. Having `HGDEMANDIMPORT` set may affect `hg` ran by child process (like hooks). How about moving the demandimport stuff to `dispatch.py`? I think eventually `dispatch.py` will have some special handling about chg. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers, phillco Cc: phillco, sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D299: py3: introduce a wrapper for __builtins__.{raw_,}input()
yuja accepted this revision. yuja added inline comments. This revision is now accepted and ready to land. INLINE COMMENTS > util.py:180 > +sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) > +return pycompat.bytestr(input(*args, **kwargs)) > +else: s/pycompat.bytestr/encoding.strtolocal/ and queued, thanks. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D299 To: durin42, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D300: python3: whitelist four more passing tests
yuja requested changes to this revision. yuja added a comment. This revision now requires changes to proceed. This appears to be identical to https://phab.mercurial-scm.org/D298. Dropped. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D300 To: durin42, #hg-reviewers, quark, indygreg, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] crecord: fixes the formatting of the select status in the status line
On Tue, 15 Aug 2017 16:51:54 -0700, Jun Wu wrote: > len(text) does not take wide characters into consideration. So it does not > work with all localizations in theory. Maybe we can just add spaces here and > rely on translators to align them. encoding.colwidth() could be used. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D351: demandimport: disable by default if chg is being used
yuja added a comment. > Setting `HGDEMANDIMPORT` for both the forked and non-forked chg client processes seems less cleaner. That seems less bad since the hg script doesn't have to know the chg stuff. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers, phillco Cc: phillco, sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D350: demandimport: test whether to enable or not in hg script
yuja added a comment. > `sys.modules['hgdemandimport']` being set? Maybe I should remove it from commit message. So there's no point to duplicate the HGDEMANDIMPORT check? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D350 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D411: push: fix docsstring
quark created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Seems the code block misses `::`. This patch makes sure `[push]` and `pushvars.server = true` are in two lines. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D411 AFFECTED FILES mercurial/commands.py CHANGE DETAILS diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4022,7 +4022,7 @@ strings that look like conflict markers. By default, servers will ignore `--pushvars`. To enable it add the -following to your configuration file +following to your configuration file:: [push] pushvars.server = true To: quark, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] crecord: fixes the formatting of the select status in the status line
len(text) does not take wide characters into consideration. So it does not work with all localizations in theory. Maybe we can just add spaces here and rely on translators to align them. Excerpts from Filip Filmar's message of 2017-08-13 01:04:52 -0700: > # HG changeset patch > # User Filip Filmar> # Date 1502608633 25200 > # Sun Aug 13 00:17:13 2017 -0700 > # Node ID 4a5fd64feb902da51e7eb5759f4c1d3966186726 > # Parent 03039ff3082b970e70f582e998a7287d1600e912 > crecord: fixes the formatting of the select status in the status line > > The status line in the crecord has the "space" status field which has variable > length depending on the length of the status label in the language of choice. > In English, the status labels are "space: deselect" and "space:select". The > "deselect" label is 2 glyphs longer. This makes the terminal output jump > around if the terminal width is just right so that the shorter label makes > the status line 1 line long, and the longer label makes it 2 lines long. > > This patch formats the selected status into a fixed-width field. The field > width is the maximum of the lengths of the two possible labels, to account for > differing translations and label lengths. This should make the label behavior > uniform across localizations. > > There does not seem to be a test for crecord, so I verified the change > manually > with a local build of 'hg'. > > diff -r 03039ff3082b -r 4a5fd64feb90 mercurial/crecord.py > --- a/mercurial/crecord.pyTue Aug 01 17:53:48 2017 +0200 > +++ b/mercurial/crecord.pySun Aug 13 00:17:13 2017 -0700 > @@ -1010,6 +1010,13 @@ > def _getstatuslinesegments(self): > """-> [str]. return segments""" > selected = self.currentselecteditem.applied > +spaceselect = _('space: select') > +spacedeselect = _('space: deselect') > +# Format the selected label into a place as long as the longer of the > +# two possible labels. This may vary by language. > +spacelen = max(len(spaceselect), len(spacedeselect)) > +selectedlabel = '%-*s' % (spacelen, > + spacedeselect if selected else spaceselect) > segments = [ > _headermessages[self.operation], > '-', > @@ -1017,7 +1024,7 @@ > _('c: confirm'), > _('q: abort'), > _('arrow keys: move/expand/collapse'), > -_('space: deselect') if selected else _('space: select'), > +selectedlabel, > _('?: help'), > ] > return segments ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D352: chgserver: special handle __version__ in mtimehash (issue5653)
quark added a comment. I will test it on a Mac tomorrow. I think this patch is optional (nice to have). FB also has some weird reports that suggest demandimport is causing chg to load a mix of old and new modules. So the first two patches are more important in terms of correctness. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D352 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D340: rebase: prefer choosing merge base with successor in destination
quark planned changes to this revision. quark added a comment. Since the "unwanted" warning "covers" the case this patch handles. The behavior is still "correct" (since the warning is printed) without this patch. I'm leaning towards dropping this patch. For errors vs warnings, I still think it's better to give power users a chance to proceed. How do you think about this approach? - If there are multiple merge base candidates, calculate "unwanted" revsets for both, and if only one of them is empty, pick that one automatically and proceed. - If both merge base candidates have "unwanted" revsets, raise `error.InterventionRequired` so power users could still have a chance to proceed fixing them manually. INLINE COMMENTS > martinvonz wrote in rebase.py:1115 > And if there are more ancestors of B, will the "rebasing %d:%s may include > unwanted changes" warning appear? > > Regardless, if B adds file B and the merge in C involves removing file B, > then the total diff will be empty. Does that mean that C' will be empty? It > should be reverting B', right? (The same thing applies if it's not a whole > file that gets added/removed, of course.) I think I'd prefer to be > conservative here and error out until we have a safe answer to these merges > that won't risk resulting in surprising contents. In this particular case, > the user can work around it by first rebasing "B+C" only (but that may be > tricky to realize). > And if there are more ancestors of B, will the "rebasing %d:%s may include > unwanted changes" warning appear? Yes. In that case maybe either way is suboptimal. The troublesome cases are: - A merge base candidate has a successor in destination with *different* content - A merge base candidate has "unwanted" ancestors that are not covered by rebaseset I think the problem of this patch is it assumes "different" content blindly. It would be better to actually have a quick check about whether that is the case. Thinking about it again, most cases the reason a commit is in destination is because of a rebase so its content does not change. Therefore this patch is about a very corner case that may not worth the complexity. > Regardless, if B adds file B and the merge in C involves removing file B, > then the total diff will be empty. That is a surprise to me. Apparently you know merge better than I am :) > martinvonz wrote in test-rebase-obsolete.t:1180 > Why do we want/need rebaseskipobsolete? I was expecting to see a test case > like then one in the documentation you added i rebase.py. Not sure why I added that. But it does seem to be unnecessary. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D340 To: quark, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: Kill off contrib/simplemerge?
> Is it used by "hg merge/rebase/etc"? Only if you pass --tool ? No to the first, and I'm not sure if it'd work for the second. If so it'd be duplicating what simplemerge.py already does. In general -- no idea how this is being used. I suspect people might be using it to just to use hg's merge logic in arbitrary locations out of convenience. In the meanwhile on IRC, Jun voiced for its inclusion and Augie and I were able to workout an alternative design* to save it that might be acceptable to everyone. So we might not need to kill it after all. * The proposal is: - add `decodeddata()` to filectx which returns data after running repo filter hooks (see comment in D374 for why) - simplemege will call this function - contrib/simplemerge then passes a filectx-like object whose `decodeddata()` returns the data read off disk On Tue, Aug 15, 2017 at 2:56 PM, Martin von Zweigbergk via Mercurial-develwrote: > What is the script used for? Is it used by "hg merge/rebase/etc"? Only > if you pass --tool ? Not at all? > > On Tue, Aug 15, 2017 at 2:52 PM, Phillip Cohen wrote: >> Hello, >> >> During some of the work to support in-memory merge, the >> `contrib/simplemerge` script (not to be confused with simplemerge.py >> in the mercurial package) has come up as a bit of a roadblock that >> makes existing code messier, and I was wondering if anyone would >> object if we removed it. >> >> This is a Python script that merges arbitrary files. It imports >> Mercurial code but doesn't have access to a repo object, or anything >> relying on one, which is where our troubles begin. To support >> in-memory merge we'd like to only support context objects so that >> making them backed by memory is trivial. But contrib/simplemerge can't >> create context objects. >> >> My existing stack (D377 - D383) refactors simplemerge.py to support >> both use cases, but reviewers have pointed out that this is unwieldy >> and asked if we can just nuke the contrib script instead. I'd happily >> support that if there are no complaints. >> >> timeless traced this script back to abd66eb0, an mpm commit from 2008 >> which moved the three-way merge script into core hg. It's likely the >> contrib script was kept around to support existing workflows at the >> time, 9 years ago. We haven't been able to find any uses of it in the >> codebase or anyone who uses it. >> >> Thanks! >> >> Phil >> ___ >> 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
D359: pushvars: add a coreconfigitem for push.pushvars.server
This revision was automatically updated to reflect the committed changes. Closed by commit rHG057d31ceace3: pushvars: add a coreconfigitem for push.pushvars.server (authored by pulkit). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D359?vs=820=963 REVISION DETAIL https://phab.mercurial-scm.org/D359 AFFECTED FILES mercurial/bundle2.py mercurial/configitems.py CHANGE DETAILS diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -361,6 +361,9 @@ coreconfigitem('progress', 'width', default=dynamicdefault, ) +coreconfigitem('push', 'pushvars.server', +default=False, +) coreconfigitem('server', 'bundle1', default=True, ) diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -1883,7 +1883,7 @@ def bundle2getvars(op, part): '''unbundle a bundle2 containing shellvars on the server''' # An option to disable unbundling on server-side for security reasons -if op.ui.configbool('push', 'pushvars.server', False): +if op.ui.configbool('push', 'pushvars.server'): hookargs = {} for key, value in part.advisoryparams: key = key.upper() To: pulkit, #hg-reviewers, lothiraldan Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: Kill off contrib/simplemerge?
What is the script used for? Is it used by "hg merge/rebase/etc"? Only if you pass --tool ? Not at all? On Tue, Aug 15, 2017 at 2:52 PM, Phillip Cohenwrote: > Hello, > > During some of the work to support in-memory merge, the > `contrib/simplemerge` script (not to be confused with simplemerge.py > in the mercurial package) has come up as a bit of a roadblock that > makes existing code messier, and I was wondering if anyone would > object if we removed it. > > This is a Python script that merges arbitrary files. It imports > Mercurial code but doesn't have access to a repo object, or anything > relying on one, which is where our troubles begin. To support > in-memory merge we'd like to only support context objects so that > making them backed by memory is trivial. But contrib/simplemerge can't > create context objects. > > My existing stack (D377 - D383) refactors simplemerge.py to support > both use cases, but reviewers have pointed out that this is unwieldy > and asked if we can just nuke the contrib script instead. I'd happily > support that if there are no complaints. > > timeless traced this script back to abd66eb0, an mpm commit from 2008 > which moved the three-way merge script into core hg. It's likely the > contrib script was kept around to support existing workflows at the > time, 9 years ago. We haven't been able to find any uses of it in the > codebase or anyone who uses it. > > Thanks! > > Phil > ___ > 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
Kill off contrib/simplemerge?
Hello, During some of the work to support in-memory merge, the `contrib/simplemerge` script (not to be confused with simplemerge.py in the mercurial package) has come up as a bit of a roadblock that makes existing code messier, and I was wondering if anyone would object if we removed it. This is a Python script that merges arbitrary files. It imports Mercurial code but doesn't have access to a repo object, or anything relying on one, which is where our troubles begin. To support in-memory merge we'd like to only support context objects so that making them backed by memory is trivial. But contrib/simplemerge can't create context objects. My existing stack (D377 - D383) refactors simplemerge.py to support both use cases, but reviewers have pointed out that this is unwieldy and asked if we can just nuke the contrib script instead. I'd happily support that if there are no complaints. timeless traced this script back to abd66eb0, an mpm commit from 2008 which moved the three-way merge script into core hg. It's likely the contrib script was kept around to support existing workflows at the time, 9 years ago. We haven't been able to find any uses of it in the codebase or anyone who uses it. Thanks! Phil ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D126: phabricator: add status to revision query language
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfb59192b4981: phabricator: add status to revision query language (authored by quark). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D126?vs=841=960 REVISION DETAIL https://phab.mercurial-scm.org/D126 AFFECTED FILES contrib/phabricator.py CHANGE DETAILS diff --git a/contrib/phabricator.py b/contrib/phabricator.py --- a/contrib/phabricator.py +++ b/contrib/phabricator.py @@ -488,6 +488,13 @@ return True +_knownstatusnames = {'accepted', 'needsreview', 'needsrevision', 'closed', + 'abandoned'} + +def _getstatusname(drev): +"""get normalized status name from a Differential Revision""" +return drev[r'statusName'].replace(' ', '').lower() + # Small language to specify differential revisions. Support symbols: (), :X, # +, and -. @@ -504,19 +511,19 @@ } def _tokenize(text): -text = text.replace(' ', '') # remove space view = memoryview(text) # zero-copy slice -special = '():+-&' +special = '():+-& ' pos = 0 length = len(text) while pos < length: symbol = ''.join(itertools.takewhile(lambda ch: ch not in special, view[pos:])) if symbol: yield ('symbol', symbol, pos) pos += len(symbol) -else: # special char -yield (text[pos], None, pos) +else: # special char, ignore space +if text[pos] != ' ': +yield (text[pos], None, pos) pos += 1 yield ('end', None, pos) @@ -644,15 +651,19 @@ tofetch.update(range(max(1, r - batchsize), r + 1)) if drevs: fetch({r'ids': list(tofetch)}) -getstack(list(ancestordrevs)) +validids = sorted(set(getstack(list(ancestordrevs))) | set(drevs)) # Walk through the tree, return smartsets def walk(tree): op = tree[0] if op == 'symbol': drev = _parsedrev(tree[1]) if drev: return smartset.baseset([drev]) +elif tree[1] in _knownstatusnames: +drevs = [r for r in validids + if _getstatusname(prefetched[r]) == tree[1]] +return smartset.baseset(drevs) else: raise error.Abort(_('unknown symbol: %s') % tree[1]) elif op in {'and_', 'add', 'sub'}: @@ -772,8 +783,13 @@ ``&``, ``(``, ``)`` for complex queries. Prefix ``:`` could be used to select a stack. +``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision`` +could be used to filter patches by status. For performance reason, they +only represent a subset of non-status selections and cannot be used alone. + For example, ``:D6+8-(2+D4)`` selects a stack up to D6, plus D8 and exclude -D2 and D4. +D2 and D4. ``:D9 & needsreview`` selects "Needs Review" revisions in a +stack up to D9. If --stack is given, follow dependencies information and read all patches. It is equivalent to the ``:`` operator. To: quark, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D125: phabricator: add a small language to query Differential Revisions
This revision was automatically updated to reflect the committed changes. Closed by commit rHG539541779010: phabricator: add a small language to query Differential Revisions (authored by quark). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D125?vs=840=961 REVISION DETAIL https://phab.mercurial-scm.org/D125 AFFECTED FILES contrib/phabricator.py CHANGE DETAILS diff --git a/contrib/phabricator.py b/contrib/phabricator.py --- a/contrib/phabricator.py +++ b/contrib/phabricator.py @@ -32,7 +32,9 @@ from __future__ import absolute_import +import itertools import json +import operator import re from mercurial.node import bin, nullid @@ -44,9 +46,11 @@ error, mdiff, obsutil, +parser, patch, registrar, scmutil, +smartset, tags, url as urlmod, util, @@ -484,11 +488,77 @@ return True -def querydrev(repo, params, stack=False): +# Small language to specify differential revisions. Support symbols: (), :X, +# +, and -. + +_elements = { +# token-type: binding-strength, primary, prefix, infix, suffix +'(': (12, None, ('group', 1, ')'), None, None), +':': (8, None, ('ancestors', 8), None, None), +'&': (5, None, None, ('and_', 5), None), +'+': (4, None, None, ('add', 4), None), +'-': (4, None, None, ('sub', 4), None), +')': (0, None, None, None, None), +'symbol': (0, 'symbol', None, None, None), +'end':(0, None, None, None, None), +} + +def _tokenize(text): +text = text.replace(' ', '') # remove space +view = memoryview(text) # zero-copy slice +special = '():+-&' +pos = 0 +length = len(text) +while pos < length: +symbol = ''.join(itertools.takewhile(lambda ch: ch not in special, + view[pos:])) +if symbol: +yield ('symbol', symbol, pos) +pos += len(symbol) +else: # special char +yield (text[pos], None, pos) +pos += 1 +yield ('end', None, pos) + +def _parse(text): +tree, pos = parser.parser(_elements).parse(_tokenize(text)) +if pos != len(text): +raise error.ParseError('invalid token', pos) +return tree + +def _parsedrev(symbol): +"""str -> int or None, ex. 'D45' -> 45; '12' -> 12; 'x' -> None""" +if symbol.startswith('D') and symbol[1:].isdigit(): +return int(symbol[1:]) +if symbol.isdigit(): +return int(symbol) + +def _prefetchdrevs(tree): +"""return ({single-drev-id}, {ancestor-drev-id}) to prefetch""" +drevs = set() +ancestordrevs = set() +op = tree[0] +if op == 'symbol': +r = _parsedrev(tree[1]) +if r: +drevs.add(r) +elif op == 'ancestors': +r, a = _prefetchdrevs(tree[1]) +drevs.update(r) +ancestordrevs.update(r) +ancestordrevs.update(a) +else: +for t in tree[1:]: +r, a = _prefetchdrevs(t) +drevs.update(r) +ancestordrevs.update(a) +return drevs, ancestordrevs + +def querydrev(repo, spec): """return a list of "Differential Revision" dicts -params is the input of "differential.query" API, and is expected to match -just a single Differential Revision. +spec is a string using a simple query language, see docstring in phabread +for details. A "Differential Revision dict" looks like: @@ -525,51 +595,77 @@ "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv", "sourcePath": null } - -If stack is True, return a list of "Differential Revision dict"s in an -order that the latter ones depend on the former ones. Otherwise, return a -list of a unique "Differential Revision dict". """ -prefetched = {} # {id or phid: drev} def fetch(params): """params -> single drev or None""" key = (params.get(r'ids') or params.get(r'phids') or [None])[0] if key in prefetched: return prefetched[key] -# Otherwise, send the request. If we're fetching a stack, be smarter -# and fetch more ids in one batch, even if it could be unnecessary. -batchparams = params -if stack and len(params.get(r'ids', [])) == 1: -i = int(params[r'ids'][0]) -# developer config: phabricator.batchsize -batchsize = repo.ui.configint('phabricator', 'batchsize', 12) -batchparams = {'ids': range(max(1, i - batchsize), i + 1)} -drevs = callconduit(repo, 'differential.query', batchparams) +drevs = callconduit(repo, 'differential.query', params) # Fill prefetched with the result for drev in drevs: prefetched[drev[r'phid']] = drev prefetched[int(drev[r'id'])] = drev if key not in prefetched: raise error.Abort(_('cannot get Differential Revision %r') % params) return
D127: phabricator: add phabupdate command to update status in batch
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6e666cd59879: phabricator: add phabupdate command to update status in batch (authored by quark). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D127?vs=842=962 REVISION DETAIL https://phab.mercurial-scm.org/D127 AFFECTED FILES contrib/phabricator.py CHANGE DETAILS diff --git a/contrib/phabricator.py b/contrib/phabricator.py --- a/contrib/phabricator.py +++ b/contrib/phabricator.py @@ -9,7 +9,7 @@ This extension provides a ``phabsend`` command which sends a stack of changesets to Phabricator without amending commit messages, and a ``phabread`` command which prints a stack of revisions in a format suitable -for :hg:`import`. +for :hg:`import`, and a ``phabupdate`` command to update statuses in batch. By default, Phabricator requires ``Test Plan`` which might prevent some changeset from being sent. The requirement could be disabled by changing @@ -798,3 +798,32 @@ spec = ':(%s)' % spec drevs = querydrev(repo, spec) readpatch(repo, drevs, ui.write) + +@command('phabupdate', + [('', 'accept', False, _('accept revisions')), + ('', 'reject', False, _('reject revisions')), + ('', 'abandon', False, _('abandon revisions')), + ('', 'reclaim', False, _('reclaim revisions')), + ('m', 'comment', '', _('comment on the last revision')), + ], _('DREVSPEC [OPTIONS]')) +def phabupdate(ui, repo, spec, **opts): +"""update Differential Revision in batch + +DREVSPEC selects revisions. See :hg:`help phabread` for its usage. +""" +flags = [n for n in 'accept reject abandon reclaim'.split() if opts.get(n)] +if len(flags) > 1: +raise error.Abort(_('%s cannot be used together') % ', '.join(flags)) + +actions = [] +for f in flags: +actions.append({'type': f, 'value': 'true'}) + +drevs = querydrev(repo, spec) +for i, drev in enumerate(drevs): +if i + 1 == len(drevs) and opts.get('comment'): +actions.append({'type': 'comment', 'value': opts['comment']}) +if actions: +params = {'objectIdentifier': drev[r'phid'], + 'transactions': actions} +callconduit(repo, 'differential.revision.edit', params) To: quark, #hg-reviewers, durin42 Cc: durin42, krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D124: phabricator: change "readpatch" to be more flexible
This revision was automatically updated to reflect the committed changes. Closed by commit rHG75fdaf851e83: phabricator: change "readpatch" to be more flexible (authored by quark). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D124?vs=839=959 REVISION DETAIL https://phab.mercurial-scm.org/D124 AFFECTED FILES contrib/phabricator.py CHANGE DETAILS diff --git a/contrib/phabricator.py b/contrib/phabricator.py --- a/contrib/phabricator.py +++ b/contrib/phabricator.py @@ -635,15 +635,12 @@ meta[r'parent'] = commit[r'parents'][0] return meta or {} -def readpatch(repo, params, write, stack=False): +def readpatch(repo, drevs, write): """generate plain-text patch readable by 'hg import' -write is usually ui.write. params is passed to "differential.query". If -stack is True, also write dependent patches. +write is usually ui.write. drevs is what "querydrev" returns, results of +"differential.query". """ -# Differential Revisions -drevs = querydrev(repo, params, stack) - # Prefetch hg:meta property for all diffs diffids = sorted(set(max(int(v) for v in drev[r'diffs']) for drev in drevs)) diffs = callconduit(repo, 'differential.querydiffs', {'ids': diffids}) @@ -683,4 +680,5 @@ revid = int(revid.split('/')[-1].replace('D', '')) except ValueError: raise error.Abort(_('invalid Revision ID: %s') % revid) -readpatch(repo, {'ids': [revid]}, ui.write, opts.get('stack')) +drevs = querydrev(repo, {'ids': [revid]}, opts.get('stack')) +readpatch(repo, drevs, ui.write) To: quark, #hg-reviewers, mitrandir, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D127: phabricator: add phabupdate command to update status in batch
durin42 accepted this revision. durin42 added a comment. This revision is now accepted and ready to land. queued, thanks REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D127 To: quark, #hg-reviewers, durin42 Cc: durin42, krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D126: phabricator: add status to revision query language
durin42 accepted this revision. durin42 added a comment. This revision is now accepted and ready to land. queued, thanks REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D126 To: quark, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D377: simplemerge: add `filtereddata=False` to simplemerge()
durin42 added a comment. Also, timeless noticed https://phab.mercurial-scm.org/rHGabd66eb0889e3efaca4f960e0eacd719c18880dd, which reinforces my belief that we don't need contrib/simplemerge anymore. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D377 To: phillco, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D377: simplemerge: add `filtereddata=False` to simplemerge()
durin42 added a comment. (from an IRC conversation) I'm not crazy about the shape this makes the API, as I'd rather we didn't start growing awareness of filtering in layers this high. I think we can probably kill contrib/simplemerge entirely - it's had nothing but cleanup changes and a feature removal since May of 2007, and I can't fathom a use for it today. Let's see if we can get consensus around that on the mailing lists and then hopefully simplify this a TON. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D377 To: phillco, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D376: filemerge: extract `_picklabels` as a helper function
This revision was automatically updated to reflect the committed changes. Closed by commit rHGaa6c290a77fa: filemerge: extract `_picklabels` as a helper function (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D376?vs=857=958 REVISION DETAIL https://phab.mercurial-scm.org/D376 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -408,6 +408,20 @@ raise error.Abort(msg) return text +def _picklabels(defaults, overrides): +name_a, name_b, name_base = defaults + +if len(overrides) > 0: +name_a = overrides[0] +if len(overrides) > 1: +name_b = overrides[1] +if len(overrides) > 2: +name_base = overrides[2] +if len(overrides) > 3: +raise error.Abort(_("can only specify three labels.")) + +return [name_a, name_b, name_base] + def simplemerge(ui, localfile, basefile, otherfile, localctx=None, basectx=None, otherctx=None, repo=None, **opts): """Performs the simplemerge algorithm. @@ -446,23 +460,11 @@ self.ctx.write(self.text, self.ctx.flags()) mode = opts.get('mode','merge') -if mode == 'union': -name_a = None -name_b = None -name_base = None -else: -name_a = localfile -name_b = otherfile -name_base = None -labels = opts.get('label', []) -if len(labels) > 0: -name_a = labels[0] -if len(labels) > 1: -name_b = labels[1] -if len(labels) > 2: -name_base = labels[2] -if len(labels) > 3: -raise error.Abort(_("can only specify three labels.")) +name_a, name_b, name_base = None, None, None +if mode != 'union': +name_a, name_b, name_base = _picklabels([localfile, + otherfile, None], +opts.get('label', [])) try: localtext = readctx(localctx) if localctx else readfile(localfile) To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D375: simplemerge: write merge result to the localctx, if passed
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb86fc43e4b73: simplemerge: write merge result to the localctx, if passed (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D375?vs=856=957 REVISION DETAIL https://phab.mercurial-scm.org/D375 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -413,8 +413,8 @@ """Performs the simplemerge algorithm. {local|base|other}ctx are optional. If passed, they (local/base/other) will -be read from. You should pass explicit labels in this mode since the default -is to use the file paths.""" +be read from and the merge result written to (local). You should pass +explicit labels in this mode since the default is to use the file paths.""" def readfile(filename): f = open(filename, "rb") text = f.read() @@ -434,6 +434,17 @@ return repo.wwritedata(ctx.path(), _verifytext(ctx.data(), ctx.path(), ui, opts)) +class ctxwriter(object): +def __init__(self, ctx): +self.ctx = ctx +self.text = "" + +def write(self, text): +self.text += text + +def close(self): +self.ctx.write(self.text, self.ctx.flags()) + mode = opts.get('mode','merge') if mode == 'union': name_a = None @@ -460,12 +471,14 @@ except error.Abort: return 1 -localfile = os.path.realpath(localfile) -if not opts.get('print'): +if opts.get('print'): +out = ui.fout +elif localctx: +out = ctxwriter(localctx) +else: +localfile = os.path.realpath(localfile) opener = vfsmod.vfs(os.path.dirname(localfile)) out = opener(os.path.basename(localfile), "w", atomictemp=True) -else: -out = ui.fout m3 = Merge3Text(basetext, localtext, othertext) extrakwargs = { To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D406: commit: use context manager with dirstateguard
This revision was automatically updated to reflect the committed changes. Closed by commit rHG158dddc635ff: commit: use context manager with dirstateguard (authored by martinvonz). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D406?vs=922=952 REVISION DETAIL https://phab.mercurial-scm.org/D406 AFFECTED FILES mercurial/cmdutil.py CHANGE DETAILS diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -3000,19 +3000,13 @@ # that doesn't support addremove if opts.get('addremove'): dsguard = dirstateguard.dirstateguard(repo, 'commit') -try: +with dsguard or util.nullcontextmanager(): if dsguard: if scmutil.addremove(repo, matcher, "", opts) != 0: raise error.Abort( _("failed to mark all new/missing files as added/removed")) -r = commitfunc(ui, repo, message, matcher, opts) -if dsguard: -dsguard.close() -return r -finally: -if dsguard: -dsguard.release() +return commitfunc(ui, repo, message, matcher, opts) def samefile(f, ctx1, ctx2): if f in ctx1.manifest(): To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D371: simplemerge: extract verifytext as a helper function
This revision was automatically updated to reflect the committed changes. Closed by commit rHGde573184686e: simplemerge: extract verifytext as a helper function (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D371?vs=852=953 REVISION DETAIL https://phab.mercurial-scm.org/D371 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -397,18 +397,23 @@ return unc +def _verifytext(text, path, ui, opts): +"""verifies that text is non-binary (unless opts[text] is passed, +then we just warn)""" +if util.binary(text): +msg = _("%s looks like a binary file.") % path +if not opts.get('quiet'): +ui.warn(_('warning: %s\n') % msg) +if not opts.get('text'): +raise error.Abort(msg) +return text + def simplemerge(ui, local, base, other, **opts): def readfile(filename): f = open(filename, "rb") text = f.read() f.close() -if util.binary(text): -msg = _("%s looks like a binary file.") % filename -if not opts.get('quiet'): -ui.warn(_('warning: %s\n') % msg) -if not opts.get('text'): -raise error.Abort(msg) -return text +return _verifytext(text, filename, ui, opts) mode = opts.get('mode','merge') if mode == 'union': To: phillco, #hg-reviewers, smf Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D373: filemerge: pass contexts to simplemerge
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdb3e9f7c91aa: filemerge: pass contexts to simplemerge (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D373?vs=854=956 REVISION DETAIL https://phab.mercurial-scm.org/D373 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -341,7 +341,8 @@ labels = _defaultconflictlabels if len(labels) < 3: labels.append('base') -r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels) +r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco, +quiet=True, label=labels, repo=repo) if not r: ui.debug(" premerge successful\n") return 0 @@ -371,7 +372,8 @@ ui = repo.ui -r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode) +r = simplemerge.simplemerge(ui, a, b, c, fcd, fca, fco, +label=labels, mode=mode, repo=repo) return True, r, False @internaltool('union', fullmerge, @@ -423,8 +425,9 @@ assert localorother is not None tool, toolpath, binary, symlink = toolconf a, b, c, back = files -r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels, -localorother=localorother) +r = simplemerge.simplemerge(repo.ui, a, b, c, fcd, fca, fco, +label=labels, localorother=localorother, +repo=repo) return True, r @internaltool('merge-local', mergeonly, precheck=_mergecheck) To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D405: commit: move dirstateguard creation out of try-block
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5d286eb7009f: commit: move dirstateguard creation out of try-block (authored by martinvonz). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D405?vs=921=951 REVISION DETAIL https://phab.mercurial-scm.org/D405 AFFECTED FILES mercurial/cmdutil.py CHANGE DETAILS diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2998,9 +2998,10 @@ dsguard = None # extract addremove carefully -- this function can be called from a command # that doesn't support addremove +if opts.get('addremove'): +dsguard = dirstateguard.dirstateguard(repo, 'commit') try: -if opts.get('addremove'): -dsguard = dirstateguard.dirstateguard(repo, 'commit') +if dsguard: if scmutil.addremove(repo, matcher, "", opts) != 0: raise error.Abort( _("failed to mark all new/missing files as added/removed")) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D374: simplemerge: use contexts to read file data from, if passed
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8b91a4ff23ad: simplemerge: use contexts to read file data from, if passed (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D374?vs=855=955 REVISION DETAIL https://phab.mercurial-scm.org/D374 AFFECTED FILES mercurial/simplemerge.py tests/test-lfconvert.t CHANGE DETAILS diff --git a/tests/test-lfconvert.t b/tests/test-lfconvert.t --- a/tests/test-lfconvert.t +++ b/tests/test-lfconvert.t @@ -128,7 +128,7 @@ $ hg merge merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat merging sub/normal2 and stuff/normal2 to stuff/normal2 - warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. (glob) + warning: stuff/maybelarge.dat looks like a binary file. (glob) warning: conflicts while merging stuff/maybelarge.dat! (edit, then use 'hg resolve --mark') 0 files updated, 1 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -410,12 +410,30 @@ def simplemerge(ui, localfile, basefile, otherfile, localctx=None, basectx=None, otherctx=None, repo=None, **opts): +"""Performs the simplemerge algorithm. + +{local|base|other}ctx are optional. If passed, they (local/base/other) will +be read from. You should pass explicit labels in this mode since the default +is to use the file paths.""" def readfile(filename): f = open(filename, "rb") text = f.read() f.close() return _verifytext(text, filename, ui, opts) +def readctx(ctx): +if not ctx: +return None +if not repo: +raise error.ProgrammingError('simplemerge: repo must be passed if ' + 'using contexts') +# `wwritedata` is used to get the post-filter data from `ctx` (i.e., +# what would have been in the working copy). Since merges were run in +# the working copy, and thus used post-filter data, we do the same to +# maintain behavior. +return repo.wwritedata(ctx.path(), + _verifytext(ctx.data(), ctx.path(), ui, opts)) + mode = opts.get('mode','merge') if mode == 'union': name_a = None @@ -436,9 +454,9 @@ raise error.Abort(_("can only specify three labels.")) try: -localtext = readfile(localfile) -basetext = readfile(basefile) -othertext = readfile(otherfile) +localtext = readctx(localctx) if localctx else readfile(localfile) +basetext = readctx(basectx) if basectx else readfile(basefile) +othertext = readctx(otherctx) if otherctx else readfile(otherfile) except error.Abort: return 1 To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D372: simplemerge: add optional context parameters to simplemerge
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb3571dc0e6b8: simplemerge: add optional context parameters to simplemerge (authored by phillco). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D372?vs=853=954 REVISION DETAIL https://phab.mercurial-scm.org/D372 AFFECTED FILES mercurial/simplemerge.py CHANGE DETAILS diff --git a/mercurial/simplemerge.py b/mercurial/simplemerge.py --- a/mercurial/simplemerge.py +++ b/mercurial/simplemerge.py @@ -408,7 +408,8 @@ raise error.Abort(msg) return text -def simplemerge(ui, local, base, other, **opts): +def simplemerge(ui, localfile, basefile, otherfile, +localctx=None, basectx=None, otherctx=None, repo=None, **opts): def readfile(filename): f = open(filename, "rb") text = f.read() @@ -421,8 +422,8 @@ name_b = None name_base = None else: -name_a = local -name_b = other +name_a = localfile +name_b = otherfile name_base = None labels = opts.get('label', []) if len(labels) > 0: @@ -435,16 +436,16 @@ raise error.Abort(_("can only specify three labels.")) try: -localtext = readfile(local) -basetext = readfile(base) -othertext = readfile(other) +localtext = readfile(localfile) +basetext = readfile(basefile) +othertext = readfile(otherfile) except error.Abort: return 1 -local = os.path.realpath(local) +localfile = os.path.realpath(localfile) if not opts.get('print'): -opener = vfsmod.vfs(os.path.dirname(local)) -out = opener(os.path.basename(local), "w", atomictemp=True) +opener = vfsmod.vfs(os.path.dirname(localfile)) +out = opener(os.path.basename(localfile), "w", atomictemp=True) else: out = ui.fout To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D409: copies: add more details to the documentation of mergecopies()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG42ad7cc645a4: copies: add more details to the documentation of mergecopies() (authored by pulkit). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D409?vs=942=950 REVISION DETAIL https://phab.mercurial-scm.org/D409 AFFECTED FILES mercurial/copies.py CHANGE DETAILS diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -304,6 +304,28 @@ def mergecopies(repo, c1, c2, base): """ +The basic algorithm for copytracing. Copytracing is used in commands like +rebase, merge, unshelve, etc to merge files that were moved/ copied in one +merge parent and modified in another. For example: + +o ---> 4 another commit +| +| o ---> 3 commit that modifies a.txt +| / +o /---> 2 commit that moves a.txt to b.txt +|/ +o ---> 1 merge base + +If we try to rebase revision 3 on revision 4, since there is no a.txt in +revision 4, and if user have copytrace disabled, we prints the following +message: + +```other changed which local deleted``` + +If copytrace is enabled, this function finds all the new files that were +added from merge base up to the top commit (here 4), and for each file it +checks if this file was copied from another file (a.txt in the above case). + Find moves and copies between context c1 and c2 that are relevant for merging. 'base' will be used as the merge base. To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D231: httppeer: add support for httppostargs when we're sending a file
This revision was automatically updated to reflect the committed changes. Closed by commit rHG3c91cc0c5fde: httppeer: add support for httppostargs when we're sending a file (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D231?vs=745=949 REVISION DETAIL https://phab.mercurial-scm.org/D231 AFFECTED FILES mercurial/hgweb/protocol.py mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -9,6 +9,7 @@ from __future__ import absolute_import import errno +import io import os import socket import struct @@ -86,6 +87,45 @@ resp.__class__ = readerproxy +class _multifile(object): +def __init__(self, *fileobjs): +for f in fileobjs: +if not util.safehasattr(f, 'length'): +raise ValueError( +'_multifile only supports file objects that ' +'have a length but this one does not:', type(f), f) +self._fileobjs = fileobjs +self._index = 0 + +@property +def length(self): +return sum(f.length for f in self._fileobjs) + +def read(self, amt=None): +if amt <= 0: +return ''.join(f.read() for f in self._fileobjs) +parts = [] +while amt and self._index < len(self._fileobjs): +parts.append(self._fileobjs[self._index].read(amt)) +got = len(parts[-1]) +if got < amt: +self._index += 1 +amt -= got +return ''.join(parts) + +def seek(self, offset, whence=os.SEEK_SET): +if whence != os.SEEK_SET: +raise NotImplementedError( +'_multifile does not support anything other' +' than os.SEEK_SET for whence on seek()') +if offset != 0: +raise NotImplementedError( +'_multifile only supports seeking to start, but that ' +'could be fixed if you need it') +for f in self._fileobjs: +f.seek(0) +self._index = 0 + class httppeer(wireproto.wirepeer): def __init__(self, ui, path): self._path = path @@ -169,17 +209,19 @@ # with infinite recursion when trying to look up capabilities # for the first time. postargsok = self._caps is not None and 'httppostargs' in self._caps -# TODO: support for httppostargs when data is a file-like -# object rather than a basestring -canmungedata = not data or isinstance(data, basestring) -if postargsok and canmungedata: +if postargsok and args: strargs = urlreq.urlencode(sorted(args.items())) -if strargs: -if not data: -data = strargs -elif isinstance(data, basestring): -data = strargs + data -headers['X-HgArgs-Post'] = len(strargs) +if not data: +data = strargs +else: +if isinstance(data, basestring): +i = io.BytesIO(data) +i.length = len(data) +data = i +argsio = io.BytesIO(strargs) +argsio.length = len(strargs) +data = _multifile(argsio, data) +headers['X-HgArgs-Post'] = len(strargs) else: if len(args) > 0: httpheader = self.capable('httpheader') diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py --- a/mercurial/hgweb/protocol.py +++ b/mercurial/hgweb/protocol.py @@ -75,6 +75,9 @@ return args def getfile(self, fp): length = int(self.req.env['CONTENT_LENGTH']) +# If httppostargs is used, we need to read Content-Length +# minus the amount that was consumed by args. +length -= int(self.req.env.get('HTTP_X_HGARGS_POST', 0)) for s in util.filechunkiter(self.req, limit=length): fp.write(s) def redirect(self): To: durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2 STABLE V2] ui: restore behavior to ignore some I/O errors (issue5658)
# HG changeset patch # User Gregory Szorc# Date 1502827471 25200 # Tue Aug 15 13:04:31 2017 -0700 # Branch stable # Node ID 4295728e1d039be477bf5b72c9b6c34fd406e020 # Parent 0d5b565629f0491a7673fcfdd9c02cbc1a4b ui: restore behavior to ignore some I/O errors (issue5658) e9646ff34d55 and 1bfb9a63b98e refactored ui methods to no longer silently swallow some IOError instances. This is arguably the correct thing to do. However, it had the unfortunate side-effect of causing StdioError to bubble up to sensitive code like transaction aborts, leading to an uncaught exceptions and failures to e.g. roll back a transaction. This could occur when a remote HTTP or SSH client connection dropped. The new behavior is resulting in semi-frequent "abandonded transaction" errors on multiple high-volume repositories at Mozilla. This commit effectively reverts e9646ff34d55 and 1bfb9a63b98e to restore the old behavior. I agree with the principle that I/O errors shouldn't be ignored. That makes this change... unfortunate. However, our hands are tied for what to do on stable. I think the proper solution is for the ui's behavior to be configurable (possibly via a context manager). During critical sections like transaction rollback and abort, it should be possible to suppress errors. But this feature would not be appropriate on stable. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -904,7 +904,8 @@ class ui(object): if not getattr(self.ferr, 'closed', False): self.ferr.flush() except IOError as inst: -raise error.StdioError(inst) +if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): +raise error.StdioError(inst) def flush(self): # opencode timeblockedsection because this is a critical path @@ -913,12 +914,14 @@ class ui(object): try: self.fout.flush() except IOError as err: -raise error.StdioError(err) +if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): +raise error.StdioError(err) finally: try: self.ferr.flush() except IOError as err: -raise error.StdioError(err) +if err.errno not in (errno.EPIPE, errno.EIO, errno.EBADF): +raise error.StdioError(err) finally: self._blockedtimes['stdio_blocked'] += \ (util.timer() - starttime) * 1000 diff --git a/tests/test-rollback.t b/tests/test-rollback.t --- a/tests/test-rollback.t +++ b/tests/test-rollback.t @@ -302,16 +302,12 @@ An I/O error during pretxncommit is hand warn during txnclose $ echo 1 > foo $ hg --config ui.ioerrors=pretxncommit commit -m 'error during pretxncommit' - error: pretxncommit.badui hook raised an exception: [Errno *] simulated epipe (glob) - transaction abort! - warn during abort - rollback completed - [255] + warn during pretxnclose + warn during txnclose $ hg commit -m 'commit 1' - warn during pretxncommit - warn during pretxnclose - warn during txnclose + nothing changed + [1] $ cd .. @@ -328,17 +324,11 @@ An I/O error during pretxnclose is handl $ echo 1 > foo $ hg --config ui.ioerrors=pretxnclose commit -m 'error during pretxnclose' warn during pretxncommit - error: pretxnclose.badui hook raised an exception: [Errno *] simulated eio (glob) - transaction abort! - warn during abort - rollback completed - abort: simulated eio - [255] + warn during txnclose $ hg commit -m 'commit 1' - warn during pretxncommit - warn during pretxnclose - warn during txnclose + nothing changed + [1] $ cd .. @@ -356,8 +346,6 @@ An I/O error during txnclose is handled $ hg --config ui.ioerrors=txnclose commit -m 'error during txnclose' warn during pretxncommit warn during pretxnclose - error: txnclose.badui hook raised an exception: [Errno *] simulated badf (glob) - (run with --traceback for stack trace) $ hg commit -m 'commit 1' nothing changed @@ -378,15 +366,15 @@ An I/O error writing "transaction abort" $ echo 1 > foo $ hg --config ui.ioerrors=msgabort --config hooks.pretxncommit=false commit -m 'error during abort message' - abort: simulated ebadf - *: DeprecationWarning: use lock.release instead of del lock (glob) -return -1 + warn during abort + rollback completed + abort: pretxncommit hook exited with status 1 [255] $ hg commit -m 'commit 1' - abort: abandoned transaction found! - (run 'hg recover' to clean up transaction) - [255] + warn during pretxncommit + warn during pretxnclose + warn during txnclose $ cd .. @@ -404,8 +392,6 @@ An I/O error during txnabort should stil $ echo 1 > foo $ hg --config ui.ioerrors=txnabort --config hooks.pretxncommit=false commit -m 'error during abort'
[PATCH 1 of 2 STABLE V2] tests: test behavior of IOError during transactions (issue5658)
# HG changeset patch # User Gregory Szorc# Date 1502741560 25200 # Mon Aug 14 13:12:40 2017 -0700 # Branch stable # Node ID 0d5b565629f0491a7673fcfdd9c02cbc1a4b # Parent 7686cbb0ba4138c56d038d8d82ccc052bf9b60d7 tests: test behavior of IOError during transactions (issue5658) ui._write(), ui._write_err(), and ui.flush() all trap IOError and re-raise as error.StdioError. If a caller doesn't catch StdioError when writing to stdio, it could bubble all the way to dispatch. This commit adds tests for I/O failures around various transaction operations. The most notable badness is during abort. Here, an uncaught StdioError will result in incomplete transaction rollback, requiring an `hg rollback` to recover. This can result in a client "corrupting" a remote repo via terminated HTTP and SSH socket. diff --git a/tests/test-rollback.t b/tests/test-rollback.t --- a/tests/test-rollback.t +++ b/tests/test-rollback.t @@ -210,3 +210,276 @@ rollback disabled by config abort: rollback is disabled because it is unsafe (see `hg help -v rollback` for information) [255] + + $ cd .. + +I/O errors on stdio are handled properly (issue5658) + + $ cat > badui.py << EOF + > import errno + > from mercurial.i18n import _ + > from mercurial import ( + > error, + > ui as uimod, + > ) + > + > def pretxncommit(ui, repo, **kwargs): + > ui.warn('warn during pretxncommit\n') + > + > def pretxnclose(ui, repo, **kwargs): + > ui.warn('warn during pretxnclose\n') + > + > def txnclose(ui, repo, **kwargs): + > ui.warn('warn during txnclose\n') + > + > def txnabort(ui, repo, **kwargs): + > ui.warn('warn during abort\n') + > + > class fdproxy(object): + > def __init__(self, ui, o): + > self._ui = ui + > self._o = o + > + > def __getattr__(self, attr): + > return getattr(self._o, attr) + > + > def write(self, msg): + > errors = set(self._ui.configlist('ui', 'ioerrors', [])) + > pretxncommit = msg == 'warn during pretxncommit\n' + > pretxnclose = msg == 'warn during pretxnclose\n' + > txnclose = msg == 'warn during txnclose\n' + > txnabort = msg == 'warn during abort\n' + > msgabort = msg == _('transaction abort!\n') + > msgrollback = msg == _('rollback completed\n') + > + > if pretxncommit and 'pretxncommit' in errors: + > raise IOError(errno.EPIPE, 'simulated epipe') + > if pretxnclose and 'pretxnclose' in errors: + > raise IOError(errno.EIO, 'simulated eio') + > if txnclose and 'txnclose' in errors: + > raise IOError(errno.EBADF, 'simulated badf') + > if txnabort and 'txnabort' in errors: + > raise IOError(errno.EPIPE, 'simulated epipe') + > if msgabort and 'msgabort' in errors: + > raise IOError(errno.EBADF, 'simulated ebadf') + > if msgrollback and 'msgrollback' in errors: + > raise IOError(errno.EIO, 'simulated eio') + > + > return self._o.write(msg) + > + > def uisetup(ui): + > class badui(ui.__class__): + > def write_err(self, *args, **kwargs): + > olderr = self.ferr + > try: + > self.ferr = fdproxy(self, olderr) + > return super(badui, self).write_err(*args, **kwargs) + > finally: + > self.ferr = olderr + > + > ui.__class__ = badui + > + > def reposetup(ui, repo): + > ui.setconfig('hooks', 'pretxnclose.badui', pretxnclose, 'badui') + > ui.setconfig('hooks', 'txnclose.badui', txnclose, 'badui') + > ui.setconfig('hooks', 'pretxncommit.badui', pretxncommit, 'badui') + > ui.setconfig('hooks', 'txnabort.badui', txnabort, 'badui') + > EOF + + $ cat >> $HGRCPATH << EOF + > [extensions] + > badui = $TESTTMP/badui.py + > EOF + +An I/O error during pretxncommit is handled + + $ hg init ioerror-pretxncommit + $ cd ioerror-pretxncommit + $ echo 0 > foo + $ hg -q commit -A -m initial + warn during pretxncommit + warn during pretxnclose + warn during txnclose + $ echo 1 > foo + $ hg --config ui.ioerrors=pretxncommit commit -m 'error during pretxncommit' + error: pretxncommit.badui hook raised an exception: [Errno *] simulated epipe (glob) + transaction abort! + warn during abort + rollback completed + [255] + + $ hg commit -m 'commit 1' + warn during pretxncommit + warn during pretxnclose + warn during txnclose + + $ cd .. + +An I/O error during pretxnclose is handled + + $ hg init ioerror-pretxnclose + $ cd ioerror-pretxnclose + $ echo 0 > foo + $ hg -q commit -A -m initial + warn during pretxncommit + warn during pretxnclose + warn during txnclose + + $ echo 1 > foo + $ hg --config ui.ioerrors=pretxnclose commit -m 'error during pretxnclose' + warn during pretxncommit + error: pretxnclose.badui hook raised an exception: [Errno *]
D299: py3: introduce a wrapper for __builtins__.{raw_,}input()
durin42 marked 5 inline comments as done. durin42 added inline comments. INLINE COMMENTS > yuja wrote in pycompat.py:84 > Nah. So this could be `util.bytesinput(fin, fout)` and `encoding.strio()`. Sigh. I'm not sure I got the encoding.py bit quite right, take a look? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D299 To: durin42, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D299: py3: introduce a wrapper for __builtins__.{raw_,}input()
durin42 updated this revision to Diff 948. durin42 edited the summary of this revision. durin42 retitled this revision from "pycompat: introduce a wrapper for __builtins__.{raw_,}input()" to "py3: introduce a wrapper for __builtins__.{raw_,}input()". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D299?vs=801=948 REVISION DETAIL https://phab.mercurial-scm.org/D299 AFFECTED FILES hgext/hgk.py mercurial/encoding.py mercurial/pycompat.py mercurial/ui.py mercurial/util.py CHANGE DETAILS diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -172,6 +172,18 @@ def safehasattr(thing, attr): return getattr(thing, attr, _notset) is not _notset +def bytesinput(fin, fout, *args, **kwargs): +sin, sout = sys.stdin, sys.stdout +try: +if pycompat.ispy3: +sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout) +return pycompat.bytestr(input(*args, **kwargs)) +else: +sys.stdin, sys.stdout = fin, fout +return raw_input(*args, **kwargs) +finally: +sys.stdin, sys.stdout = sin, sout + def bitsfrom(container): bits = 0 for bit in container: diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1217,18 +1217,10 @@ self.write(prompt, prompt=True) self.flush() -# instead of trying to emulate raw_input, swap (self.fin, -# self.fout) with (sys.stdin, sys.stdout) -oldin = sys.stdin -oldout = sys.stdout -sys.stdin = self.fin -sys.stdout = self.fout # prompt ' ' must exist; otherwise readline may delete entire line # - http://bugs.python.org/issue12833 with self.timeblockedsection('stdio'): -line = raw_input(' ') -sys.stdin = oldin -sys.stdout = oldout +line = util.bytesinput(self.fin, self.fout, r' ') # When stdin is in binary mode on Windows, it can cause # raw_input() to emit an extra trailing carriage return diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -304,6 +304,7 @@ stdin = sys.stdin stdout = sys.stdout stderr = sys.stderr + if getattr(sys, 'argv', None) is not None: sysargv = sys.argv sysplatform = sys.platform diff --git a/mercurial/encoding.py b/mercurial/encoding.py --- a/mercurial/encoding.py +++ b/mercurial/encoding.py @@ -8,6 +8,7 @@ from __future__ import absolute_import import array +import io import locale import os import unicodedata @@ -573,3 +574,16 @@ c = chr(ord(c.decode("utf-8")) & 0xff) r += c return r + +class strio(io.TextIOWrapper): +"""Wrapper around TextIOWrapper that respects hg's encoding assumptions. + +Also works around Python closing streams. +""" + +def __init__(self, buffer, **kwargs): +kwargs[r'encoding'] = encoding +super(strio, self).__init__(buffer, **kwargs) + +def __del__(self): +"""Override __del__ so it doesn't close the underlying stream.""" diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -50,6 +50,7 @@ patch, registrar, scmutil, +util, ) cmdtable = {} @@ -96,7 +97,7 @@ while True: if opts['stdin']: try: -line = raw_input().split(' ') +line = util.bytesinput(ui.fin, ui.fout).split(' ') node1 = line[0] if len(line) > 1: node2 = line[1] @@ -177,7 +178,7 @@ prefix = "" if opts['stdin']: try: -(type, r) = raw_input().split(' ') +(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') prefix = "" except EOFError: return @@ -195,7 +196,7 @@ catcommit(ui, repo, n, prefix) if opts['stdin']: try: -(type, r) = raw_input().split(' ') +(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ') except EOFError: break else: To: durin42, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D296: extensions: if on py3 and propname is a bytestr, convert to sysstr
durin42 added a comment. Take another look? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D296 To: durin42, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D353: extensions: don't give AttributeError bytes message on Python 3
durin42 updated this revision to Diff 946. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D353?vs=800=946 REVISION DETAIL https://phab.mercurial-scm.org/D353 AFFECTED FILES mercurial/extensions.py CHANGE DETAILS diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -396,8 +396,8 @@ break if currcls is object: -raise AttributeError( -_("type '%s' has no property '%s'") % (cls, propname)) +raise AttributeError(r"type '%s' has no property '%s'" % ( +cls, propname)) def wrapfunction(container, funcname, wrapper): '''Wrap the function named funcname in container To: durin42, #hg-reviewers, yuja Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D298: python3: whitelist four more passing tests
durin42 updated this revision to Diff 947. durin42 retitled this revision from "python3: whitelist two more passing tests" to "python3: whitelist four more passing tests". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D298?vs=681=947 REVISION DETAIL https://phab.mercurial-scm.org/D298 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -15,19 +15,23 @@ test-diff-subdir.t test-dirstate-nonnormalset.t test-doctest.py +test-duplicateoptions.py test-empty-dir.t test-excessive-merge.t +test-hghave.t test-issue1089.t test-issue1993.t test-issue842.t test-locate.t test-lrucachedict.py test-manifest.py +test-match.py test-merge-default.t test-merge2.t test-merge5.t test-revlog-packentry.t test-run-tests.py +test-terse-status.t test-unified-test.t test-update-reverse.t test-xdg.t To: durin42, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D296: extensions: if on py3 and propname is a bytestr, convert to sysstr
durin42 updated this revision to Diff 945. durin42 marked 2 inline comments as done. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D296?vs=799=945 REVISION DETAIL https://phab.mercurial-scm.org/D296 AFFECTED FILES mercurial/extensions.py CHANGE DETAILS diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -384,6 +384,7 @@ These can't be wrapped using the normal wrapfunction. """ +propname = pycompat.sysstr(propname) assert callable(wrapper) for currcls in cls.__mro__: if propname in currcls.__dict__: To: durin42, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D300: python3: whitelist four more passing tests
durin42 updated this revision to Diff 944. durin42 retitled this revision from "python3: whitelist two more passing tests" to "python3: whitelist four more passing tests". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D300?vs=683=944 REVISION DETAIL https://phab.mercurial-scm.org/D300 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -15,19 +15,23 @@ test-diff-subdir.t test-dirstate-nonnormalset.t test-doctest.py +test-duplicateoptions.py test-empty-dir.t test-excessive-merge.t +test-hghave.t test-issue1089.t test-issue1993.t test-issue842.t test-locate.t test-lrucachedict.py test-manifest.py +test-match.py test-merge-default.t test-merge2.t test-merge5.t test-revlog-packentry.t test-run-tests.py +test-terse-status.t test-unified-test.t test-update-reverse.t test-xdg.t To: durin42, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH v4] run-tests: also color the summary messages (skipped, failed...)
On Fri, Aug 11, 2017 at 02:25:12PM +0200, mlaneuvi...@gmail.com wrote: > # HG changeset patch > # User Matthieu Laneuville> # Date 1502454109 -7200 > # Fri Aug 11 14:21:49 2017 +0200 > # Node ID 26bd9bfc7f679dc521b8056b48875eee71cd8627 > # Parent 609606d217659e0a6c1cf6f907b6512be5340e57 > run-tests: also color the summary messages (skipped, failed...) queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] crecord: fixes the formatting of the select status in the status line
On Sun, Aug 13, 2017 at 01:04:52AM -0700, Filip Filmar wrote: > # HG changeset patch > # User Filip Filmar> # Date 1502608633 25200 > # Sun Aug 13 00:17:13 2017 -0700 > # Node ID 4a5fd64feb902da51e7eb5759f4c1d3966186726 > # Parent 03039ff3082b970e70f582e998a7287d1600e912 > crecord: fixes the formatting of the select status in the status line queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] cext: move PyInt macros to charencode.c properly
On Mon, Aug 14, 2017 at 04:53:00PM +0900, Yuya Nishihara wrote: > # HG changeset patch > # User Yuya Nishihara> # Date 1502685326 -32400 > # Mon Aug 14 13:35:26 2017 +0900 > # Node ID 9d9186f859585f2513e3bde3a304cc72cb534565 > # Parent f7d6978a4da9deed920535630c32509683f29915 > cext: move PyInt macros to charencode.c properly queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] py3: change encoding.localstr to a subclass of bytes, not str
On Mon, Aug 14, 2017 at 04:53:19PM +0900, Yuya Nishihara wrote: > # HG changeset patch > # User Yuya Nishihara> # Date 1502693440 -32400 > # Mon Aug 14 15:50:40 2017 +0900 > # Node ID 3852cbe06ef50c23d5c6d25b4ad9b40885e47201 > # Parent 8af5c6fc8ce4c53b43900c6bfb565daa285b8af1 > py3: change encoding.localstr to a subclass of bytes, not str queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] bundle2: relax the condition to update transaction.hookargs
On Mon, Aug 14, 2017 at 04:53:50PM +0900, Yuya Nishihara wrote: > # HG changeset patch > # User Yuya Nishihara> # Date 1502590235 -32400 > # Sun Aug 13 11:10:35 2017 +0900 > # Node ID 8af5c6fc8ce4c53b43900c6bfb565daa285b8af1 > # Parent 1643bad8116707fb6e162a509682b470e9223fba > bundle2: relax the condition to update transaction.hookargs queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D358: copytrace: move fb extension to core under flag experimental.fastcopytrace
pulkit updated this revision to Diff 943. pulkit edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D358?vs=819=943 REVISION DETAIL https://phab.mercurial-scm.org/D358 AFFECTED FILES mercurial/configitems.py mercurial/copies.py tests/test-fastcopytrace.t CHANGE DETAILS diff --git a/tests/test-fastcopytrace.t b/tests/test-fastcopytrace.t new file mode 100644 --- /dev/null +++ b/tests/test-fastcopytrace.t @@ -0,0 +1,595 @@ + $ cat >> $TESTTMP/copytrace.sh << '__EOF__' + > initclient() { + > cat >> $1/.hg/hgrc < [experimental] + > fastcopytrace = True + > EOF + > } + > __EOF__ + $ . "$TESTTMP/copytrace.sh" + + $ cat >> $HGRCPATH << EOF + > [extensions] + > rebase= + > shelve= + > EOF + +Check filename heuristics (same dirname and same basename) + $ hg init server + $ cd server + $ echo a > a + $ mkdir dir + $ echo a > dir/file.txt + $ hg addremove + adding a + adding dir/file.txt + $ hg ci -m initial + $ hg mv a b + $ hg mv -q dir dir2 + $ hg ci -m 'mv a b, mv dir/ dir2/' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo + $ hg up -q 0 + $ echo b > a + $ echo b > dir/file.txt + $ hg ci -qm 'mod a, mod dir/file.txt' + + $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n' + @ changeset: 557f403c0afd2a3cf15d7e2fb1f1001a8b85e081 + | desc: mod a, mod dir/file.txt, phase: draft + | o changeset: 928d74bc9110681920854d845c06959f6dfc9547 + |/desc: mv a b, mv dir/ dir2/, phase: public + o changeset: 3c482b16e54596fed340d05ffaf155f156cda7ee + desc: initial, phase: public + + $ hg rebase -s . -d 1 + rebasing 2:557f403c0afd "mod a, mod dir/file.txt" (tip) + merging b and a to b + merging dir2/file.txt and dir/file.txt to dir2/file.txt + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/557f403c0afd-9926eeff-rebase.hg (glob) + $ cd .. + $ rm -rf server + $ rm -rf repo + +Make sure filename heuristics do not when they are not related + $ hg init server + $ cd server + $ echo 'somecontent' > a + $ hg add a + $ hg ci -m initial + $ hg rm a + $ echo 'completelydifferentcontext' > b + $ hg add b + $ hg ci -m 'rm a, add b' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo + $ hg up -q 0 + $ printf 'somecontent\nmoarcontent' > a + $ hg ci -qm 'mode a' + + $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n' + @ changeset: d526312210b9e8f795d576a77dc643796384d86e + | desc: mode a, phase: draft + | o changeset: 46985f76c7e5e5123433527f5c8526806145650b + |/desc: rm a, add b, phase: public + o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0 + desc: initial, phase: public + + $ hg rebase -s . -d 1 + rebasing 2:d526312210b9 "mode a" (tip) + other [source] changed a which local [dest] deleted + use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u + unresolved conflicts (see hg resolve, then hg rebase --continue) + [1] + $ cd .. + $ rm -rf server + $ rm -rf repo + +Test when lca didn't modified the file that was moved + $ hg init server + $ cd server + $ echo 'somecontent' > a + $ hg add a + $ hg ci -m initial + $ echo c > c + $ hg add c + $ hg ci -m randomcommit + $ hg mv a b + $ hg ci -m 'mv a b' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo + $ hg up -q 1 + $ echo b > a + $ hg ci -qm 'mod a' + + $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n' + @ changeset: 9d5cf99c3d9f8e8b05ba55421f7f56530cfcf3bc + | desc: mod a, phase: draft + | o changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d + |/desc: mv a b, phase: public + o changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83 + | desc: randomcommit, phase: public + o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0 + desc: initial, phase: public + + $ hg rebase -s . -d 2 + rebasing 3:9d5cf99c3d9f "mod a" (tip) + merging b and a to b + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9d5cf99c3d9f-f02358cc-rebase.hg (glob) + $ cd .. + $ rm -rf server + $ rm -rf repo + +Rebase "backwards" + $ hg init server + $ cd server + $ echo 'somecontent' > a + $ hg add a + $ hg ci -m initial + $ echo c > c + $ hg add c + $ hg ci -m randomcommit + $ hg mv a b + $ hg ci -m 'mv a b' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo + $ hg up -q 2 + $ echo b > b + $ hg ci -qm 'mod b' + + $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n' + @ changeset: fbe97126b3969056795c462a67d93faf13e4d298 + | desc: mod b, phase: draft + o changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d + | desc: mv a b, phase: public + o changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83 + | desc: randomcommit, phase: public + o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0 + desc: initial, phase: public + + $ hg rebase -s . -d 0 + rebasing 3:fbe97126b396 "mod b" (tip)
D409: copies: add more details to the documentation of mergecopies()
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This documentation is very helpful for any developer to understand what copytracing is and what the function does. Since this is the main function of doing copytracing, I have also included bits about copytracing in it. This additions are picked from a doc by Stash@Fb. So thanks to him. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D409 AFFECTED FILES mercurial/copies.py CHANGE DETAILS diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -304,6 +304,28 @@ def mergecopies(repo, c1, c2, base): """ +The basic algorithm for copytracing. Copytracing is used in commands like +rebase, merge, unshelve, etc to merge files that were moved/ copied in one +merge parent and modified in another. For example: + +o ---> 4 another commit +| +| o ---> 3 commit that modifies a.txt +| / +o /---> 2 commit that moves a.txt to b.txt +|/ +o ---> 1 merge base + +If we try to rebase revision 3 on revision 4, since there is no a.txt in +revision 4, and if user have copytrace disabled, we prints the following +message: + +```other changed which local deleted``` + +If copytrace is enabled, this function finds all the new files that were +added from merge base up to the top commit (here 4), and for each file it +checks if this file was copied from another file (a.txt in the above case). + Find moves and copies between context c1 and c2 that are relevant for merging. 'base' will be used as the merge base. To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D351: demandimport: disable by default if chg is being used
phillco accepted this revision. phillco added a comment. lgtm, pending sid's comment. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers, phillco Cc: phillco, sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D360: log: add a "graphwidth" template variable
hooper updated this revision to Diff 941. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D360?vs=940=941 REVISION DETAIL https://phab.mercurial-scm.org/D360 AFFECTED FILES mercurial/cmdutil.py mercurial/graphmod.py mercurial/templatekw.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -4319,3 +4319,155 @@ custom $ cd .. + +Test 'graphwidth' in 'hg log' on various topologies. The key here is that the +printed graphwidths 3, 5, 7, etc. should all line up in their respective +columns. We don't care about other aspects of the graph rendering here. + + $ hg init graphwidth + $ cd graphwidth + + $ wrappabletext="a a a a a a a a a a a a" + + $ printf "first\n" > file + $ hg add file + $ hg commit -m "$wrappabletext" + + $ printf "first\nsecond\n" > file + $ hg commit -m "$wrappabletext" + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg merge + merging file + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | @ 5 + |/ + o 3 + + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @5 + |\ + | o 5 + | | + o | 5 + |/ + o 3 + + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\nsecond\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | o7 + | |\ + +---o 7 + | | + | o 5 + |/ + o 3 + + + $ hg log --graph -T "{graphwidth}" -r 3 + o5 + |\ + ~ ~ + + $ hg log --graph -T "{graphwidth}" -r 1 + o 3 + | + ~ + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg commit -m "$wrappabletext" + + $ printf "seventh\n" >> file + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + o5 + |\ + | o 5 + | | + o |7 + |\ \ + | o | 7 + | |/ + o / 5 + |/ + o 3 + + +The point of graphwidth is to allow wrapping that accounts for the space taken +by the graph. + + $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}" + @ a a a a + | a a a a + | a a a a + oa a a + |\ a a a + | | a a a + | | a a a + | o a a a + | | a a a + | | a a a + | | a a a + o |a a + |\ \ a a + | | | a a + | | | a a + | | | a a + | | | a a + | o | a a + | |/ a a + | |a a + | |a a + | |a a + | |a a + o | a a a + |/ a a a + |a a a + |a a a + o a a a a + a a a a + a a a a + +Something tricky happens when there are elided nodes; the next drawn row of +edges can be more than one column wider, but the graph width only increases by +one column. The remaining columns are added in between the nodes. + + $ hg log --graph -T "{graphwidth}" -r "0|2|4|5" + o5 + |\ + | \ + | :\ + o : : 7 + :/ / + : o 5 + :/ + o 3 + + + $ cd .. + diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -764,6 +764,13 @@ """Integer. The width of the current terminal.""" return repo.ui.termwidth() +@templatekeyword('graphwidth') +def graphwidth(repo, ctx, templ, **args): +"""Integer. The width of the graph drawn by 'log --graph' or zero.""" +# The value args['graphwidth'] will be this function, so we use an internal +# name to pass the value through props into this function. +return args.get('_graphwidth', 0) + @templatekeyword('troubles') def showtroubles(**args): """List of strings. Evolution troubles affecting the changeset. diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py --- a/mercurial/graphmod.py +++ b/mercurial/graphmod.py @@ -172,7 +172,7 @@ yield (cur, type, data, (col, color), edges) seen = next -def asciiedges(type, char, lines, state, rev, parents): +def asciiedges(type, char, state, rev, parents): """adds edge info to changelog DAG walk suitable for ascii()""" seen = state['seen'] if rev not in seen: @@ -192,6 +192,7 @@ state['edges'][parent] = state['styles'].get(ptype, '|') ncols = len(seen) +width = 1 + ncols * 2 nextseen = seen[:] nextseen[nodeidx:nodeidx + 1] = newparents edges = [(nodeidx, nextseen.index(p)) for p in knownparents] @@ -205,7 +206,8 @@ edges.append((nodeidx, nodeidx)) edges.append((nodeidx, nodeidx + 1)) nmorecols = 1 -yield (type, char, lines, (nodeidx, edges, ncols, nmorecols)) +width += 2 +
D360: log: add a "graphwidth" template variable
hooper added inline comments. INLINE COMMENTS > yuja wrote in templatekw.py:768 > s/graphwidth/showgraphwidth/, and functions should be sorted alphabetically. Can you explain why it should be renamed? I thought it should mirror termwidth. They both return an integer for computations in templates. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D360 To: hooper, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D360: log: add a "graphwidth" template variable
hooper updated this revision to Diff 940. hooper edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D360?vs=822=940 REVISION DETAIL https://phab.mercurial-scm.org/D360 AFFECTED FILES mercurial/cmdutil.py mercurial/graphmod.py mercurial/templatekw.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -4319,3 +4319,155 @@ custom $ cd .. + +Test 'graphwidth' in 'hg log' on various topologies. The key here is that the +printed graphwidths 3, 5, 7, etc. should all line up in their respective +columns. We don't care about other aspects of the graph rendering here. + + $ hg init graphwidth + $ cd graphwidth + + $ wrappabletext="a a a a a a a a a a a a" + + $ printf "first\n" > file + $ hg add file + $ hg commit -m "$wrappabletext" + + $ printf "first\nsecond\n" > file + $ hg commit -m "$wrappabletext" + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg merge + merging file + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | @ 5 + |/ + o 3 + + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @5 + |\ + | o 5 + | | + o | 5 + |/ + o 3 + + + $ hg checkout 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ printf "third\nfirst\nsecond\n" > file + $ hg commit -m "$wrappabletext" + created new head + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + | o7 + | |\ + +---o 7 + | | + | o 5 + |/ + o 3 + + + $ hg log --graph -T "{graphwidth}" -r 3 + o5 + |\ + ~ ~ + + $ hg log --graph -T "{graphwidth}" -r 1 + o 3 + | + ~ + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg commit -m "$wrappabletext" + + $ printf "seventh\n" >> file + $ hg commit -m "$wrappabletext" + + $ hg log --graph -T "{graphwidth}" + @ 3 + | + o5 + |\ + | o 5 + | | + o |7 + |\ \ + | o | 7 + | |/ + o / 5 + |/ + o 3 + + +The point of graphwidth is to allow wrapping that accounts for the space taken +by the graph. + + $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}" + @ a a a a + | a a a a + | a a a a + oa a a + |\ a a a + | | a a a + | | a a a + | o a a a + | | a a a + | | a a a + | | a a a + o |a a + |\ \ a a + | | | a a + | | | a a + | | | a a + | | | a a + | o | a a + | |/ a a + | |a a + | |a a + | |a a + | |a a + o | a a a + |/ a a a + |a a a + |a a a + o a a a a + a a a a + a a a a + +Something tricky happens when there are elided nodes; the next drawn row of +edges can be more than one column wider, but the graph width only increases by +one column. The remaining columns are added in between the nodes. + + $ hg log --graph -T "{graphwidth}" -r "0|2|4|5" + o5 + |\ + | \ + | :\ + o : : 7 + :/ / + : o 5 + :/ + o 3 + + + $ cd .. + diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -764,6 +764,13 @@ """Integer. The width of the current terminal.""" return repo.ui.termwidth() +@templatekeyword('graphwidth') +def graphwidth(repo, ctx, templ, **args): +"""Integer. The width of the graph drawn by 'log --graph' or zero.""" +# The value args['graphwidth'] will be this function, so we use an internal +# name to pass the value through props into this function. +return args.get('_graphwidth', 0) + @templatekeyword('troubles') def showtroubles(**args): """List of strings. Evolution troubles affecting the changeset. diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py --- a/mercurial/graphmod.py +++ b/mercurial/graphmod.py @@ -172,7 +172,7 @@ yield (cur, type, data, (col, color), edges) seen = next -def asciiedges(type, char, lines, state, rev, parents): +def asciiedges(type, char, state, rev, parents): """adds edge info to changelog DAG walk suitable for ascii()""" seen = state['seen'] if rev not in seen: @@ -192,6 +192,7 @@ state['edges'][parent] = state['styles'].get(ptype, '|') ncols = len(seen) +width = 1 + ncols * 2 nextseen = seen[:] nextseen[nodeidx:nodeidx + 1] = newparents edges = [(nodeidx, nextseen.index(p)) for p in knownparents] @@ -205,7 +206,8 @@ edges.append((nodeidx, nodeidx)) edges.append((nodeidx, nodeidx + 1)) nmorecols = 1 -yield (type, char, lines, (nodeidx, edges,
D351: demandimport: disable by default if chg is being used
sid0 added a comment. > I tried that approach. If we only set HGDEMANDIMPORT for the forked process to execute hg server, it will be an infinite loop - environment config hash will mismatch. Setting HGDEMANDIMPORT for both the forked and non-forked chg client processes seems less cleaner. This should be a comment in this patch :) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers Cc: sid0, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D369: util: add `hgdatetopython` to convert hg-style dates to datetimes
phillco added a comment. r https://phab.mercurial-scm.org/rHG87c6ad2251d8703d7f16d51e99e3d1c040f0be49 INLINE COMMENTS > phillco wrote in util.py:1862 > Hm, good question. I only do that because that's what the earlier code did -- > that change dates from `87c6ad2251d8703d7f16d51e99e3d1c040f0be49`, I think. https://phab.mercurial-scm.org/rHG87c6ad2251d8703d7f16d51e99e3d1c040f0be49 -- it linkifies if you don't use backtics, apparently REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D369 To: phillco, #hg-reviewers Cc: durin42, lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D369: util: add `hgdatetopython` to convert hg-style dates to datetimes
phillco added inline comments. INLINE COMMENTS > durin42 wrote in util.py:1862 > This function makes me really nervous, because it's a naive datetime rather > than a tz-aware datetime. Could we do better about preserving the exact > point-in-time value of the tz-aware time information? > > ("no" is a possible answer here, but I'd really like to know why we're not > storing the zone offset in the datetime object.) Hm, good question. I only do that because that's what the earlier code did -- that change dates from `87c6ad2251d8703d7f16d51e99e3d1c040f0be49`, I think. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D369 To: phillco, #hg-reviewers Cc: durin42, lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D355: contrib: add check flag for use of admonitions and its validity
rishabhmadan96 abandoned this revision. rishabhmadan96 marked an inline comment as done. rishabhmadan96 added a comment. In https://phab.mercurial-scm.org/D355#6196, @durin42 wrote: > is this the same thing as https://phab.mercurial-scm.org/D368? Should we close this one in favor of that one? Yes. I'm abandoning this one. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D355 To: rishabhmadan96, #hg-reviewers, pulkit Cc: durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D338: wireproto: use new peer interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdedab036215d: wireproto: use new peer interface (authored by indygreg). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D338?vs=763=937#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D338?vs=763=937 REVISION DETAIL https://phab.mercurial-scm.org/D338 AFFECTED FILES mercurial/httppeer.py mercurial/peer.py mercurial/sshpeer.py mercurial/wireproto.py tests/notcapable tests/test-wireproto.py CHANGE DETAILS diff --git a/tests/test-wireproto.py b/tests/test-wireproto.py --- a/tests/test-wireproto.py +++ b/tests/test-wireproto.py @@ -19,7 +19,26 @@ def __init__(self, serverrepo): self.serverrepo = serverrepo -def _capabilities(self): +@property +def ui(self): +return self.serverrepo.ui + +def url(self): +return 'test' + +def local(self): +return None + +def peer(self): +return self + +def canpush(self): +return True + +def close(self): +pass + +def capabilities(self): return ['batch'] def _call(self, cmd, **args): diff --git a/tests/notcapable b/tests/notcapable --- a/tests/notcapable +++ b/tests/notcapable @@ -6,9 +6,9 @@ fi cat > notcapable-$CAP.py << EOF -from mercurial import extensions, peer, localrepo +from mercurial import extensions, localrepo, repository def extsetup(): -extensions.wrapfunction(peer.peerrepository, 'capable', wrapcapable) +extensions.wrapfunction(repository.peer, 'capable', wrapcapable) extensions.wrapfunction(localrepo.localrepository, 'peer', wrappeer) def wrapcapable(orig, self, name, *args, **kwargs): if name in '$CAP'.split(' '): diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -27,6 +27,7 @@ peer, pushkey as pushkeymod, pycompat, +repository, streamclone, util, ) @@ -212,36 +213,15 @@ # client side -class wirepeer(peer.peerrepository): +class wirepeer(repository.legacypeer): """Client-side interface for communicating with a peer repository. Methods commonly call wire protocol commands of the same name. See also httppeer.py and sshpeer.py for protocol-specific implementations of this interface. """ -def _submitbatch(self, req): -"""run batch request on the server - -Returns an iterator of the raw responses from the server. -""" -rsp = self._callstream("batch", cmds=encodebatchcmds(req)) -chunk = rsp.read(1024) -work = [chunk] -while chunk: -while ';' not in chunk and chunk: -chunk = rsp.read(1024) -work.append(chunk) -merged = ''.join(work) -while ';' in merged: -one, merged = merged.split(';', 1) -yield unescapearg(one) -chunk = rsp.read(1024) -work = [merged, chunk] -yield unescapearg(''.join(work)) - -def _submitone(self, op, args): -return self._call(op, **args) +# Begin of basewirepeer interface. def iterbatch(self): return remoteiterbatcher(self) @@ -293,26 +273,17 @@ except TypeError: self._abort(error.ResponseError(_("unexpected response:"), d)) -def branches(self, nodes): -n = encodelist(nodes) -d = self._call("branches", nodes=n) -try: -br = [tuple(decodelist(b)) for b in d.splitlines()] -return br -except ValueError: -self._abort(error.ResponseError(_("unexpected response:"), d)) - -def between(self, pairs): -batch = 8 # avoid giant requests -r = [] -for i in xrange(0, len(pairs), batch): -n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]]) -d = self._call("between", pairs=n) -try: -r.extend(l and decodelist(l) or [] for l in d.splitlines()) -except ValueError: -self._abort(error.ResponseError(_("unexpected response:"), d)) -return r +@batchable +def listkeys(self, namespace): +if not self.capable('pushkey'): +yield {}, None +f = future() +self.ui.debug('preparing listkeys for "%s"\n' % namespace) +yield {'namespace': encoding.fromlocal(namespace)}, f +d = f.value +self.ui.debug('received listkey for "%s": %i bytes\n' + % (namespace, len(d))) +yield pushkeymod.decodekeys(d) @batchable def pushkey(self, namespace, key, old, new): @@ -335,34 +306,9 @@ self.ui.status(_('remote: '), l) yield d -@batchable -def listkeys(self, namespace): -if not self.capable('pushkey'): -yield {}, None -f = future() -self.ui.debug('preparing
D335: localrepo: use peer interfaces
This revision was automatically updated to reflect the committed changes. Closed by commit rHG707750e5310b: localrepo: use peer interfaces (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D335?vs=760=934 REVISION DETAIL https://phab.mercurial-scm.org/D335 AFFECTED FILES mercurial/localrepo.py CHANGE DETAILS diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -49,6 +49,7 @@ phases, pushkey, pycompat, +repository, repoview, revset, revsetlang, @@ -144,43 +145,52 @@ 'unbundle'} legacycaps = moderncaps.union({'changegroupsubset'}) -class localpeer(peer.peerrepository): +class localpeer(repository.peer): '''peer for a local repo; reflects only the most recent API''' def __init__(self, repo, caps=None): +super(localpeer, self).__init__() + if caps is None: caps = moderncaps.copy() -peer.peerrepository.__init__(self) self._repo = repo.filtered('served') -self.ui = repo.ui +self._ui = repo.ui self._caps = repo._restrictcapabilities(caps) +# Begin of _basepeer interface. + +@util.propertycache +def ui(self): +return self._ui + +def url(self): +return self._repo.url() + +def local(self): +return self._repo + +def peer(self): +return self + +def canpush(self): +return True + def close(self): self._repo.close() -def _capabilities(self): -return self._caps - -def local(self): -return self._repo +# End of _basepeer interface. -def canpush(self): -return True - -def url(self): -return self._repo.url() - -def lookup(self, key): -return self._repo.lookup(key) +# Begin of _basewirecommands interface. def branchmap(self): return self._repo.branchmap() -def heads(self): -return self._repo.heads() +def capabilities(self): +return self._caps -def known(self, nodes): -return self._repo.known(nodes) +def debugwireargs(self, one, two, three=None, four=None, five=None): +"""Used to test argument passing over the wire""" +return "%s %s %s %s %s" % (one, two, three, four, five) def getbundle(self, source, heads=None, common=None, bundlecaps=None, **kwargs): @@ -197,8 +207,24 @@ else: return changegroup.getunbundler('01', cb, None) -# TODO We might want to move the next two calls into legacypeer and add -# unbundle instead. +def heads(self): +return self._repo.heads() + +def known(self, nodes): +return self._repo.known(nodes) + +def listkeys(self, namespace): +return self._repo.listkeys(namespace) + +def lookup(self, key): +return self._repo.lookup(key) + +def pushkey(self, namespace, key, old, new): +return self._repo.pushkey(namespace, key, old, new) + +def stream_out(self): +raise error.Abort(_('cannot perform stream clone against local ' +'peer')) def unbundle(self, cg, heads, url): """apply a bundle on a repo @@ -235,35 +261,38 @@ except error.PushRaced as exc: raise error.ResponseError(_('push failed:'), str(exc)) -def pushkey(self, namespace, key, old, new): -return self._repo.pushkey(namespace, key, old, new) +# End of _basewirecommands interface. -def listkeys(self, namespace): -return self._repo.listkeys(namespace) +# Begin of peer interface. -def debugwireargs(self, one, two, three=None, four=None, five=None): -'''used to test argument passing over the wire''' -return "%s %s %s %s %s" % (one, two, three, four, five) +def iterbatch(self): +return peer.localiterbatcher(self) -class locallegacypeer(localpeer): +# End of peer interface. + +class locallegacypeer(repository.legacypeer, localpeer): '''peer extension which implements legacy methods too; used for tests with restricted capabilities''' def __init__(self, repo): -localpeer.__init__(self, repo, caps=legacycaps) +super(locallegacypeer, self).__init__(repo, caps=legacycaps) + +# Begin of baselegacywirecommands interface. + +def between(self, pairs): +return self._repo.between(pairs) def branches(self, nodes): return self._repo.branches(nodes) -def between(self, pairs): -return self._repo.between(pairs) - def changegroup(self, basenodes, source): return changegroup.changegroup(self._repo, basenodes, source) def changegroupsubset(self, bases, heads, source): return changegroup.changegroupsubset(self._repo, bases, heads, source) +# End of baselegacywirecommands interface. + # Increment the
D30: merge: Removed sorting in casefolding detection, for a slight performance win
This revision was automatically updated to reflect the committed changes. Closed by commit rHG055fee3547df: merge: removed sorting in casefolding detection, for a slight performance win (authored by alex_gaynor). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D30?vs=737=939 REVISION DETAIL https://phab.mercurial-scm.org/D30 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -753,7 +753,7 @@ # check case-folding collision in provisional merged manifest foldmap = {} -for f in sorted(pmmf): +for f in pmmf: fold = util.normcase(f) if fold in foldmap: raise error.Abort(_("case-folding collision between %s and %s") To: alex_gaynor, durin42, dsp, #hg-reviewers, quark Cc: quark, krbullock, dsp, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D339: tests: verify that peer instances only expose interface members
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb70029f355a3: tests: verify that peer instances only expose interface members (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D339?vs=764=938 REVISION DETAIL https://phab.mercurial-scm.org/D339 AFFECTED FILES tests/test-check-interfaces.py tests/test-check-interfaces.py.out CHANGE DETAILS diff --git a/tests/test-check-interfaces.py.out b/tests/test-check-interfaces.py.out new file mode 100644 --- /dev/null +++ b/tests/test-check-interfaces.py.out @@ -0,0 +1,2 @@ +public attributes not in abstract interface: badpeer.badattribute +public attributes not in abstract interface: badpeer.badmethod diff --git a/tests/test-check-interfaces.py b/tests/test-check-interfaces.py new file mode 100644 --- /dev/null +++ b/tests/test-check-interfaces.py @@ -0,0 +1,71 @@ +# Test that certain objects conform to well-defined interfaces. + +from __future__ import absolute_import, print_function + +from mercurial import ( +httppeer, +localrepo, +sshpeer, +ui as uimod, +) + +def checkobject(o): +"""Verify a constructed object conforms to interface rules. + +An object must have __abstractmethods__ defined. + +All "public" attributes of the object (attributes not prefixed with +an underscore) must be in __abstractmethods__ or appear on a base class +with __abstractmethods__. +""" +name = o.__class__.__name__ + +allowed = set() +for cls in o.__class__.__mro__: +if not getattr(cls, '__abstractmethods__', set()): +continue + +allowed |= cls.__abstractmethods__ +allowed |= {a for a in dir(cls) if not a.startswith('_')} + +if not allowed: +print('%s does not have abstract methods' % name) +return + +public = {a for a in dir(o) if not a.startswith('_')} + +for attr in sorted(public - allowed): +print('public attributes not in abstract interface: %s.%s' % ( +name, attr)) + +# Facilitates testing localpeer. +class dummyrepo(object): +def __init__(self): +self.ui = uimod.ui() +def filtered(self, name): +pass +def _restrictcapabilities(self, caps): +pass + +# Facilitates testing sshpeer without requiring an SSH server. +class testingsshpeer(sshpeer.sshpeer): +def _validaterepo(self, *args, **kwargs): +pass + +class badpeer(httppeer.httppeer): +def __init__(self): +super(badpeer, self).__init__(uimod.ui(), 'http://localhost') +self.badattribute = True + +def badmethod(self): +pass + +def main(): +ui = uimod.ui() + +checkobject(badpeer()) +checkobject(httppeer.httppeer(ui, 'http://localhost')) +checkobject(localrepo.localpeer(dummyrepo())) +checkobject(testingsshpeer(ui, 'ssh://localhost/foo')) + +main() To: indygreg, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D337: httppeer: use peer interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf913e90f15a0: httppeer: use peer interface (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D337?vs=762=936 REVISION DETAIL https://phab.mercurial-scm.org/D337 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -21,6 +21,7 @@ error, httpconnection, pycompat, +repository, statichttprepo, url, util, @@ -86,7 +87,7 @@ resp.__class__ = readerproxy -class httppeer(wireproto.wirepeer): +class httppeer(wireproto.wirepeer, repository.legacypeer): def __init__(self, ui, path): self._path = path self._caps = None @@ -100,28 +101,48 @@ # urllib cannot handle URLs with embedded user or passwd self._url, authinfo = u.authinfo() -self.ui = ui -self.ui.debug('using %s\n' % self._url) +self._ui = ui +ui.debug('using %s\n' % self._url) self._urlopener = url.opener(ui, authinfo) self._requestbuilder = urlreq.request +# TODO remove once peerrepository isn't in inheritance. +self._capabilities = self.capabilities + def __del__(self): urlopener = getattr(self, '_urlopener', None) if urlopener: for h in urlopener.handlers: h.close() getattr(h, "close_all", lambda : None)() +# Begin of _basepeer interface. + +@util.propertycache +def ui(self): +return self._ui + def url(self): return self._path -# look up capabilities only when needed +def local(self): +return None + +def peer(self): +return self + +def canpush(self): +return True -def _fetchcaps(self): -self._caps = set(self._call('capabilities').split()) +def close(self): +pass -def _capabilities(self): +# End of _basepeer interface. + +# Begin of _basewirepeer interface. + +def capabilities(self): if self._caps is None: try: self._fetchcaps() @@ -131,6 +152,13 @@ (' '.join(self._caps or ['none']))) return self._caps +# End of _basewirepeer interface. + +# look up capabilities only when needed + +def _fetchcaps(self): +self._caps = set(self._call('capabilities').split()) + def _callstream(self, cmd, _compressible=False, **args): if cmd == 'pushkey': args['data'] = '' To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D334: repository: implement generic capability methods on peer class
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa0aad86b3b6a: repository: implement generic capability methods on peer class (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D334?vs=849=933 REVISION DETAIL https://phab.mercurial-scm.org/D334 AFFECTED FILES mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -9,6 +9,11 @@ import abc +from .i18n import _ +from . import ( +error, +) + class _basepeer(object): """Represents a "connection" to a repository. @@ -228,5 +233,36 @@ calls. However, they must all support this API. """ +def capable(self, name): +"""Determine support for a named capability. + +Returns ``False`` if capability not supported. + +Returns ``True`` if boolean capability is supported. Returns a string +if capability support is non-boolean. +""" +caps = self.capabilities() +if name in caps: +return True + +name = '%s=' % name +for cap in caps: +if cap.startswith(name): +return cap[len(name):] + +return False + +def requirecap(self, name, purpose): +"""Require a capability to be present. + +Raises a ``CapabilityError`` if the capability isn't present. +""" +if self.capable(name): +return + +raise error.CapabilityError( +_('cannot %s; remote repository does not support the %r ' + 'capability') % (purpose, name)) + class legacypeer(peer, _baselegacywirecommands): """peer but with support for legacy wire protocol commands.""" To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D332: repository: formalize peer interface with abstract base class
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf257943e47ab: repository: formalize peer interface with abstract base class (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D332?vs=847=931 REVISION DETAIL https://phab.mercurial-scm.org/D332 AFFECTED FILES mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py new file mode 100644 --- /dev/null +++ b/mercurial/repository.py @@ -0,0 +1,71 @@ +# repository.py - Interfaces and base classes for repositories and peers. +# +# Copyright 2017 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. + +from __future__ import absolute_import + +import abc + +class _basepeer(object): +"""Represents a "connection" to a repository. + +This is the base interface for representing a connection to a repository. +It holds basic properties and methods applicable to all peer types. + +This is not a complete interface definition and should not be used +outside of this module. +""" +__metaclass__ = abc.ABCMeta + +@abc.abstractproperty +def ui(self): +"""ui.ui instance.""" + +@abc.abstractmethod +def url(self): +"""Returns a URL string representing this peer. + +Currently, implementations expose the raw URL used to construct the +instance. It may contain credentials as part of the URL. The +expectations of the value aren't well-defined and this could lead to +data leakage. + +TODO audit/clean consumers and more clearly define the contents of this +value. +""" + +@abc.abstractmethod +def local(self): +"""Returns a local repository instance. + +If the peer represents a local repository, returns an object that +can be used to interface with it. Otherwise returns ``None``. +""" + +@abc.abstractmethod +def peer(self): +"""Returns an object conforming to this interface. + +Most implementations will ``return self``. +""" + +@abc.abstractmethod +def canpush(self): +"""Returns a boolean indicating if this peer can be pushed to.""" + +@abc.abstractmethod +def close(self): +"""Close the connection to this peer. + +This is called when the peer will no longer be used. Resources +associated with the peer should be cleaned up. +""" + +class peer(_basepeer): +"""Unified interface and base class for peer repositories. + +All peer instances must inherit from this class. +""" To: indygreg, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D336: sshpeer: use peer interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1f8460b55986: sshpeer: use peer interface (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D336?vs=761=935 REVISION DETAIL https://phab.mercurial-scm.org/D336 AFFECTED FILES mercurial/sshpeer.py CHANGE DETAILS diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py --- a/mercurial/sshpeer.py +++ b/mercurial/sshpeer.py @@ -13,6 +13,7 @@ from . import ( error, pycompat, +repository, util, wireproto, ) @@ -114,10 +115,10 @@ def flush(self): return self._main.flush() -class sshpeer(wireproto.wirepeer): +class sshpeer(wireproto.wirepeer, repository.legacypeer): def __init__(self, ui, path, create=False): self._url = path -self.ui = ui +self._ui = ui self._pipeo = self._pipei = self._pipee = None u = util.url(path, parsequery=False, parsefragment=False) @@ -150,9 +151,39 @@ self._validaterepo(sshcmd, args, remotecmd) +# TODO remove this alias once peerrepository inheritance is removed. +self._capabilities = self.capabilities + +# Begin of _basepeer interface. + +@util.propertycache +def ui(self): +return self._ui + def url(self): return self._url +def local(self): +return None + +def peer(self): +return self + +def canpush(self): +return True + +def close(self): +pass + +# End of _basepeer interface. + +# Begin of _basewirecommands interface. + +def capabilities(self): +return self._caps + +# End of _basewirecommands interface. + def _validaterepo(self, sshcmd, args, remotecmd): # cleanup up previous run self._cleanup() @@ -200,9 +231,6 @@ self._caps.update(l[:-1].split(":")[1].split()) break -def _capabilities(self): -return self._caps - def _readerr(self): _forwardoutput(self.ui, self._pipee) To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D333: repository: formalize wire protocol interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG558f5b2ee10e: repository: formalize wire protocol interface (authored by indygreg). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D333?vs=848=932 REVISION DETAIL https://phab.mercurial-scm.org/D333 AFFECTED FILES mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -64,8 +64,169 @@ associated with the peer should be cleaned up. """ -class peer(_basepeer): +class _basewirecommands(object): +"""Client-side interface for communicating over the wire protocol. + +This interface is used as a gateway to the Mercurial wire protocol. +methods commonly call wire protocol commands of the same name. +""" +__metaclass__ = abc.ABCMeta + +@abc.abstractmethod +def branchmap(self): +"""Obtain heads in named branches. + +Returns a dict mapping branch name to an iterable of nodes that are +heads on that branch. +""" + +@abc.abstractmethod +def capabilities(self): +"""Obtain capabilities of the peer. + +Returns a set of string capabilities. +""" + +@abc.abstractmethod +def debugwireargs(self, one, two, three=None, four=None, five=None): +"""Used to facilitate debugging of arguments passed over the wire.""" + +@abc.abstractmethod +def getbundle(self, source, **kwargs): +"""Obtain remote repository data as a bundle. + +This command is how the bulk of repository data is transferred from +the peer to the local repository + +Returns a generator of bundle data. +""" + +@abc.abstractmethod +def heads(self): +"""Determine all known head revisions in the peer. + +Returns an iterable of binary nodes. +""" + +@abc.abstractmethod +def known(self, nodes): +"""Determine whether multiple nodes are known. + +Accepts an iterable of nodes whose presence to check for. + +Returns an iterable of booleans indicating of the corresponding node +at that index is known to the peer. +""" + +@abc.abstractmethod +def listkeys(self, namespace): +"""Obtain all keys in a pushkey namespace. + +Returns an iterable of key names. +""" + +@abc.abstractmethod +def lookup(self, key): +"""Resolve a value to a known revision. + +Returns a binary node of the resolved revision on success. +""" + +@abc.abstractmethod +def pushkey(self, namespace, key, old, new): +"""Set a value using the ``pushkey`` protocol. + +Arguments correspond to the pushkey namespace and key to operate on and +the old and new values for that key. + +Returns a string with the peer result. The value inside varies by the +namespace. +""" + +@abc.abstractmethod +def stream_out(self): +"""Obtain streaming clone data. + +Successful result should be a generator of data chunks. +""" + +@abc.abstractmethod +def unbundle(self, bundle, heads, url): +"""Transfer repository data to the peer. + +This is how the bulk of data during a push is transferred. + +Returns the integer number of heads added to the peer. +""" + +class _baselegacywirecommands(object): +"""Interface for implementing support for legacy wire protocol commands. + +Wire protocol commands transition to legacy status when they are no longer +used by modern clients. To facilitate identifying which commands are +legacy, the interfaces are split. +""" +__metaclass__ = abc.ABCMeta + +@abc.abstractmethod +def between(self, pairs): +"""Obtain nodes between pairs of nodes. + +``pairs`` is an iterable of node pairs. + +Returns an iterable of iterables of nodes corresponding to each +requested pair. +""" + +@abc.abstractmethod +def branches(self, nodes): +"""Obtain ancestor changesets of specific nodes back to a branch point. + +For each requested node, the peer finds the first ancestor node that is +a DAG root or is a merge. + +Returns an iterable of iterables with the resolved values for each node. +""" + +@abc.abstractmethod +def changegroup(self, nodes, kind): +"""Obtain a changegroup with data for descendants of specified nodes.""" + +@abc.abstractmethod +def changegroupsubset(self, bases, heads, kind): +pass + +class peer(_basepeer, _basewirecommands): """Unified interface and base class for peer repositories. -All peer instances must inherit from this class. +All peer instances must inherit from this class and conform to its +interface. """ + +@abc.abstractmethod +def
D362: hg: Avoid relying on errno numbers / descriptions
This revision was automatically updated to reflect the committed changes. Closed by commit rHG82c39a8ec3b1: hg: avoid relying on errno numbers / descriptions (authored by mithrandi). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D362?vs=824=930 REVISION DETAIL https://phab.mercurial-scm.org/D362 AFFECTED FILES tests/test-acl.t tests/test-tags.t CHANGE DETAILS diff --git a/tests/test-tags.t b/tests/test-tags.t --- a/tests/test-tags.t +++ b/tests/test-tags.t @@ -381,7 +381,7 @@ $ hg blackbox -l 6 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags - 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno 13] Permission denied: '$TESTTMP/t2/.hg/cache/hgtagsfnodes1' + 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno *] * (glob) 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 2/3 cache hits/lookups in * seconds (glob) 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob) diff --git a/tests/test-acl.t b/tests/test-acl.t --- a/tests/test-acl.t +++ b/tests/test-acl.t @@ -883,7 +883,7 @@ added 3 changesets with 3 changes to 3 files calling hook pretxnchangegroup.acl: hgext.acl.hook acl: checking access for user "barney" - error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config' + error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob) bundle2-input-part: total payload size 1553 bundle2-input-bundle: 3 parts total transaction abort! To: mithrandi, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D361: hg: Tolerate long vs. int in test-context.py
This revision was automatically updated to reflect the committed changes. Closed by commit rHG3889cf955a62: hg: tolerate long vs. int in test-context.py (authored by mithrandi). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D361?vs=823=929 REVISION DETAIL https://phab.mercurial-scm.org/D361 AFFECTED FILES tests/test-context.py CHANGE DETAILS diff --git a/tests/test-context.py b/tests/test-context.py --- a/tests/test-context.py +++ b/tests/test-context.py @@ -24,11 +24,10 @@ repo[None].add(['foo']) repo.commit(text='commit1', date="0 0") +d = repo[None]['foo'].date() if os.name == 'nt': -d = repo[None]['foo'].date() -print("workingfilectx.date = (%d, %d)" % (d[0], d[1])) -else: -print("workingfilectx.date =", repo[None]['foo'].date()) +d = d[:2] +print("workingfilectx.date = (%d, %d)" % d) # test memctx with non-ASCII commit message To: mithrandi, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D362: hg: Avoid relying on errno numbers / descriptions
durin42 added a comment. Sigh. Do you happen to know if the names of the errno enum values is constant? If it is, maybe we could turn the number back into a name. In any case, queued for stable. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D362 To: mithrandi, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D355: contrib: add check flag for use of admonitions and its validity
durin42 added a comment. is this the same thing as https://phab.mercurial-scm.org/D368? Should we close this one in favor of that one? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D355 To: rishabhmadan96, #hg-reviewers, pulkit Cc: durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D368: releasenotes: add check flag for use of admonitions and its validity
durin42 requested changes to this revision. durin42 added a comment. This revision now requires changes to proceed. A style nit, generally +1 and if you get the style nits handled we should be good to go. INLINE COMMENTS > releasenotes.py:266 > +else: > +ui.write(_("Invalid admonition \'%s\' present in changeset > %s\ > +\n") % (admonition.group(1), ctx.hex()[:12])) nit: in a "-quoted string, you can omit \ on ' not a nit: use ("foo" "bar") instead of \ to wrap a multi-line string literal (the concatenation is implicit at module load time). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D368 To: rishabhmadan96, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D369: util: add `hgdatetopython` to convert hg-style dates to datetimes
durin42 added inline comments. INLINE COMMENTS > util.py:1862 > +def hgdatetopython(date): > +"""Returns a Python datetime from a Mercurial tuple-style date""" > +t, tz = date This function makes me really nervous, because it's a naive datetime rather than a tz-aware datetime. Could we do better about preserving the exact point-in-time value of the tz-aware time information? ("no" is a possible answer here, but I'd really like to know why we're not storing the zone offset in the datetime object.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D369 To: phillco, #hg-reviewers Cc: durin42, lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 6] i18n: ignore docstring for modules under mercurial
# HG changeset patch # User FUJIWARA Katsunori# Date 1502798786 -32400 # Tue Aug 15 21:06:26 2017 +0900 # Node ID 9278f5eb1e79227c875ddf3a2147b18fc529c504 # Parent b6dd19c795147e675b9caf58383b6cafd3f03534 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 9278f5eb1e79 # EXP-Topic i18n-fix-update-pot-issues i18n: ignore docstring for modules under mercurial Docstring of modules is needed only for "hg help -e EXTNAME". This is a preparation for applying hggettext on util.py, which has module docstring, but it isn't needed for translation. diff --git a/i18n/hggettext b/i18n/hggettext --- a/i18n/hggettext +++ b/i18n/hggettext @@ -103,7 +103,7 @@ def docstrings(path): only extract docstrings from functions mentioned in these tables. """ mod = importpath(path) -if mod.__doc__: +if not path.startswith('mercurial/') and mod.__doc__: src = open(path).read() lineno = 1 + offset(src, mod.__doc__, path, 7) print(poentry(path, lineno, mod.__doc__)) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 6] i18n: use saved object to get actual function information if available
# HG changeset patch # User FUJIWARA Katsunori# Date 1502792844 -32400 # Tue Aug 15 19:27:24 2017 +0900 # Node ID b6dd19c795147e675b9caf58383b6cafd3f03534 # Parent 1d204d17d51eb143f1ef66426cec1831cd8c93bf # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r b6dd19c79514 # EXP-Topic i18n-fix-update-pot-issues i18n: use saved object to get actual function information if available To list up available compression types instead of ".. bundlecompressionmarker" in "hg help bundlespec" output, proxy object "docobject" is used, because: - current online help system requires that __doc__ of registered object (maybe, function) is already well formatted in reST syntax - bundletype() method of compressionengine classes is used to list up available compression types, but - __doc__ of bundletype() object (= "instancemethod") is read-only On the other hand, hggettext requires original function object, in order to get document location in source code. Therefore, description of each compression types isn't yet translatable. Even if translatable, translators should make much effort to determine location of original texts in source code. To get actual function information, this patch makes hggettext use function object saved as "_origfunc", if it is available. This patch also changes bundlecompressiontopics() side, in order to explain how these changes work easily. This patch is a part of preparations for making description of each compression types translatable. diff --git a/i18n/hggettext b/i18n/hggettext --- a/i18n/hggettext +++ b/i18n/hggettext @@ -119,6 +119,8 @@ def docstrings(path): for func, rstrip in functions: if func.__doc__: +docobj = func # this might be a proxy to provide formatted doc +func = getattr(func, '_origfunc', func) funcmod = inspect.getmodule(func) extra = '' if funcmod.__package__ == funcmod.__name__: @@ -128,8 +130,8 @@ def docstrings(path): src = inspect.getsource(func) name = "%s.%s" % (actualpath, func.__name__) lineno = inspect.getsourcelines(func)[1] -doc = func.__doc__ -origdoc = getattr(func, '_origdoc', '') +doc = docobj.__doc__ +origdoc = getattr(docobj, '_origdoc', '') if rstrip: doc = doc.rstrip() origdoc = origdoc.rstrip() diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -3752,6 +3752,8 @@ def bundlecompressiontopics(): value = docobject() value.__doc__ = doc +value._origdoc = engine.bundletype.__doc__ +value._origfunc = engine.bundletype items[bt[0]] = value ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 6] i18n: get translation entries for description of each compression engines
# HG changeset patch # User FUJIWARA Katsunori# Date 1502798973 -32400 # Tue Aug 15 21:09:33 2017 +0900 # Node ID 2f24939cbd6674abc6815746a07049fa98fa7fa6 # Parent 9278f5eb1e79227c875ddf3a2147b18fc529c504 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 2f24939cbd66 # EXP-Topic i18n-fix-update-pot-issues i18n: get translation entries for description of each compression engines Now, hggettext can be applied safely on util.py, of which i18nfunctions contains appropriate objects related to each compression types. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -132,6 +132,7 @@ i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n mercurial/templater.py \ mercurial/filemerge.py \ mercurial/hgweb/webcommands.py \ + mercurial/util.py \ $(DOCFILES) > i18n/hg.pot.tmp # All strings marked for translation in Mercurial contain # ASCII characters only. But some files contain string diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -3759,5 +3759,7 @@ def bundlecompressiontopics(): return items +i18nfunctions = bundlecompressiontopics().values() + # convenient shortcut dst = debugstacktrace ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 6] largefiles: fix help text to avoid warning at "make update-pot"
# HG changeset patch # User FUJIWARA Katsunori# Date 1501604107 -32400 # Wed Aug 02 01:15:07 2017 +0900 # Node ID abd0f3801a00bf7d3e5a74de796ec68d97d3e9dd # Parent 17bdacaa47c5b08ebe4e5b8e140b9c0f6d4bf129 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r abd0f3801a00 # EXP-Topic i18n-fix-update-pot-issues largefiles: fix help text to avoid warning at "make update-pot" This change helps hggettext to find out help text in original source, because it assumes that backslash ('\') is doubled in docstring. diff --git a/hgext/largefiles/__init__.py b/hgext/largefiles/__init__.py --- a/hgext/largefiles/__init__.py +++ b/hgext/largefiles/__init__.py @@ -91,7 +91,7 @@ tracked as largefiles:: [largefiles] patterns = *.jpg -re:.*\.(png|bmp)$ +re:.*\\.(png|bmp)$ library.zip content/audio/* ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 6] i18n: ignore doctest part to avoid warning at "make update-pot"
# HG changeset patch # User FUJIWARA Katsunori# Date 1502605216 -32400 # Sun Aug 13 15:20:16 2017 +0900 # Node ID 1d204d17d51eb143f1ef66426cec1831cd8c93bf # Parent abd0f3801a00bf7d3e5a74de796ec68d97d3e9dd # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 1d204d17d51e # EXP-Topic i18n-fix-update-pot-issues i18n: ignore doctest part to avoid warning at "make update-pot" hggettext assumes that backslashes in docstring are always doubled in original source code, in order to find the location of original docstring out certainly. This assumption almost always works as expected. But doctest easily breaks it, because many of backslashes in doctests aren't doubled. This mismatching causes "unknown offset in ..." warning at "make update-pot". To avoid such warning, this patch ignores doctest part of docstring before finding the location of original docstring out. BTW, at this patch, only person() in templatefilters.py has doctest part, which causes "unknown offset ..." warning. Therefore, just making backslashes in that doctest doubled can avoid such warning, too. But forcing doctest writers to double backslashes in doctest isn't reasonable, IMHO. diff --git a/i18n/hggettext b/i18n/hggettext --- a/i18n/hggettext +++ b/i18n/hggettext @@ -24,6 +24,7 @@ from __future__ import absolute_import, import inspect import os +import re import sys @@ -60,9 +61,15 @@ def poentry(path, lineno, s): 'msgid %s\n' % normalize(s) + 'msgstr ""\n') +doctestre = re.compile(r'^ +>>> ', re.MULTILINE) def offset(src, doc, name, default): """Compute offset or issue a warning on stdout.""" +# remove doctest part, in order to avoid backslash mismatching +m = doctestre.search(doc) +if m: +doc = doc[:m.start()] + # Backslashes in doc appear doubled in src. end = src.find(doc.replace('\\', '')) if end == -1: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 6] i18n: make hggettext use original docstring to compute offset
# HG changeset patch # User FUJIWARA Katsunori# Date 1501603400 -32400 # Wed Aug 02 01:03:20 2017 +0900 # Node ID 17bdacaa47c5b08ebe4e5b8e140b9c0f6d4bf129 # Parent 05264fc9d8d64159ab942c1bde400238f2c0ec88 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 17bdacaa47c5 # EXP-Topic i18n-fix-update-pot-issues i18n: make hggettext use original docstring to compute offset Before this patch, hggettext uses __doc__ of each functions to compute offset of document text. But __doc__ of many functions is already modified by decorators in registrar (e.g. @templatekeyword adds ":NAME: " prefix to it), and hggettext can not find it out in original source. This causes many "unknown offset in ..." warning at "make update-pot", and leaving them might cause overlooking serious problems. This patch makes hggettext use original docstring, which decorators in registrar save into _origdoc, to compute offset. Even after this patch, there are still a few "unknown offset in ..." warning at "make update-pot" for specific reasons. These will be fixed later one by one. diff --git a/i18n/hggettext b/i18n/hggettext --- a/i18n/hggettext +++ b/i18n/hggettext @@ -122,9 +122,14 @@ def docstrings(path): name = "%s.%s" % (actualpath, func.__name__) lineno = inspect.getsourcelines(func)[1] doc = func.__doc__ +origdoc = getattr(func, '_origdoc', '') if rstrip: doc = doc.rstrip() -lineno += offset(src, doc, name, 1) +origdoc = origdoc.rstrip() +if origdoc: +lineno += offset(src, origdoc, name, 1) +else: +lineno += offset(src, doc, name, 1) print(poentry(actualpath, lineno, doc)) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D98: revset: support reading aliases from a .hgrevsets file
quark added a comment. In https://phab.mercurial-scm.org/D98#6041, @mharbison72 wrote: > I thought about doing this, instead of fixing up a stripped down projrc extension. But then you have to get every developer to edit the local .hg/hgrc file for every clone they have. So even if we have to have this off by default, I still see value in this in a corporate environment. Our solution for this is to tell people to use a special clone script. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D98 To: indygreg, #hg-reviewers Cc: durin42, yuja, mharbison72, quark, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5660] New: hg should not put warning messages in stdout
https://bz.mercurial-scm.org/show_bug.cgi?id=5660 Bug ID: 5660 Summary: hg should not put warning messages in stdout Product: Mercurial Version: unspecified Hardware: PC OS: Linux Status: UNCONFIRMED Severity: bug Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: aalekse...@janestreet.com CC: mercurial-devel@mercurial-scm.org This is basically a duplicate of https://bz.mercurial-scm.org/show_bug.cgi?id=2828, but I think the resolution of that is insufficient. Currently hg prints various diagnostic/warning messages to stdout even for commands that produce machine-readable output. For example: $ hg id 'ssh://irrelevant' -e 'echo ssh diagnostic message >&2; true' 2>/dev/null remote: ssh diagnostic message EXIT STATUS 255 These messages get printed to stdout even in the case of success, which means that it's almost impossible to use [hg] in programs that require the output to be in the correct format. If you're lucky these warning messages won't parse, and if you're unlucky you might end up interpreting them as something meaningful. Examples of such messages that actually cause issues include: - waiting for lock ... - got lock after ... - warning messages from ssh: -- remote: X11 forwarding request failed on channel ... -- remote: ControlSocket ... already exists, disabling multiplexing [--quiet] was proposed as a workaround, and I think it's great when the [hg] command ends up succeeding. The problem is that if the command fails you can end up with a much less informative error message. E.g. this command doesn't show why ssh failed: $ hg id 'ssh://irrelevant' --quiet -e 'echo ssh diagnostic message >&2; false' 2>/dev/null EXIT STATUS 255 -- 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
D351: demandimport: disable by default if chg is being used
quark added a comment. I tried that approach. If we only set `HGDEMANDIMPORT` for the forked process to execute chg, it will be an infinite loop - environment config hash will mismatch. Setting `HGDEMANDIMPORT` for both the forked and non-forked chg client process seems less cleaner. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D351 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D350: demandimport: test whether to enable or not in hg script
quark added a comment. `sys.modules['hgdemandimport']` being set? Maybe I should remove it from commit message. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D350 To: quark, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 STABLE] transaction: ignore I/O errors during abort logging (issue5658)
On Mon, 14 Aug 2017 17:22:53 -0700, Gregory Szorc wrote: > On Mon, Aug 14, 2017 at 4:40 PM, Jun Wuwrote: > Yes, wrapping report() is better than the current patch. But it still isn't > sufficient because various callbacks can call e.g. ui.write() and run into > the same trouble. [...] > > > The proper solution is to make some stdio I/O errors non-fatal > > > during transaction abort. Individual call sites shouldn't have > > > to know to catch and ignore errors during logging, IMO. This was > > > the previous behavior before e9646ff34d55 and 1bfb9a63b98e. > > > I'm not sure how to implement this in a manner appropriate for > > > stable because the abort method and transaction object don't have > > > an explicit handle on the ui instance. We could potentially > > > revert e9646ff34d55 and 1bfb9a63b98e. But I'm not sure of the > > > consequences. I think it's okay to revert these changesets. Perhaps this problem isn't just for the transaction. Maybe we can take IOError of ui.status/warn/note/debug/write_err as non-fatal because they won't carry the data requested by user. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D402: util: make nogc effective for CPython
This revision was automatically updated to reflect the committed changes. Closed by commit rHG05264fc9d8d6: util: make nogc effective for CPython (authored by quark). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D402?vs=909=924 REVISION DETAIL https://phab.mercurial-scm.org/D402 AFFECTED FILES mercurial/util.py CHANGE DETAILS diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -964,10 +964,9 @@ into. As a workaround, disable GC while building complex (huge) containers. -This garbage collector issue have been fixed in 2.7. +This garbage collector issue have been fixed in 2.7. But it still affect +CPython's performance. """ -if sys.version_info >= (2, 7): -return func def wrapper(*args, **kwargs): gcenabled = gc.isenabled() gc.disable() @@ -978,6 +977,10 @@ gc.enable() return wrapper +if pycompat.ispypy: +# PyPy runs slower with gc disabled +nogc = lambda x: x + def pathto(root, n1, n2): '''return the relative path from one place to another. root should use os.sep to separate directories To: quark, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D301: scmutil: use util.shellquote instead of %r
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2cd5aba5e1d2: scmutil: use util.shellquote instead of %r (authored by durin42). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D301?vs=684=923 REVISION DETAIL https://phab.mercurial-scm.org/D301 AFFECTED FILES mercurial/scmutil.py tests/test-add.t tests/test-copy.t tests/test-rename.t CHANGE DETAILS diff --git a/tests/test-rename.t b/tests/test-rename.t --- a/tests/test-rename.t +++ b/tests/test-rename.t @@ -12,7 +12,7 @@ $ hg rename d1/d11/a1 d2/c $ hg --config ui.portablefilenames=abort rename d1/a d1/con.xml - abort: filename contains 'con', which is reserved on Windows: 'd1/con.xml' + abort: filename contains 'con', which is reserved on Windows: d1/con.xml [255] $ hg sum parent: 0:9b4b6e7b2c26 tip diff --git a/tests/test-copy.t b/tests/test-copy.t --- a/tests/test-copy.t +++ b/tests/test-copy.t @@ -15,7 +15,7 @@ $ hg status $ hg copy a b $ hg --config ui.portablefilenames=abort copy a con.xml - abort: filename contains 'con', which is reserved on Windows: 'con.xml' + abort: filename contains 'con', which is reserved on Windows: con.xml [255] $ hg status A b diff --git a/tests/test-add.t b/tests/test-add.t --- a/tests/test-add.t +++ b/tests/test-add.t @@ -44,14 +44,14 @@ abort: ui.portablefilenames value is invalid ('jump') [255] $ hg --config ui.portablefilenames=abort add con.xml - abort: filename contains 'con', which is reserved on Windows: 'con.xml' + abort: filename contains 'con', which is reserved on Windows: con.xml [255] $ hg st A a A b ? con.xml $ hg add con.xml - warning: filename contains 'con', which is reserved on Windows: 'con.xml' + warning: filename contains 'con', which is reserved on Windows: con.xml $ hg st A a A b diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -273,7 +273,7 @@ if abort or warn: msg = util.checkwinfilename(f) if msg: -msg = "%s: %r" % (msg, f) +msg = "%s: %s" % (msg, util.shellquote(f)) if abort: raise error.Abort(msg) ui.warn(_("warning: %s\n") % msg) To: durin42, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel