D5792: uncommit: added interactive mode(issue6062)
taapas1128 added a comment. @pulkit Can you please review this . I did not send a patch regarding `-n` flag because tests could be completed without it and also it would mean i would have to import large chunks of code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5792 To: taapas1128, #hg-reviewers Cc: pulkit, lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
martinvonz added a comment. In https://phab.mercurial-scm.org/D5949#86909, @martinvonz wrote: > In https://phab.mercurial-scm.org/D5949#86908, @JordiGH wrote: > > > So, I haven't been here in a while. Do we still do V2s for this kind of thing? > > > Often fixed in n flight. I'll still fix it later tonight if I remember. But to answer your question me generally: I think this kind of thing is usually ignored. I have seen so many of my own commit messages have typos and still get accepted (and I notice the typo later). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 To: martinvonz, #hg-reviewers Cc: JordiGH, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
martinvonz added a comment. In https://phab.mercurial-scm.org/D5949#86908, @JordiGH wrote: > So, I haven't been here in a while. Do we still do V2s for this kind of thing? Often fixed in n flight. I'll still fix it later tonight if I remember. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 To: martinvonz, #hg-reviewers Cc: JordiGH, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
JordiGH added a comment. So, I haven't been here in a while. Do we still do V2s for this kind of thing? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 To: martinvonz, #hg-reviewers Cc: JordiGH, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
martinvonz added a comment. In https://phab.mercurial-scm.org/D5949#86905, @JordiGH wrote: > > fix typo in synpsis > > in synpsis > > synpsis > > https://en.wikipedia.org/wiki/Muphry%27s_law Heh, I initially typo'ed "typo" as "typy", but I noticed that one. Impressive that I squeezed another typo in in those few words REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 To: martinvonz, #hg-reviewers Cc: JordiGH, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
JordiGH added a comment. > fix typo in synpsis > in synpsis > synpsis https://en.wikipedia.org/wiki/Muphry%27s_law REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 To: martinvonz, #hg-reviewers Cc: JordiGH, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5952: url: always use str for proxy configuration
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previously, proxies didn't work on Python 3 for various reasons. First, the keys to the "proxies" dict are fed into a `setattr(self, "%s_open", ...)` call and passing bytestrings results in setting an oddly named attribute due to the b'' in %s formatting. This resulted in "http_open" and "https_open" not being properly overridden and proxies not being used. Second, the standard library was expecting proxy URLs to be str. And various operations (including our custom code in url.py) would fail to account for the str/bytes mismatch. This commit normalizes everything to str and adjusts our proxy code in url.py to account for the presence of str on Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5952 AFFECTED FILES mercurial/url.py CHANGE DETAILS diff --git a/mercurial/url.py b/mercurial/url.py --- a/mercurial/url.py +++ b/mercurial/url.py @@ -131,17 +131,19 @@ else: self.no_list = no_list -proxyurl = bytes(proxy) -proxies = {'http': proxyurl, 'https': proxyurl} -ui.debug('proxying through %s\n' % util.hidepassword(proxyurl)) +# Keys and values need to be str because the standard library +# expects them to be. +proxyurl = str(proxy) +proxies = {r'http': proxyurl, r'https': proxyurl} +ui.debug('proxying through %s\n' % util.hidepassword(bytes(proxy))) else: proxies = {} urlreq.proxyhandler.__init__(self, proxies) self.ui = ui def proxy_open(self, req, proxy, type_): -host = urllibcompat.gethost(req).split(':')[0] +host = pycompat.bytesurl(urllibcompat.gethost(req)).split(':')[0] for e in self.no_list: if host == e: return None @@ -184,15 +186,15 @@ def _generic_start_transaction(handler, h, req): tunnel_host = req._tunnel_host if tunnel_host: -if tunnel_host[:7] not in ['http://', 'https:/']: -tunnel_host = 'https://' + tunnel_host +if tunnel_host[:7] not in [r'http://', r'https:/']: +tunnel_host = r'https://' + tunnel_host new_tunnel = True else: tunnel_host = urllibcompat.getselector(req) new_tunnel = False if new_tunnel or tunnel_host == urllibcompat.getfullurl(req): # has proxy -u = util.url(tunnel_host) +u = util.url(pycompat.bytesurl(tunnel_host)) if new_tunnel or u.scheme == 'https': # only use CONNECT for HTTPS h.realhostport = ':'.join([u.host, (u.port or '443')]) h.headers = req.headers.copy() 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
D5951: py3: port tinyproxy.py to work with Python 3
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY There were various str/bytes mismatches in the code. This caused the proxy server to misbehave at run-time. The manifestation was typically premature socket disconnect from the perspective of the client. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5951 AFFECTED FILES tests/tinyproxy.py CHANGE DETAILS diff --git a/tests/tinyproxy.py b/tests/tinyproxy.py --- a/tests/tinyproxy.py +++ b/tests/tinyproxy.py @@ -20,7 +20,10 @@ import socket import sys -from mercurial import util +from mercurial import ( +pycompat, +util, +) httpserver = util.httpserver socketserver = util.socketserver @@ -77,10 +80,11 @@ try: if self._connect_to(self.path, soc): self.log_request(200) -self.wfile.write(self.protocol_version + - " 200 Connection established\r\n") -self.wfile.write("Proxy-agent: %s\r\n" % self.version_string()) -self.wfile.write("\r\n") +self.wfile.write(pycompat.bytestr(self.protocol_version) + + b" 200 Connection established\r\n") +self.wfile.write(b"Proxy-agent: %s\r\n" % + pycompat.bytestr(self.version_string())) +self.wfile.write(b"\r\n") self._read_write(soc, 300) finally: print("\t" "bye") @@ -97,15 +101,17 @@ try: if self._connect_to(netloc, soc): self.log_request() -soc.send("%s %s %s\r\n" % ( -self.command, -urlreq.urlunparse(('', '', path, params, query, '')), -self.request_version)) +url = urlreq.urlunparse(('', '', path, params, query, '')) +soc.send(b"%s %s %s\r\n" % ( +pycompat.bytestr(self.command), +pycompat.bytestr(url), +pycompat.bytestr(self.request_version))) self.headers['Connection'] = 'close' del self.headers['Proxy-Connection'] -for key_val in self.headers.items(): -soc.send("%s: %s\r\n" % key_val) -soc.send("\r\n") +for key, val in self.headers.items(): +soc.send(b"%s: %s\r\n" % (pycompat.bytestr(key), + pycompat.bytestr(val))) +soc.send(b"\r\n") self._read_write(soc) finally: print("\t" "bye") 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
D5950: url: always access req._tunnel_host
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The getattr() was there to handle Python versions before 2.6, which lacked this attribute. We /might/ be able to further delete some code here. However, the behavior here is extremely hard to follow because large parts of this code duplicate code from the Python standard library and it is difficult to understand what is actually needed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5950 AFFECTED FILES mercurial/url.py CHANGE DETAILS diff --git a/mercurial/url.py b/mercurial/url.py --- a/mercurial/url.py +++ b/mercurial/url.py @@ -179,10 +179,10 @@ return proxyres return keepalive.HTTPConnection.getresponse(self) -# general transaction handler to support different ways to handle -# HTTPS proxying before and after Python 2.6.3. +# Large parts of this function have their origin from before Python 2.6 +# and could potentially be removed. def _generic_start_transaction(handler, h, req): -tunnel_host = getattr(req, '_tunnel_host', None) +tunnel_host = req._tunnel_host if tunnel_host: if tunnel_host[:7] not in ['http://', 'https:/']: tunnel_host = 'https://' + tunnel_host 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
[PATCH] walkchangerevs: obey allfiles parameter when taking the slow path
# HG changeset patch # User Jordi Gutiérrez Hermoso # Date 1550009431 18000 # Tue Feb 12 17:10:31 2019 -0500 # Node ID 06f76b4009c4802a48abc184984d0eebc7d7d91e # Parent 61415361e90684a8c7a031413e9182f51937c2e7 walkchangerevs: obey allfiles parameter when taking the slow path When walkchangerevs sees that there's a pattern, it hits the slow path. The slow path in turn reverts to the old dumb grep behaviour of only looking at files changed at each revision. Therefore, a command such as hg grep -l --all-files '.*' 'glob:**' would show you all the nonempty files touched by the current revision. This modifies that behaviour to look at the manifest at each revision instead of the changed files in case that --all-files was requested. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1961,7 +1961,10 @@ def walkchangerevs(repo, match, opts, pr else: self.revs.discard(value) ctx = change(value) -matches = [f for f in ctx.files() if match(f)] +if allfiles: +matches = list(ctx.manifest().walk(match)) +else: +matches = [f for f in ctx.files() if match(f)] if matches: fncache[value] = matches self.set.add(value) diff --git a/tests/test-grep.t b/tests/test-grep.t --- a/tests/test-grep.t +++ b/tests/test-grep.t @@ -517,5 +517,8 @@ test -rMULTIREV with --all-files $ hg grep -r "0:2" "unmod" --all-files um um:0:unmod um:1:unmod + $ hg grep -r "0:2" "unmod" --all-files "glob:**/um" # Check that patterns also work + um:0:unmod + um:1:unmod $ cd .. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5945: rust: itering less on MissingAncestors.bases for max()
kevincox added inline comments. INLINE COMMENTS > gracinet wrote in ancestors.rs:41 > I must confess to have hesitated a bit on that one. On one hand, it would > work, but semantically if ever a new "special" revision -2 is introduced, > this could become problematic. On the other hand, there are probably a few > areas that already depend on the fact that NULL_REVISION is the smallest one. > > From the graph side of things, NULL_REVISION being a common ancestor of all > revisions, so it must be smaller or equal than all, so it doesn't matter much. > > Option was merely a simple way to be sure not to be wrong, I'm open > to suggestions. If you don't want to depend on the value of NULL_REVISION you can use the minimum value for the type backing revision. Other special revisions shouldn't be relevant because you shouldn't be comparing them as the max anyways. That being said the currents state is fine. So if you think it makes more sense that sounds good to me. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5945 To: gracinet, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5949: debugpathcopies: fix typo in synpsis
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5949 AFFECTED FILES mercurial/debugcommands.py CHANGE DETAILS diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -1808,7 +1808,7 @@ @command('debugpathcopies', cmdutil.walkopts, - 'hg debugcopies REV1 REV2 [FILE]', + 'hg debugpathcopies REV1 REV2 [FILE]', inferrepo=True) def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts): """show copies between two revisions""" 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
D5948: debugrename: don't require at least one path
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I don't see a reason that it needs to require a path. Most commands match everything when no paths are given, but here you have to do something like `hg debugrename -r . .` (from the repo root) to match everything. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5948 AFFECTED FILES mercurial/debugcommands.py CHANGE DETAILS diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -2010,13 +2010,13 @@ @command('debugrename', [('r', 'rev', '', _('revision to debug'), _('REV'))], -_('[-r REV] FILE')) -def debugrename(ui, repo, file1, *pats, **opts): +_('[-r REV] [FILE]...')) +def debugrename(ui, repo, *pats, **opts): """dump rename information""" opts = pycompat.byteskwargs(opts) ctx = scmutil.revsingle(repo, opts.get('rev')) -m = scmutil.match(ctx, (file1,) + pats, opts) +m = scmutil.match(ctx, pats, opts) for abs in ctx.walk(m): fctx = ctx[abs] o = fctx.filelog().renamed(fctx.filenode()) 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
D5941: tweakdefault: Add better documentation for ui.tweakdefault(issue6000)
akshjain.jain74 updated this revision to Diff 14050. akshjain.jain74 retitled this revision from "config.txt: Add better documentation for ui.tweakdefault (issue6000)" to "tweakdefault: Add better documentation for ui.tweakdefault (issue6000)". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5941?vs=14038=14050 REVISION DETAIL https://phab.mercurial-scm.org/D5941 AFFECTED FILES mercurial/help/config.txt CHANGE DETAILS diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -2401,6 +2401,13 @@ effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does not include ``tweakdefaults``. (default: False) +It is a way to opt-in to what the community has decided +is the "best" default experience for Mercurial. + +It greps our current directory instead of grepping every filelog +at all revisions and reportin g the highest filelog revision that matches. + + It currently means:: .. tweakdefaultsmarker To: akshjain.jain74, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5947: revlog: use iterbytestr()
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Otherwise we iterate over integers in Python 3 and the character compare fails. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5947 AFFECTED FILES mercurial/revlog.py CHANGE DETAILS diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1340,7 +1340,7 @@ return True def maybewdir(prefix): -return all(c == 'f' for c in prefix) +return all(c == 'f' for c in pycompat.iterbytestr(prefix)) hexnode = hex(node) 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
D5897: test: stabilize test-wireproto-exchangev2.t flaky output
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1ab6f5df263e: test: stabilize test-wireproto-exchangev2.t flaky output (authored by lothiraldan, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5897?vs=13917=14048 REVISION DETAIL https://phab.mercurial-scm.org/D5897 AFFECTED FILES tests/test-wireproto-exchangev2.t CHANGE DETAILS diff --git a/tests/test-wireproto-exchangev2.t b/tests/test-wireproto-exchangev2.t --- a/tests/test-wireproto-exchangev2.t +++ b/tests/test-wireproto-exchangev2.t @@ -36,22 +36,18 @@ Test basic clone - $ hg --debug clone -U http://localhost:$HGPORT client-simple +Output is flaky, save it in a file and check part independently + $ hg --debug clone -U http://localhost:$HGPORT client-simple > clone-output + + $ cat clone-output | grep -v "received frame" using http://localhost:$HGPORT/ sending capabilities command query 1; heads sending 2 commands sending command heads: {} sending command known: { 'nodes': [] } - received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) - received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) - received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos) sending 1 commands sending command changesetdata: { 'fields': set([ @@ -71,10 +67,6 @@ } ] } - received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) - received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=941; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) add changeset 3390ef850073 add changeset 4432d83626e8 add changeset cd2534766bec @@ -97,10 +89,6 @@ ], 'tree': '' } - received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) - received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=992; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) - received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) sending 1 commands sending command filesdata: { 'fields': set([ @@ -121,13 +109,32 @@ } ] } + updating the branch cache + new changesets 3390ef850073:caa2a465451d (3 drafts) + (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob) + + $ cat clone-output | grep "received frame" + received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) + received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) + received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos) + received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) + received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=941; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) + received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos) + received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=992; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) + received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings;
D5946: server: allow customizing the default repo filter
joerg.sonnenberger created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY hgweb has the (undocument) configuration option web.view that allows restricting visible revisions to immutable. This is useful for serving the same storage as publishing and non-publishing repo. Add the new server.view option to serve the same purpose by changing the default behavior of `getdispatchrepo`. Drop the hard-coded 'served' filter in the batch handler of v1 of the wire proto, this is a left-over from the days before `getdispatchrepo` existed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5946 AFFECTED FILES mercurial/configitems.py mercurial/help/config.txt mercurial/wireprotov1server.py mercurial/wireprotov2server.py 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 @@ -78,6 +78,9 @@ yield unmangle(f.value) class serverrepo(object): +def __init__(self, ui): +self.ui = ui + def greet(self, name): return b"Hello, " + name @@ -94,7 +97,7 @@ wireprotov1server.commands[b'greet'] = (greet, b'name') -srv = serverrepo() +srv = serverrepo(uimod.ui()) clt = clientpeer(srv, uimod.ui()) def printb(data, end=b'\n'): diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -342,7 +342,8 @@ action) def getdispatchrepo(repo, proto, command): -return repo.filtered('served') +viewconfig = repo.ui.config('server', 'view') +return repo.filtered(viewconfig) def dispatch(repo, proto, command, redirect): """Run a wire protocol command. diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py --- a/mercurial/wireprotov1server.py +++ b/mercurial/wireprotov1server.py @@ -64,7 +64,8 @@ extensions that need commands to operate on different repo views under specialized circumstances. """ -return repo.filtered('served') +viewconfig = repo.ui.config('server', 'view') +return repo.filtered(viewconfig) def dispatch(repo, proto, command): repo = getdispatchrepo(repo, proto, command) @@ -166,7 +167,6 @@ @wireprotocommand('batch', 'cmds *', permission='pull') def batch(repo, proto, cmds, others): unescapearg = wireprototypes.unescapebatcharg -repo = repo.filtered("served") res = [] for pair in cmds.split(';'): op, args = pair.split(' ', 1) diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1990,6 +1990,12 @@ See also ``server.zliblevel``. +```view``` +Repository filter used when exchanging revisions with the peer. + +The default view (``served``) excludes secret and hidden changesets. +Another useful value is ``immutable`` (no draft, secret or hidden changesets). + ``smtp`` diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1029,6 +1029,9 @@ coreconfigitem('server', 'uncompressedallowsecret', default=False, ) +coreconfigitem('server', 'view', +default='served', +) coreconfigitem('server', 'validate', default=False, ) To: joerg.sonnenberger, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5945: rust: itering less on MissingAncestors.bases for max()
gracinet added inline comments. INLINE COMMENTS > kevincox wrote in ancestors.rs:41 > Does it make sense to just default this to -1 and remove the option? I must confess to have hesitated a bit on that one. On one hand, it would work, but semantically if ever a new "special" revision -2 is introduced, this could become problematic. On the other hand, there are probably a few areas that already depend on the fact that NULL_REVISION is the smallest one. From the graph side of things, NULL_REVISION being a common ancestor of all revisions, so it must be smaller or equal than all, so it doesn't matter much. Option was merely a simple way to be sure not to be wrong, I'm open to suggestions. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5945 To: gracinet, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5945: rust: itering less on MissingAncestors.bases for max()
gracinet updated this revision to Diff 14046. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5945?vs=14042=14046 REVISION DETAIL https://phab.mercurial-scm.org/D5945 AFFECTED FILES rust/hg-core/src/ancestors.rs rust/hg-core/src/dagops.rs CHANGE DETAILS diff --git a/rust/hg-core/src/dagops.rs b/rust/hg-core/src/dagops.rs --- a/rust/hg-core/src/dagops.rs +++ b/rust/hg-core/src/dagops.rs @@ -46,7 +46,9 @@ let mut heads: HashSet = iter_revs.clone().cloned().collect(); heads.remove(_REVISION); for rev in iter_revs { -remove_parents(graph, *rev, heads)?; +if *rev != NULL_REVISION { +remove_parents(graph, *rev, heads)?; +} } Ok(heads) } @@ -71,7 +73,9 @@ // mutating let as_vec: Vec = revs.iter().cloned().collect(); for rev in as_vec { -remove_parents(graph, rev, revs)?; +if rev != NULL_REVISION { +remove_parents(graph, rev, revs)?; +} } Ok(()) } diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs --- a/rust/hg-core/src/ancestors.rs +++ b/rust/hg-core/src/ancestors.rs @@ -38,6 +38,7 @@ pub struct MissingAncestors { graph: G, bases: HashSet, +max_base: Option, } impl AncestorsIterator { @@ -209,7 +210,13 @@ impl MissingAncestors { pub fn new(graph: G, bases: impl IntoIterator) -> Self { -MissingAncestors { graph: graph, bases: bases.into_iter().collect() } +let mut created = MissingAncestors { +graph: graph, +bases: HashSet::new(), +max_base: None, +}; +created.add_bases(bases); +created } pub fn has_bases() -> bool { @@ -237,12 +244,26 @@ Ok(self.bases) } +/// Add some revisions to `self.bases` +/// +/// Takes care of keeping `self.max_base` up to date. pub fn add_bases( self, new_bases: impl IntoIterator, ) { -self.bases.extend(new_bases); +// even if the type of Revision changes, +// NULL_REVISION would keep being the smallest +let mut max_base = self.max_base.unwrap_or(NULL_REVISION); +self.bases.extend(new_bases.into_iter().map(|r| { +if r > max_base { +max_base = r; +} +r +})); self.bases.remove(_REVISION); +if max_base != NULL_REVISION { +self.max_base = Some(max_base); +} } /// Remove all ancestors of self.bases from the revs set (in place) @@ -261,14 +282,11 @@ } // anything in revs > start is definitely not an ancestor of bases // revs <= start need to be investigated -// TODO optim: if a missingancestors is to be used several times, -// we shouldn't need to iterate each time on bases -let start = match self.bases.iter().cloned().max() { -Some(m) => m, -None => { // self.bases is empty -return Ok(()); -} -}; + +let start = match self.max_base { +Some(r) => r, +None => {return Ok(());}}; + // whatever happens, we'll keep at least keepcount of them // knowing this gives us a earlier stop condition than // going all the way to the root @@ -285,12 +303,17 @@ Ok(()) } -/// Add rev's parents to self.bases +/// Add the parents of `rev` to `self.bases` +/// +/// This has no effect on `self.max_base` #[inline] fn add_parents( self, rev: Revision) -> Result<(), GraphError> { -// No need to bother the set with inserting NULL_REVISION over and -// over +if rev == NULL_REVISION { +return Ok(()); +} for p in self.graph.parents(rev)?.iter().cloned() { +// No need to bother the set with inserting NULL_REVISION over and +// over if p != NULL_REVISION { self.bases.insert(p); } @@ -320,12 +343,8 @@ if revs_visit.is_empty() { return Ok(Vec::new()); } - -let max_bases = -bases_visit.iter().cloned().max().unwrap_or(NULL_REVISION); -let max_revs = -revs_visit.iter().cloned().max().unwrap_or(NULL_REVISION); -let start = max(max_bases, max_revs); +let max_revs = revs_visit.iter().cloned().max().unwrap(); +let start = max(self.max_base.unwrap_or(max_revs), max_revs); // TODO heuristics for with_capacity()? let mut missing: Vec = Vec::new(); @@ -571,11 +590,13 @@ missing_ancestors.get_bases().iter().cloned().collect(); as_vec.sort(); assert_eq!(as_vec, [1, 3, 5]); +assert_eq!(missing_ancestors.max_base, Some(5)); missing_ancestors.add_bases([3, 7, 8].iter().cloned()); as_vec =
mercurial@41681: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/61415361e906 changeset: 41681:61415361e906 bookmark:@ tag: tip user:Kyle Lippincott date:Mon Feb 04 14:29:03 2019 -0800 summary: zsh: fix `hg resolve` completion when in a subdirectory (issue6067) -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 6077] New: Traceback in hg fix: TypeError: argument of type 'NoneType' is not iterable
https://bz.mercurial-scm.org/show_bug.cgi?id=6077 Bug ID: 6077 Summary: Traceback in hg fix: TypeError: argument of type 'NoneType' is not iterable Product: Mercurial Version: 4.9 Hardware: PC OS: Linux Status: UNCONFIRMED Severity: bug Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: z...@zash.se CC: mercurial-devel@mercurial-scm.org hg config: ``` [extensions] fix = [fix] trailing-whitespace:command = sed trailing-whitespace:linerange = -e '{first},{last}s/\s\+$//' ``` Steps to reproduce: ``` $ hg init $ echo hello > test $ hg add test $ hg fix -w ``` Full traceback: ``` Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/mercurial/worker.py", line 191, in _posixworker ret = scmutil.callcatch(ui, workerfunc) File "/usr/lib/python2.7/dist-packages/mercurial/scmutil.py", line 165, in callcatch return func() File "/usr/lib/python2.7/dist-packages/mercurial/worker.py", line 187, in workerfunc for result in func(*(staticargs + (pargs,))): File "/usr/lib/python2.7/dist-packages/hgext/fix.py", line 204, in getfixes newdata = fixfile(ui, opts, fixers, ctx, path, basectxs[rev]) File "/usr/lib/python2.7/dist-packages/hgext/fix.py", line 498, in fixfile if fixer.affects(opts, fixctx, path): File "/usr/lib/python2.7/dist-packages/hgext/fix.py", line 672, in affects return scmutil.match(fixctx, [self._pattern], opts)(path) File "/usr/lib/python2.7/dist-packages/mercurial/scmutil.py", line 790, in match return matchandpats(ctx, pats, opts, globbed, default, badfn=badfn)[0] File "/usr/lib/python2.7/dist-packages/mercurial/scmutil.py", line 781, in matchandpats default, listsubrepos=opts.get('subrepos'), badfn=badfn) File "/usr/lib/python2.7/dist-packages/mercurial/context.py", line 1411, in match icasefs=icasefs) File "/usr/lib/python2.7/dist-packages/mercurial/match.py", line 177, in match kindpats = normalize(patterns, default, root, cwd, auditor, warn) File "/usr/lib/python2.7/dist-packages/mercurial/match.py", line 222, in _donormalize for kind, pat in [_patsplit(p, default) for p in patterns]: File "/usr/lib/python2.7/dist-packages/mercurial/match.py", line 1029, in _patsplit if ':' in pattern: TypeError: argument of type 'NoneType' is not iterable ``` -- 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
D5945: rust: itering less on MissingAncestors.bases for max()
kevincox accepted this revision. kevincox added inline comments. INLINE COMMENTS > ancestors.rs:41 > bases: HashSet, > +max_base: Option, > } Does it make sense to just default this to -1 and remove the option? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5945 To: gracinet, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5944: rust: stop putting NULL_REVISION in MissingAncestors.bases
kevincox accepted this revision. kevincox added inline comments. INLINE COMMENTS > ancestors.rs:245 > self.bases.extend(new_bases); > +self.bases.remove(_REVISION); > } I think it would be more clear if you filtered the NULL_REVISION out before extending the set. let new_bases = new_bases.into_iter().filter(|| rev != NULL_REVISION); self.bases.extend(new_bases); REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5944 To: gracinet, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5836: zsh: fix `hg resolve` completion when in a subdirectory (issue6067)
This revision was automatically updated to reflect the committed changes. Closed by commit rHG61415361e906: zsh: fix `hg resolve` completion when in a subdirectory (issue6067) (authored by spectral, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D5836?vs=13763=14045#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5836?vs=13763=14045 REVISION DETAIL https://phab.mercurial-scm.org/D5836 AFFECTED FILES contrib/zsh_completion CHANGE DETAILS diff --git a/contrib/zsh_completion b/contrib/zsh_completion --- a/contrib/zsh_completion +++ b/contrib/zsh_completion @@ -248,7 +248,7 @@ [[ -d $PREFIX ]] || PREFIX=$PREFIX:h - _hg_cmd resolve -l ./$PREFIX | while read rstate rpath + _hg_cmd resolve -l ./$PREFIX -T '{mergestatus}\ {relpath\(path\)}\\n' | while read rstate rpath do [[ $rstate == 'R' ]] && resolved_files+=($rpath) [[ $rstate == 'U' ]] && unresolved_files+=($rpath) To: spectral, #hg-reviewers, pulkit Cc: pulkit, av6, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@41680: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/8185c8abce87 changeset: 41680:8185c8abce87 bookmark:@ tag: tip user:Navaneeth Suresh date:Sun Feb 03 19:10:39 2019 +0530 summary: revset: add expectsize to check the size of a set -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5417: rust: translated random test of missingancestors
gracinet added a comment. @yuja I'm trying to find a compromise between our points of view : I'd like very much it to be run automatically (hence an integration test), and you want to be parametrizable. So, I'm pushing a version that has these two properties, working with env variables, since command-line arguments are already used by the testing framework. Hope it'll suit you, if it doesn't, I'll put it in examples and find a way to run it anyway REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5417 To: gracinet, #hg-reviewers Cc: yuja, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5417: rust: translated random test of missingancestors
gracinet updated this revision to Diff 14044. gracinet edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5417?vs=12856=14044 REVISION DETAIL https://phab.mercurial-scm.org/D5417 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/lib.rs rust/hg-core/tests/test_missing_ancestors.rs CHANGE DETAILS diff --git a/rust/hg-core/tests/test_missing_ancestors.rs b/rust/hg-core/tests/test_missing_ancestors.rs new file mode 100644 --- /dev/null +++ b/rust/hg-core/tests/test_missing_ancestors.rs @@ -0,0 +1,340 @@ +extern crate hg; +extern crate rand; +extern crate rand_pcg; + +use hg::testing::VecGraph; +use hg::Revision; +use hg::*; +use rand::distributions::{Distribution, LogNormal, Uniform}; +use rand::{thread_rng, Rng, RngCore, SeedableRng}; +use std::cmp::min; +use std::collections::HashSet; +use std::env; +use std::fmt::Debug; + +fn build_random_graph( +nodes_opt: Option, +rootprob_opt: Option, +mergeprob_opt: Option, +prevprob_opt: Option, +) -> VecGraph { +let nodes = nodes_opt.unwrap_or(100); +let rootprob = rootprob_opt.unwrap_or(0.05); +let mergeprob = mergeprob_opt.unwrap_or(0.2); +let prevprob = prevprob_opt.unwrap_or(0.7); + +let mut rng = thread_rng(); +let mut vg: VecGraph = Vec::with_capacity(nodes); +for i in 0..nodes { +if i == 0 || rng.gen_bool(rootprob) { +vg.push([NULL_REVISION, NULL_REVISION]) +} else if i == 1 { +vg.push([0, NULL_REVISION]) +} else if rng.gen_bool(mergeprob) { +let p1 = { +if i == 2 || rng.gen_bool(prevprob) { +(i - 1) as Revision +} else { +rng.gen_range(0, i - 1) as Revision +} +}; +// p2 is a random revision lower than i and different from p1 +let mut p2 = rng.gen_range(0, i - 1) as Revision; +if p2 >= p1 { +p2 = p2 + 1; +} +vg.push([p1, p2]); +} else if rng.gen_bool(prevprob) { +vg.push([(i - 1) as Revision, NULL_REVISION]) +} else { +vg.push([rng.gen_range(0, i - 1) as Revision, NULL_REVISION]) +} +} +vg +} + +/// Compute the ancestors set of all revisions of a VecGraph +fn ancestors_sets(vg: ) -> Vec> { +let mut ancs: Vec> = Vec::new(); +for i in 0..vg.len() { +let mut ancs_i = HashSet::new(); +ancs_i.insert(i as Revision); +for p in vg[i].iter().cloned() { +if p != NULL_REVISION { +ancs_i.extend([p as usize]); +} +} +ancs.push(ancs_i); +} +ancs +} + +#[derive(Clone, Debug)] +enum MissingAncestorsAction { +InitialBases(HashSet), +AddBases(HashSet), +RemoveAncestorsFrom(HashSet), +MissingAncestors(HashSet), +} + +/// An instrumented naive yet obviously correct implementation +/// +/// It also records all its actions for easy reproduction for replay +/// of problematic cases +struct NaiveMissingAncestors<'a> { +ancestors_sets: &'a Vec>, +graph: &'a VecGraph, // used for error reporting only +bases: HashSet, +history: Vec, +// for error reporting, assuming we are in a random test +random_seed: String, +} + +impl<'a> NaiveMissingAncestors<'a> { +fn new( +graph: &'a VecGraph, +ancestors_sets: &'a Vec>, +bases: , +random_seed: , +) -> Self { +Self { +ancestors_sets: ancestors_sets, +bases: bases.clone(), +graph: graph, +history: vec![MissingAncestorsAction::InitialBases(bases.clone())], +random_seed: random_seed.into(), +} +} + +fn add_bases( self, new_bases: HashSet) { +self.bases.extend(_bases); +self.history +.push(MissingAncestorsAction::AddBases(new_bases)) +} + +fn remove_ancestors_from( self, revs: HashSet) { +revs.remove(_REVISION); +self.history +.push(MissingAncestorsAction::RemoveAncestorsFrom(revs.clone())); +for base in self.bases.iter().cloned() { +if base != NULL_REVISION { +for rev in _sets[base as usize] { +revs.remove(); +} +} +} +} + +fn missing_ancestors( + self, +revs: impl IntoIterator, +) -> Vec { +let revs_as_set: HashSet = revs.into_iter().collect(); + +let mut missing: HashSet = HashSet::new(); +for rev in revs_as_set.iter().cloned() { +if rev != NULL_REVISION { +missing.extend(_sets[rev as usize]) +} +} +self.history +.push(MissingAncestorsAction::MissingAncestors(revs_as_set)); + +for base in self.bases.iter().cloned() { +if base != NULL_REVISION { +
D5836: zsh: fix `hg resolve` completion when in a subdirectory (issue6067)
pulkit added subscribers: av6, pulkit. pulkit accepted this revision. pulkit added a comment. Queued as per @av6 review. INLINE COMMENTS > zsh_completion:251 > > - _hg_cmd resolve -l ./$PREFIX | while read rstate rpath > + _hg_cmd resolve -l ./$PREFIX -T'{mergestatus}\ {relpath\(path\)}\\n' | > while read rstate rpath >do added a whitespace after `-T` as per @av6 suggestion. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5836 To: spectral, #hg-reviewers, pulkit Cc: pulkit, av6, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5813: revset: add expect to check the size of a set
pulkit added inline comments. INLINE COMMENTS > revset.py:866 > +def expectsize(repo, subset, x, order): > +"""Abort if the revset doesn't expect given size""" > +args = getargsdict(x, 'expectsize', 'set size') Can you improve this documentation as a follow-up? We should mentioned about specifying ranges, and also if the set has the given size, that set is returned. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5813 To: navaneeth.suresh, #hg-reviewers Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@41679: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/91701785c2c5 changeset: 41679:91701785c2c5 bookmark:@ tag: tip parent: 41678:9d0d8793e847 parent: 41614:f2f538725d07 user:Augie Fackler date:Mon Feb 11 11:18:37 2019 -0500 summary: merge with stable -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5813: revset: add expect to check the size of a set
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8185c8abce87: revset: add expectsize to check the size of a set (authored by navaneeth.suresh, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D5813?vs=14029=14043#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D5813?vs=14029=14043 REVISION DETAIL https://phab.mercurial-scm.org/D5813 AFFECTED FILES mercurial/revset.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -2978,3 +2978,63 @@ * set: 0 + +abort if the revset doesn't expect given size + $ log 'expectsize()' + hg: parse error: invalid set of arguments + [255] + $ log 'expectsize(0:2, a)' + hg: parse error: expectsize requires a size range or a positive integer + [255] + $ log 'expectsize(0:2, 3)' + 0 + 1 + 2 + + $ log 'expectsize(2:0, 3)' + 2 + 1 + 0 + $ log 'expectsize(0:1, 1)' + abort: revset size mismatch. expected 1, got 2! + [255] + $ log 'expectsize(0:4, -1)' + hg: parse error: negative size + [255] + $ log 'expectsize(0:2, 2:4)' + 0 + 1 + 2 + $ log 'expectsize(0:1, 3:5)' + abort: revset size mismatch. expected between 3 and 5, got 2! + [255] + $ log 'expectsize(0:1, -1:2)' + hg: parse error: negative size + [255] + $ log 'expectsize(0:1, 1:-2)' + hg: parse error: negative size + [255] + $ log 'expectsize(0:2, a:4)' + hg: parse error: size range bounds must be integers + [255] + $ log 'expectsize(0:2, 2:b)' + hg: parse error: size range bounds must be integers + [255] + $ log 'expectsize(0:2, 2:)' + 0 + 1 + 2 + $ log 'expectsize(0:2, :5)' + 0 + 1 + 2 + $ log 'expectsize(0:2, :)' + 0 + 1 + 2 + $ log 'expectsize(0:2, 4:)' + abort: revset size mismatch. expected between 4 and 11, got 3! + [255] + $ log 'expectsize(0:2, :2)' + abort: revset size mismatch. expected between 0 and 2, got 3! + [255] diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -861,6 +861,37 @@ contentdivergent = obsmod.getrevs(repo, 'contentdivergent') return subset & contentdivergent +@predicate('expectsize(set[, size])', safe=True, takeorder=True) +def expectsize(repo, subset, x, order): +"""Abort if the revset doesn't expect given size""" +args = getargsdict(x, 'expectsize', 'set size') +minsize = 0 +maxsize = len(repo) + 1 +err = '' +if 'size' not in args or 'set' not in args: +raise error.ParseError(_('invalid set of arguments')) +minsize, maxsize = getintrange(args['size'], + _('expectsize requires a size range' + ' or a positive integer'), + _('size range bounds must be integers'), + minsize, maxsize) +if minsize < 0 or maxsize < 0: +raise error.ParseError(_('negative size')) +rev = getset(repo, fullreposet(repo), args['set'], order=order) +if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize): +err = _('revset size mismatch.' +' expected between %d and %d, got %d') % (minsize, maxsize, + len(rev)) +elif minsize == maxsize and len(rev) != minsize: +err = _('revset size mismatch.' +' expected %d, got %d') % (minsize, len(rev)) +if err: +raise error.RepoLookupError(err) +if order == followorder: +return subset & rev +else: +return rev & subset + @predicate('extdata(source)', safe=False, weight=100) def extdata(repo, subset, x): """Changesets in the specified extdata source. (EXPERIMENTAL)""" To: navaneeth.suresh, #hg-reviewers Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5813: revset: add expect to check the size of a set
yuja added a comment. > +@predicate('expectsize(set[, size])', safe=True, takeorder=True) > +def expectrevsetsize(repo, subset, x, order): > +"""Abort if the revset doesn't expect given size""" > +args = getargsdict(x, 'expect', 'set size') Fixed function name and queued, thanks. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5813 To: navaneeth.suresh, #hg-reviewers Cc: yuja, pulkit, durin42, mjpieters, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D5813: revset: add expect to check the size of a set
> +@predicate('expectsize(set[, size])', safe=True, takeorder=True) > +def expectrevsetsize(repo, subset, x, order): > +"""Abort if the revset doesn't expect given size""" > +args = getargsdict(x, 'expect', 'set size') Fixed function name and queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5945: rust: itering less on MissingAncestors.bases for max()
gracinet created this revision. Herald added subscribers: mercurial-devel, kevincox, durin42. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Instead of iterating on the whole `self.bases` each time to find its max, we keep the latter in a separate member attribute and keep it up to date in `add_bases()` On a perfdiscovery done on PyPy, with repos prepared with `contrib/discovery-helper.sh 50 100`, this gives a slight improvement (around 0.5% on wall time, but 10% on CPU) before: ! wall 0.172801 comb 0.18 user 0.18 sys 0.00 (median of 541) after: ! wall 0.171798 comb 0.16 user 0.16 sys 0.00 (median of 551) (perf command run time upped because of bigger variability during this test). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5945 AFFECTED FILES contrib/perf.py rust/hg-core/src/ancestors.rs rust/hg-core/src/dagops.rs CHANGE DETAILS diff --git a/rust/hg-core/src/dagops.rs b/rust/hg-core/src/dagops.rs --- a/rust/hg-core/src/dagops.rs +++ b/rust/hg-core/src/dagops.rs @@ -46,7 +46,9 @@ let mut heads: HashSet = iter_revs.clone().cloned().collect(); heads.remove(_REVISION); for rev in iter_revs { -remove_parents(graph, *rev, heads)?; +if *rev != NULL_REVISION { +remove_parents(graph, *rev, heads)?; +} } Ok(heads) } @@ -71,7 +73,9 @@ // mutating let as_vec: Vec = revs.iter().cloned().collect(); for rev in as_vec { -remove_parents(graph, rev, revs)?; +if rev != NULL_REVISION { +remove_parents(graph, rev, revs)?; +} } Ok(()) } diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs --- a/rust/hg-core/src/ancestors.rs +++ b/rust/hg-core/src/ancestors.rs @@ -38,6 +38,7 @@ pub struct MissingAncestors { graph: G, bases: HashSet, +max_base: Option, } impl AncestorsIterator { @@ -209,7 +210,13 @@ impl MissingAncestors { pub fn new(graph: G, bases: impl IntoIterator) -> Self { -MissingAncestors { graph: graph, bases: bases.into_iter().collect() } +let mut created = MissingAncestors { +graph: graph, +bases: HashSet::new(), +max_base: None, +}; +created.add_bases(bases); +created } pub fn has_bases() -> bool { @@ -237,12 +244,26 @@ Ok(self.bases) } +/// Add some revisions to `self.bases` +/// +/// Takes care of keeping `self.max_base` up to date. pub fn add_bases( self, new_bases: impl IntoIterator, ) { -self.bases.extend(new_bases); +// even if the type of Revision changes, +// NULL_REVISION would keep being the smallest +let mut max_base = self.max_base.unwrap_or(NULL_REVISION); +self.bases.extend(new_bases.into_iter().map(|r| { +if r > max_base { +max_base = r; +} +r +})); self.bases.remove(_REVISION); +if max_base != NULL_REVISION { +self.max_base = Some(max_base); +} } /// Remove all ancestors of self.bases from the revs set (in place) @@ -261,14 +282,11 @@ } // anything in revs > start is definitely not an ancestor of bases // revs <= start need to be investigated -// TODO optim: if a missingancestors is to be used several times, -// we shouldn't need to iterate each time on bases -let start = match self.bases.iter().cloned().max() { -Some(m) => m, -None => { // self.bases is empty -return Ok(()); -} -}; + +let start = match self.max_base { +Some(r) => r, +None => {return Ok(());}}; + // whatever happens, we'll keep at least keepcount of them // knowing this gives us a earlier stop condition than // going all the way to the root @@ -285,12 +303,17 @@ Ok(()) } -/// Add rev's parents to self.bases +/// Add the parents of `rev` to `self.bases` +/// +/// This has no effect on `self.max_base` #[inline] fn add_parents( self, rev: Revision) -> Result<(), GraphError> { -// No need to bother the set with inserting NULL_REVISION over and -// over +if rev == NULL_REVISION { +return Ok(()); +} for p in self.graph.parents(rev)?.iter().cloned() { +// No need to bother the set with inserting NULL_REVISION over and +// over if p != NULL_REVISION { self.bases.insert(p); } @@ -320,12 +343,8 @@ if revs_visit.is_empty() { return Ok(Vec::new()); } - -let max_bases = -bases_visit.iter().cloned().max().unwrap_or(NULL_REVISION); -let max_revs = -
D5944: rust: stop putting NULL_REVISION in MissingAncestors.bases
gracinet created this revision. Herald added subscribers: mercurial-devel, kevincox, durin42. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As noted in initial review of MissingAncestors, adding NULL_REVISION in constructor in case the given `bases` is empty wasn't really useful, yet it's been kept for identity with the Python implementation REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5944 AFFECTED FILES rust/hg-core/src/ancestors.rs CHANGE DETAILS diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs --- a/rust/hg-core/src/ancestors.rs +++ b/rust/hg-core/src/ancestors.rs @@ -209,15 +209,11 @@ impl MissingAncestors { pub fn new(graph: G, bases: impl IntoIterator) -> Self { -let mut bases: HashSet = bases.into_iter().collect(); -if bases.is_empty() { -bases.insert(NULL_REVISION); -} -MissingAncestors { graph, bases } +MissingAncestors { graph: graph, bases: bases.into_iter().collect() } } pub fn has_bases() -> bool { -self.bases.iter().any(|| b != NULL_REVISION) +!self.bases.is_empty() } /// Return a reference to current bases. @@ -246,15 +242,19 @@ new_bases: impl IntoIterator, ) { self.bases.extend(new_bases); +self.bases.remove(_REVISION); } /// Remove all ancestors of self.bases from the revs set (in place) pub fn remove_ancestors_from( self, revs: HashSet, ) -> Result<(), GraphError> { revs.retain(|r| !self.bases.contains(r)); -// the null revision is always an ancestor +// the null revision is always an ancestor. Logically speaking +// it's debatable in case bases is empty, but the Python +// implementation always adds NULL_REVISION to bases, making it +// unconditionnally true. revs.remove(_REVISION); if revs.is_empty() { return Ok(()); @@ -265,8 +265,7 @@ // we shouldn't need to iterate each time on bases let start = match self.bases.iter().cloned().max() { Some(m) => m, -None => { -// bases is empty (shouldn't happen, but let's be safe) +None => { // self.bases is empty return Ok(()); } }; To: gracinet, #hg-reviewers Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5943: rust: less set lookups in MissingAncestors
gracinet created this revision. Herald added subscribers: mercurial-devel, kevincox, durin42. Herald added a reviewer: hg-reviewers. REVISION SUMMARY using the return values of HashSet::remove(), we can factor pairs of `contains()/remove()` into a single `remove()`. On a perfdiscovery run done on the PyPy repository, prepared with contrib/discovery-helper.sh 50 100, I do get a modest improvement with this (mean of medians of three runs is better by 2%) Sample readings, before this change: ! wall 0.175609 comb 0.18 user 0.18 sys 0.00 (median of 58) With this change: ! wall 0.171662 comb 0.18 user 0.17 sys 0.01 (median of 60) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5943 AFFECTED FILES rust/hg-core/src/ancestors.rs CHANGE DETAILS diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs --- a/rust/hg-core/src/ancestors.rs +++ b/rust/hg-core/src/ancestors.rs @@ -334,12 +334,9 @@ if revs_visit.is_empty() { break; } -if both_visit.contains() { +if both_visit.remove() { // curr's parents might have made it into revs_visit through // another path -// TODO optim: Rust's HashSet.remove returns a boolean telling -// if it happened. This will spare us one set lookup -both_visit.remove(); for p in self.graph.parents(curr)?.iter().cloned() { if p == NULL_REVISION { continue; @@ -354,13 +351,14 @@ if p == NULL_REVISION { continue; } -if bases_visit.contains() || both_visit.contains() { -// p is an ancestor of revs_visit, and is implicitly -// in bases_visit, which means p is ::revs & ::bases. -// TODO optim: hence if bothvisit, we look up twice +if bases_visit.contains() { +// p is already known to be an ancestor of revs_visit +revs_visit.remove(); +both_visit.insert(p); +} else if both_visit.contains() { +// p should have been in bases_visit revs_visit.remove(); bases_visit.insert(p); -both_visit.insert(p); } else { // visit later revs_visit.insert(p); @@ -371,11 +369,9 @@ if p == NULL_REVISION { continue; } -if revs_visit.contains() || both_visit.contains() { +if revs_visit.remove() || both_visit.contains() { // p is an ancestor of bases_visit, and is implicitly // in revs_visit, which means p is ::revs & ::bases. -// TODO optim: hence if bothvisit, we look up twice -revs_visit.remove(); bases_visit.insert(p); both_visit.insert(p); } else { To: gracinet, #hg-reviewers Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D5942: rust: less set lookups in AncestorsIterator
gracinet created this revision. Herald added subscribers: mercurial-devel, kevincox, durin42. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This uses the boolean return of `HashSet::insert()` to factor pairs of contains()/insert() into a single insert() On the mozilla-central repository (450k changesets), I get about a bit more than 10% better medians in perfancestors (taking the mean of three runs) Best run for parent changeset: ! wall 0.106474 comb 0.11 user 0.11 sys 0.00 (median of 93) Best run fot this changeset: ! wall 0.093191 comb 0.09 user 0.09 sys 0.00 (median of 100) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D5942 AFFECTED FILES rust/hg-core/src/ancestors.rs CHANGE DETAILS diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs --- a/rust/hg-core/src/ancestors.rs +++ b/rust/hg-core/src/ancestors.rs @@ -79,8 +79,7 @@ #[inline] fn conditionally_push_rev( self, rev: Revision) { -if self.stoprev <= rev && !self.seen.contains() { -self.seen.insert(rev); +if self.stoprev <= rev && self.seen.insert(rev) { self.visit.push(rev); } } @@ -154,11 +153,10 @@ Ok(ps) => ps, Err(e) => return Some(Err(e)), }; -if p1 < self.stoprev || self.seen.contains() { +if p1 < self.stoprev || !self.seen.insert(p1) { self.visit.pop(); } else { *(self.visit.peek_mut().unwrap()) = p1; -self.seen.insert(p1); }; self.conditionally_push_rev(p2); To: gracinet, #hg-reviewers Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel