D1758: remotenames: add new namespaces for remotebookmarks and remotebranches
pulkit added inline comments. INLINE COMMENTS > martinvonz wrote in remotenames.py:189 > > Does remotebookmark, and remotebranch sounds good? > > Will the log output get aligned for these longer names? > > Should we include a space? "remote bookmark:" looks more user-friendly I made it `remote bookmark` and `remote branch` and the log output does not get aligned. :( REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1758 To: pulkit, #hg-reviewers, durin42 Cc: martinvonz, durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2002: remotenames: add three new revsets related to remotenames
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This patch adds three new revsets 'remotenames', 'remotebookmarks' and 'remotebranches' which will return changesets which have remotenames, remotebookmarks and remotebranches on them respectively. The remotenames revset exist in hgremotenames extension and is moved from there whereas rest of the two revsets are introduced in this patch. hgremotenames: https://bitbucket.org/seanfarley/hgremotenames REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2002 AFFECTED FILES hgext/remotenames.py tests/test-logexchange.t CHANGE DETAILS diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t --- a/tests/test-logexchange.t +++ b/tests/test-logexchange.t @@ -226,3 +226,36 @@ | o 0:18d04c59bb5d [] () +Testing the revsets provided by remotenames extension + +`remotenames` revset + + $ hg log -r "remotenames()" -GT "{rev}:{node|short} {remotenames}\n" + @ 8:3e1487808078 $TESTTMP/server2/wat default/wat + : + : o 7:ec2426147f0e $TESTTMP/server2/default default/default + : | + : o 6:87d6d6676308 $TESTTMP/server2/bar default/bar + :/ + o 3:62615734edd5 $TESTTMP/server2/foo default/foo + | + ~ + +`remotebranches` revset + + $ hg log -r "remotebranches()" -GT "{rev}:{node|short} {remotenames}\n" + @ 8:3e1487808078 $TESTTMP/server2/wat default/wat + | + ~ + o 7:ec2426147f0e $TESTTMP/server2/default default/default + | + ~ + +`remotebookmarks` revset + + $ hg log -r "remotebookmarks()" -GT "{rev}:{node|short} {remotenames}\n" + o 6:87d6d6676308 $TESTTMP/server2/bar default/bar + : + o 3:62615734edd5 $TESTTMP/server2/foo default/foo + | + ~ diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -32,6 +32,8 @@ namespaces, pycompat, registrar, +revset, +smartset, templatekw, ) @@ -44,6 +46,7 @@ configtable = {} configitem = registrar.configitem(configtable) templatekeyword = registrar.templatekeyword() +revsetpredicate = registrar.revsetpredicate() configitem('remotenames', 'bookmarks', default=True, @@ -256,3 +259,52 @@ return templatekw.showlist('remotebranch', remotebranches, args, plural='remotebranches') + +@revsetpredicate('remotenames') +def remotenamesrevset(repo, subset, x): +"""``remotenames()`` +All changesets which have a remotename on them. +""" +revset.getargs(x, 0, 0, "remotenames takes no arguments") +remoterevs = set() +cl = repo.changelog +for rtype in ('remotebookmarks', 'remotebranches'): +if rtype in repo.names: +ns = repo.names[rtype] +for name in ns.listnames(repo): +remoterevs.update(ns.nodes(repo, name)) + +results = (cl.rev(n) for n in remoterevs if n in repo) +return subset & smartset.baseset(sorted(results)) + +@revsetpredicate('remotebranches') +def remotebranchesrevset(repo, subset, x): +"""``remotebranches()`` +All changesets which are branch heads on remotes. +""" +revset.getargs(x, 0, 0, "remotebranches takes no arguments") +remoterevs = set() +cl = repo.changelog +if 'remotebranches' in repo.names: +ns = repo.names['remotebranches'] +for name in ns.listnames(repo): +remoterevs.update(ns.nodes(repo, name)) + +results = (cl.rev(n) for n in remoterevs if n in repo) +return subset & smartset.baseset(sorted(results)) + +@revsetpredicate('remotebookmarks') +def remotebmarksrevset(repo, subset, x): +"""``remotebookmarks()`` +All changesets which have bookmarks on remotes. +""" +revset.getargs(x, 0, 0, "remotebookmarks takes no arguments") +remoterevs = set() +cl = repo.changelog +if 'remotebookmarks' in repo.names: +ns = repo.names['remotebookmarks'] +for name in ns.listnames(repo): +remoterevs.update(ns.nodes(repo, name)) + +results = (cl.rev(n) for n in remoterevs if n in repo) +return subset & smartset.baseset(sorted(results)) 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
D1759: remotenames: introduce new template keywords for remotenames
pulkit updated this revision to Diff 5148. pulkit edited the summary of this revision. pulkit retitled this revision from "remotenames: introduce a template keyword for remotenames" to "remotenames: introduce new template keywords for remotenames". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1759?vs=4613=5148 REVISION DETAIL https://phab.mercurial-scm.org/D1759 AFFECTED FILES hgext/remotenames.py tests/test-logexchange.t CHANGE DETAILS diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t --- a/tests/test-logexchange.t +++ b/tests/test-logexchange.t @@ -182,3 +182,47 @@ date:Thu Jan 01 00:00:00 1970 + summary: Added a +Testing the templates provided by remotenames extension + +`remotenames` keyword + + $ hg log -G -T "{rev}:{node|short} {remotenames}\n" + @ 8:3e1487808078 $TESTTMP/server2/wat default/wat + | + | o 7:ec2426147f0e $TESTTMP/server2/default default/default + | | + | o 6:87d6d6676308 $TESTTMP/server2/bar default/bar + | | + | o 5:825660c69f0c + |/ + o 4:aa98ab95a928 + | + o 3:62615734edd5 $TESTTMP/server2/foo default/foo + | + o 2:28ad74487de9 + | + o 1:29becc82797a + | + o 0:18d04c59bb5d + +`remotebookmarks` and `remotebranches` keywords + + $ hg log -G -T "{rev}:{node|short} [{remotebookmarks}] ({remotebranches})" + @ 8:3e1487808078 [] ($TESTTMP/server2/wat default/wat) + | + | o 7:ec2426147f0e [] ($TESTTMP/server2/default default/default) + | | + | o 6:87d6d6676308 [$TESTTMP/server2/bar default/bar] () + | | + | o 5:825660c69f0c [] () + |/ + o 4:aa98ab95a928 [] () + | + o 3:62615734edd5 [$TESTTMP/server2/foo default/foo] () + | + o 2:28ad74487de9 [] () + | + o 1:29becc82797a [] () + | + o 0:18d04c59bb5d [] () + diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -30,7 +30,9 @@ from mercurial import ( logexchange, namespaces, +pycompat, registrar, +templatekw, ) # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for @@ -41,6 +43,7 @@ configtable = {} configitem = registrar.configitem(configtable) +templatekeyword = registrar.templatekeyword() configitem('remotenames', 'bookmarks', default=True, @@ -205,3 +208,51 @@ nodemap = lambda repo, node: repo._remotenames.nodetobranch().get(node, [])) repo.names.addnamespace(remotebranchns) + +@templatekeyword('remotenames') +def remotenameskw(**args): +""":remotenames: List of strings. List of remote names associated with the +changeset. +""" +args = pycompat.byteskwargs(args) +repo, ctx = args['repo'], args['ctx'] + +remotenames = [] +if 'remotebookmarks' in repo.names: +remotenames = repo.names['remotebookmarks'].names(repo, ctx.node()) + +if 'remotebranches' in repo.names: +remotenames += repo.names['remotebranches'].names(repo, ctx.node()) + +return templatekw.showlist('remotename', remotenames, args, + plural='remotenames') + +@templatekeyword('remotebookmarks') +def remotebookmarkskw(**args): +""":remotebookmarks: List of strings. List of remote bookmarks associated +with the changeset. +""" +args = pycompat.byteskwargs(args) +repo, ctx = args['repo'], args['ctx'] + +remotebmarks = [] +if 'remotebookmarks' in repo.names: +remotebmarks = repo.names['remotebookmarks'].names(repo, ctx.node()) + +return templatekw.showlist('remotebookmark', remotebmarks, args, + plural='remotebookmarks') + +@templatekeyword('remotebranches') +def remotebrancheskw(**args): +""":remotebranches: List of strings. List of remote branches associated +with the changeset. +""" +args = pycompat.byteskwargs(args) +repo, ctx = args['repo'], args['ctx'] + +remotebranches = [] +if 'remotebranches' in repo.names: +remotebranches = repo.names['remotebranches'].names(repo, ctx.node()) + +return templatekw.showlist('remotebranch', remotebranches, args, + plural='remotebranches') 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
D1757: remotenames: introduce a class to lazily resolve remotnames
pulkit updated this revision to Diff 5146. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1757?vs=4611=5146 REVISION DETAIL https://phab.mercurial-scm.org/D1757 AFFECTED FILES hgext/remotenames.py CHANGE DETAILS diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -10,6 +10,11 @@ from __future__ import absolute_import +import UserDict + +from mercurial.node import ( +bin, +) from mercurial import ( logexchange, ) @@ -20,34 +25,102 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' +class lazyremotenamedict(UserDict.DictMixin): +""" +Read-only dict-like Class to lazily resolve remotename entries + +We are doing that because remotenames startup was slow. +We lazily read the remotenames file once to figure out the potential entries +and store them in self.potentialentries. Then when asked to resolve an +entry, if it is not in self.potentialentries, then it isn't there, if it +is in self.potentialentries we resolve it and store the result in +self.cache. We cannot be lazy is when asked all the entries (keys). +""" +def __init__(self, kind, repo): +self.cache = {} +self.potentialentries = {} +self._kind = kind # bookmarks or branches +self._repo = repo +self.loaded = False + +def _load(self): +""" Read the remotenames file, store entries matching selected kind """ +self.loaded = True +repo = self._repo +for node, rpath, rname in logexchange.readremotenamefile(repo, +self._kind): +name = rpath + '/' + rname +self.potentialentries[name] = (node, rpath, name) + +def _resolvedata(self, potentialentry): +""" Check that the node for potentialentry exists and return it """ +if not potentialentry in self.potentialentries: +return None +node, remote, name = self.potentialentries[potentialentry] +repo = self._repo +binnode = bin(node) +# if the node doesn't exist, skip it +try: +repo.changelog.rev(binnode) +except LookupError: +return None +# Skip closed branches +if (self._kind == 'branches' and repo[binnode].closesbranch()): +return None +return [binnode] + +def __getitem__(self, key): +if not self.loaded: +self._load() +val = self._fetchandcache(key) +if val is not None: +return val +else: +raise KeyError() + +def _fetchandcache(self, key): +if key in self.cache: +return self.cache[key] +val = self._resolvedata(key) +if val is not None: +self.cache[key] = val +return val +else: +return None + +def keys(self): +""" Get a list of bookmark or branch names """ +if not self.loaded: +self._load() +return self.potentialentries.keys() + +def iteritems(self): +""" Iterate over (name, node) tuples """ + +if not self.loaded: +self._load() + +for k, vtup in self.potentialentries.iteritems(): +yield (k, [bin(vtup[0])]) + class remotenames(dict): """ This class encapsulates all the remotenames state. It also contains -methods to access that state in convenient ways. +methods to access that state in convenient ways. Remotenames are lazy +loaded. Whenever client code needs to ensure the freshest copy of +remotenames, use the `clearnames` method to force an eventual load. """ def __init__(self, repo, *args): dict.__init__(self, *args) self._repo = repo -self['bookmarks'] = {} -self['branches'] = {} -self.loadnames() -self._loadednames = True - -def loadnames(self): -""" loads the remotenames information from the remotenames file """ -for rtype in ('bookmarks', 'branches'): -for node, rpath, name in logexchange.readremotenamefile(self._repo, -rtype): -rname = rpath + '/' + name -self[rtype][rname] = [node] +self.clearnames() def clearnames(self): """ Clear all remote names state """ -self['bookmarks'] = {} -self['branches'] = {} +self['bookmarks'] = lazyremotenamedict("bookmarks", self._repo) +self['branches'] = lazyremotenamedict("branches", self._repo) self._invalidatecache() -self._loadednames = False def _invalidatecache(self): self._nodetobmarks = None To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list
D1756: remotenames: introduce class to encapsulate remotenames info in an extension
pulkit updated this revision to Diff 5145. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1756?vs=4610=5145 REVISION DETAIL https://phab.mercurial-scm.org/D1756 AFFECTED FILES hgext/remotenames.py tests/test-help.t CHANGE DETAILS diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -274,6 +274,7 @@ purge command to delete untracked files from the working directory relinkrecreates hardlinks between repository clones + remotenames showing remotebookmarks and remotebranches in UI schemes extend schemes with shortcuts to repository swarms share share a common history between several working directories shelvesave and restore changes to the working directory diff --git a/hgext/remotenames.py b/hgext/remotenames.py new file mode 100644 --- /dev/null +++ b/hgext/remotenames.py @@ -0,0 +1,77 @@ +# remotenames.py - extension to display remotenames +# +# Copyright 2017 Augie Fackler+# Copyright 2017 Sean Farley +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +""" showing remotebookmarks and remotebranches in UI """ + +from __future__ import absolute_import + +from mercurial import ( +logexchange, +) + +# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for +# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should +# be specifying the version(s) of Mercurial they are tested with, or +# leave the attribute unspecified. +testedwith = 'ships-with-hg-core' + +class remotenames(dict): +""" +This class encapsulates all the remotenames state. It also contains +methods to access that state in convenient ways. +""" + +def __init__(self, repo, *args): +dict.__init__(self, *args) +self._repo = repo +self['bookmarks'] = {} +self['branches'] = {} +self.loadnames() +self._loadednames = True + +def loadnames(self): +""" loads the remotenames information from the remotenames file """ +for rtype in ('bookmarks', 'branches'): +for node, rpath, name in logexchange.readremotenamefile(self._repo, +rtype): +rname = rpath + '/' + name +self[rtype][rname] = [node] + +def clearnames(self): +""" Clear all remote names state """ +self['bookmarks'] = {} +self['branches'] = {} +self._invalidatecache() +self._loadednames = False + +def _invalidatecache(self): +self._nodetobmarks = None +self._nodetobranch = None + +def bmarktonodes(self): +return self['bookmarks'] + +def nodetobmarks(self): +if not self._nodetobmarks: +bmarktonodes = self.bmarktonodes() +self._nodetobmarks = {} +for name, node in bmarktonodes.iteritems(): +self._nodetobmarks.setdefault(node[0], []).append(name) +return self._nodetobmarks + +def branchtonodes(self): +return self['branches'] + +def nodetobranch(self): +if not self._nodetobranch: +branchtonodes = self.branchtonodes() +self._nodetobranch = {} +for name, nodes in branchtonodes.iteritems(): +for node in nodes: +self._nodetobranch.setdefault(node, []).append(name) +return self._nodetobranch To: pulkit, #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
D1755: logexchange: introduce helper function to get remote path name
pulkit updated this revision to Diff 5144. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1755?vs=4794=5144 REVISION DETAIL https://phab.mercurial-scm.org/D1755 AFFECTED FILES mercurial/logexchange.py tests/test-logexchange.t CHANGE DETAILS diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t --- a/tests/test-logexchange.t +++ b/tests/test-logexchange.t @@ -57,14 +57,14 @@ $ cat .hg/logexchange/bookmarks 0 - 87d6d66763085b629e6d7ed56778c79827273022\x00file:$TESTTMP/server\x00bar (esc) - 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00file:$TESTTMP/server\x00foo (esc) + 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc) + 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc) $ cat .hg/logexchange/branches 0 - ec2426147f0e39dbc9cef599b066be6035ce691d\x00file:$TESTTMP/server\x00default (esc) - 3e1487808078543b0af6d10dadf5d46943578db0\x00file:$TESTTMP/server\x00wat (esc) + ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc) + 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc) Making a new server --- @@ -94,15 +94,15 @@ $ cat .hg/logexchange/bookmarks 0 - 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00file:$TESTTMP/server\x00foo (esc) - 87d6d66763085b629e6d7ed56778c79827273022\x00file:$TESTTMP/server\x00bar (esc) - 87d6d66763085b629e6d7ed56778c79827273022\x00file:$TESTTMP/server2\x00bar (esc) - 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00file:$TESTTMP/server2\x00foo (esc) + 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc) + 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc) + 87d6d66763085b629e6d7ed56778c79827273022\x00$TESTTMP/server2\x00bar (esc) + 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00$TESTTMP/server2\x00foo (esc) $ cat .hg/logexchange/branches 0 - 3e1487808078543b0af6d10dadf5d46943578db0\x00file:$TESTTMP/server\x00wat (esc) - ec2426147f0e39dbc9cef599b066be6035ce691d\x00file:$TESTTMP/server\x00default (esc) - ec2426147f0e39dbc9cef599b066be6035ce691d\x00file:$TESTTMP/server2\x00default (esc) - 3e1487808078543b0af6d10dadf5d46943578db0\x00file:$TESTTMP/server2\x00wat (esc) + 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc) + ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc) + ec2426147f0e39dbc9cef599b066be6035ce691d\x00$TESTTMP/server2\x00default (esc) + 3e1487808078543b0af6d10dadf5d46943578db0\x00$TESTTMP/server2\x00wat (esc) diff --git a/mercurial/logexchange.py b/mercurial/logexchange.py --- a/mercurial/logexchange.py +++ b/mercurial/logexchange.py @@ -11,6 +11,7 @@ from .node import hex from . import ( +util, vfs as vfsmod, ) @@ -94,14 +95,38 @@ finally: wlock.release() +def activepath(repo, remote): +"""returns remote path""" +local = None +# is the remote a local peer +local = remote.local() + +# determine the remote path from the repo, if possible; else just +# use the string given to us +rpath = remote +if local: +rpath = remote._repo.root +elif not isinstance(remote, str): +rpath = remote._url + +# represent the remotepath with user defined path name if exists +for path, url in repo.ui.configitems('paths'): +# remove auth info from user defined url +url = util.removeauth(url) +if url == rpath: +rpath = path +break + +return rpath + def pullremotenames(localrepo, remoterepo): """ pulls bookmarks and branches information of the remote repo during a pull or clone operation. localrepo is our local repository remoterepo is the peer instance """ -remotepath = remoterepo.url() +remotepath = activepath(localrepo, remoterepo) bookmarks = remoterepo.listkeys('bookmarks') # on a push, we don't want to keep obsolete heads since # they won't show up as heads on the next pull, so we To: pulkit, #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
D1758: remotenames: add new namespaces for remotebookmarks and remotebranches
pulkit updated this revision to Diff 5147. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1758?vs=4612=5147 REVISION DETAIL https://phab.mercurial-scm.org/D1758 AFFECTED FILES hgext/remotenames.py tests/test-logexchange.t CHANGE DETAILS diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t --- a/tests/test-logexchange.t +++ b/tests/test-logexchange.t @@ -6,6 +6,9 @@ > glog = log -G -T '{rev}:{node|short} {desc}' > [experimental] > remotenames = True + > [extensions] + > remotenames = + > show = > EOF Making a server repo @@ -66,6 +69,19 @@ ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc) 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc) + $ hg show work + o 3e14 (wat) (default/wat) added bar + | + ~ + @ ec24 (default/default) Added h + | + ~ + + $ hg update "default/wat" + 1 files updated, 0 files merged, 3 files removed, 0 files unresolved + $ hg identify + 3e1487808078 (wat) tip + Making a new server --- @@ -106,3 +122,63 @@ ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc) ec2426147f0e39dbc9cef599b066be6035ce691d\x00$TESTTMP/server2\x00default (esc) 3e1487808078543b0af6d10dadf5d46943578db0\x00$TESTTMP/server2\x00wat (esc) + + $ hg log -G + @ changeset: 8:3e1487808078 + | branch: wat + | tag: tip + | remote branch:$TESTTMP/server2/wat + | remote branch:default/wat + | parent: 4:aa98ab95a928 + | user:test + | date:Thu Jan 01 00:00:00 1970 + + | summary: added bar + | + | o changeset: 7:ec2426147f0e + | | remote branch:$TESTTMP/server2/default + | | remote branch:default/default + | | user:test + | | date:Thu Jan 01 00:00:00 1970 + + | | summary: Added h + | | + | o changeset: 6:87d6d6676308 + | | bookmark:bar + | | remote bookmark:$TESTTMP/server2/bar + | | remote bookmark:default/bar + | | user:test + | | date:Thu Jan 01 00:00:00 1970 + + | | summary: Added g + | | + | o changeset: 5:825660c69f0c + |/ user:test + |date:Thu Jan 01 00:00:00 1970 + + |summary: Added f + | + o changeset: 4:aa98ab95a928 + | user:test + | date:Thu Jan 01 00:00:00 1970 + + | summary: Added e + | + o changeset: 3:62615734edd5 + | bookmark:foo + | remote bookmark:$TESTTMP/server2/foo + | remote bookmark:default/foo + | user:test + | date:Thu Jan 01 00:00:00 1970 + + | summary: Added d + | + o changeset: 2:28ad74487de9 + | user:test + | date:Thu Jan 01 00:00:00 1970 + + | summary: Added c + | + o changeset: 1:29becc82797a + | user:test + | date:Thu Jan 01 00:00:00 1970 + + | summary: Added b + | + o changeset: 0:18d04c59bb5d + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: Added a + diff --git a/hgext/remotenames.py b/hgext/remotenames.py --- a/hgext/remotenames.py +++ b/hgext/remotenames.py @@ -6,7 +6,19 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -""" showing remotebookmarks and remotebranches in UI """ +""" showing remotebookmarks and remotebranches in UI + +By default both remotebookmarks and remotebranches are turned on. Config knob to +control the individually are as follows. + +Config options to tweak the default behaviour: + +remotenames.bookmarks + Boolean value to enable or disable showing of remotebookmarks + +remotenames.branches + Boolean value to enable or disable showing of remotebranches +""" from __future__ import absolute_import @@ -17,14 +29,26 @@ ) from mercurial import ( logexchange, +namespaces, +registrar, ) # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should # be specifying the version(s) of Mercurial they are tested with, or # leave the attribute unspecified. testedwith = 'ships-with-hg-core' +configtable = {} +configitem = registrar.configitem(configtable) + +configitem('remotenames', 'bookmarks', +default=True, +) +configitem('remotenames', 'branches', +default=True, +) + class lazyremotenamedict(UserDict.DictMixin): """ Read-only dict-like Class to lazily resolve remotename entries @@ -148,3 +172,36 @@ for node in nodes: self._nodetobranch.setdefault(node, []).append(name) return self._nodetobranch + +def reposetup(ui, repo): +if not repo.local(): +return + +repo._remotenames = remotenames(repo) +ns = namespaces.namespace + +if ui.configbool('remotenames', 'bookmarks'): +remotebookmarkns = ns( +
D2001: httppeer: remove support for connecting to <0.9.1 servers (BC)
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previously, HTTP wire protocol clients would attempt a "capabilities" wire protocol command. If that failed, they would fall back to issuing a "between" command. The "capabilities" command was added in Mercurial 0.9.1 (released July 2006). The "between" command has been present for as long as the wire protocol has existed. So if the "between" command failed, it was safe to assume that the remote could not speak any version of the Mercurial wire protocol. The "between" fallback was added in https://phab.mercurial-scm.org/rHG395a84f78736aa1912d16ae2138e7d5596bdaa42 in 2011. Before that changeset, Mercurial would *always* issue the "between" command and would issue "capabilities" if capabilities were requested. At that time, many connections would issue "capabilities" eventually, so it was decided to issue "capabilities" by default and fall back to "between" if that failed. This saved a round trip when connecting to modern servers while still preserving compatibility with legacy servers. Fast forward ~7 years. Mercurial servers supporting "capabilities" have been around for over a decade. If modern clients are connecting to <0.9.1 servers, they are getting a bad experience. They may even be getting bad data (an old server is vulnerable to numerous security issues and could have been p0wned, leading to a Mercurial repository serving backdoors or other badness). In addition, the fallback can harm experience for modern servers. If a client experiences an intermittent HTTP request failure (due to bad network, etc) and falls back to a "between" that works, it would assume an empty capability set and would attempt to communicate with the repository using a very ancient wire protocol. Auditing HTTP logs for hg.mozilla.org, I did find a handful of requests for the null range of the "between" command. However, requests can be days apart. And when I do see requests, they come in batches. Those batches seem to correlate to spikes of HTTP 500 or other server/network events. So I think these requests are fallbacks from failed "capabilities" requests and not from old clients. If you need even more evidence to discontinue support, apparently we have no test coverage for communicating with servers not supporting "capabilities." I know this because all tests pass with the "between" fallback removed. Finally, server-side support for <0.9.1 pushing (the "addchangegroup" wire protocol command along with locking-related commands) was dropped from the HTTP client in https://phab.mercurial-scm.org/rHGfda0867cfe03ebf457c12b7e0ff1b174aeb67759 in 2017 and the SSH client in https://phab.mercurial-scm.org/rHG9f6e0e7ef82884e3ec66455dac7312820c2b35ce in 2015. I think this all adds up to enough justification for removing client support for communicating with servers not supporting "capabilities." So this commit removes that fallback. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2001 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 @@ -491,13 +491,9 @@ inst = httpspeer(ui, path) else: inst = httppeer(ui, path) -try: -# Try to do useful work when checking compatibility. -# Usually saves a roundtrip since we want the caps anyway. -inst._fetchcaps() -except error.RepoError: -# No luck, try older compatibility check. -inst.between([(nullid, nullid)]) + +inst._fetchcaps() + return inst except error.RepoError as httpexception: try: 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
D2000: internals: document when "hello" and "capabilities" commands were added
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Both were introduced in 0.9.1. "hello" made its entrance in https://phab.mercurial-scm.org/rHGb17eebc911ae808e10487a567d94e1f05d70adf1, https://phab.mercurial-scm.org/rHG144280f1578f11844de8eebd6e9f0464805dbec3, and https://phab.mercurial-scm.org/rHGa1cfe679192c7533765c470ce31e9fe1a0ef8091 to support SSH. "capabilities" was added in https://phab.mercurial-scm.org/rHGc660691fb45d2cc1a411556e877e796c5a80b84c to support HTTP. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2000 AFFECTED FILES mercurial/help/internals/wireprotocol.txt CHANGE DETAILS diff --git a/mercurial/help/internals/wireprotocol.txt b/mercurial/help/internals/wireprotocol.txt --- a/mercurial/help/internals/wireprotocol.txt +++ b/mercurial/help/internals/wireprotocol.txt @@ -662,6 +662,8 @@ This command does not accept any arguments. Return type is a ``string``. +This command was introduced in Mercurial 0.9.1 (released July 2006). + changegroup --- @@ -779,6 +781,8 @@ This command does not accept any arguments. The return type is a ``string``. +This command was introduced in Mercurial 0.9.1 (released July 2006). + listkeys 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
D1919: phabricator: specify API tokens per host, rather than per repo
quark added a comment. > Another thing to consider is reading things from .arcconfig files and reading the API token however Arcanist does it (as the comment in this file suggests). That was my original plan - in `readurltoken`, fallback to `~/.arcrc` and `.arcconfig` if hgrc does not have enough information. I didn't implement it though. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1919 To: tom.prince, #hg-reviewers, durin42 Cc: quark, indygreg, durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2 RESEND] lfs: emit a status message to indicate how many blobs were uploaded
# HG changeset patch # User Matt Harbison# Date 1517281788 18000 # Mon Jan 29 22:09:48 2018 -0500 # Node ID dac55f22cd775a8d3a213e9b6716f03e49e1e765 # Parent 0088fad7fa84a6ec668682e137273e252bc7441c lfs: emit a status message to indicate how many blobs were uploaded Previously, there was a progress bar indicating the byte count, but then it disappeared once the transfer was done. Having that value stay on the screen seems useful. Downloads are done one at a time, so hold off on that until they can be coalesced, to avoid a series of lines being printed. (I don't have any great ideas on how to do that. It would be a shame to have to wrap a bunch of read commands to be able to do this.) I'm not sure if the 'lfs:' prefix is the right thing to do here. The others in the test are verbose/debug messages, so in the normal case, this is the only line that's prefixed. diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -366,12 +366,23 @@ oids = transfer(sorted(objects, key=lambda o: o.get('oid'))) processed = 0 +blobs = 0 for _one, oid in oids: processed += sizes[oid] +blobs += 1 self.ui.progress(topic, processed, total=total) self.ui.note(_('lfs: processed: %s\n') % oid) self.ui.progress(topic, pos=None, total=total) +if blobs > 0: +if action == 'upload': +self.ui.status(_('lfs: uploaded %d files (%s)\n') + % (blobs, util.bytecount(processed))) +# TODO: coalesce the download requests, and comment this in +#elif action == 'download': +#self.ui.status(_('lfs: downloaded %d files (%s)\n') +# % (blobs, util.bytecount(processed))) + def __del__(self): # copied from mercurial/httppeer.py urlopener = getattr(self, 'urlopener', None) diff --git a/tests/test-lfs-test-server.t b/tests/test-lfs-test-server.t --- a/tests/test-lfs-test-server.t +++ b/tests/test-lfs-test-server.t @@ -48,6 +48,7 @@ searching for changes lfs: uploading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes) lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b + lfs: uploaded 1 files (12 bytes) 1 changesets found uncompressed size of bundle content: * (changelog) (glob) @@ -86,6 +87,7 @@ lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 lfs: uploading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes) lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 + lfs: uploaded 2 files (39 bytes) 1 changesets found uncompressed size of bundle content: adding changesets ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2 RESEND] lfs: drop an unused function parameter
# HG changeset patch # User Matt Harbison# Date 1517362401 18000 # Tue Jan 30 20:33:21 2018 -0500 # Node ID 0088fad7fa84a6ec668682e137273e252bc7441c # Parent f1a0933ce59e809f190602655e22ae6ec107c397 lfs: drop an unused function parameter diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py --- a/hgext/lfs/__init__.py +++ b/hgext/lfs/__init__.py @@ -211,7 +211,7 @@ class lfsrepo(repo.__class__): @localrepo.unfilteredmethod def commitctx(self, ctx, error=False): -repo.svfs.options['lfstrack'] = _trackedmatcher(self, ctx) +repo.svfs.options['lfstrack'] = _trackedmatcher(self) return super(lfsrepo, self).commitctx(ctx, error) repo.__class__ = lfsrepo @@ -238,7 +238,7 @@ else: repo.prepushoutgoinghooks.add('lfs', wrapper.prepush) -def _trackedmatcher(repo, ctx): +def _trackedmatcher(repo): """Return a function (path, size) -> bool indicating whether or not to track a given file with lfs.""" if not repo.wvfs.exists('.hglfs'): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1994: config: replace a for-else by any()
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf1a0933ce59e: config: replace a for-else by any() (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1994?vs=5118=5141 REVISION DETAIL https://phab.mercurial-scm.org/D1994 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 @@ -1657,10 +1657,7 @@ else: paths = rcutil.userrcpath() -for f in paths: -if os.path.exists(f): -break -else: +if not any(os.path.exists(f) for f in paths): if opts.get('global'): samplehgrc = uimod.samplehgrcs['global'] elif opts.get('local'): To: martinvonz, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1993: discovery: don't reimplement all()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5523aabb85c3: discovery: dont reimplement all() (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1993?vs=5117=5140 REVISION DETAIL https://phab.mercurial-scm.org/D1993 AFFECTED FILES mercurial/discovery.py CHANGE DETAILS diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -53,13 +53,8 @@ return treediscovery.findcommonincoming(repo, remote, heads, force) if heads: -allknown = True knownnode = repo.changelog.hasnode # no nodemap until it is filtered -for h in heads: -if not knownnode(h): -allknown = False -break -if allknown: +if all(knownnode(h) for h in heads): return (heads, False, heads) res = setdiscovery.findcommonheads(repo.ui, repo, remote, heads, To: martinvonz, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1970: contrib: fix dirstatenonnormalcheck to work in Python 3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG786a70abb4d7: contrib: fix dirstatenonnormalcheck to work in Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1970?vs=5115=5139 REVISION DETAIL https://phab.mercurial-scm.org/D1970 AFFECTED FILES contrib/dirstatenonnormalcheck.py mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1237,9 +1237,12 @@ util.clearcachedproperty(self, "nonnormalset") util.clearcachedproperty(self, "otherparentset") -def iteritems(self): +def items(self): return self._map.iteritems() +# forward for python2,3 compat +iteritems = items + def __len__(self): return len(self._map) diff --git a/contrib/dirstatenonnormalcheck.py b/contrib/dirstatenonnormalcheck.py --- a/contrib/dirstatenonnormalcheck.py +++ b/contrib/dirstatenonnormalcheck.py @@ -17,32 +17,33 @@ """Compute nonnormal entries from dirstate's dmap""" res = set() for f, e in dmap.iteritems(): -if e[0] != 'n' or e[3] == -1: +if e[0] != b'n' or e[3] == -1: res.add(f) return res def checkconsistency(ui, orig, dmap, _nonnormalset, label): """Compute nonnormalset from dmap, check that it matches _nonnormalset""" nonnormalcomputedmap = nonnormalentries(dmap) if _nonnormalset != nonnormalcomputedmap: -ui.develwarn("%s call to %s\n" % (label, orig), config='dirstate') -ui.develwarn("inconsistency in nonnormalset\n", config='dirstate') -ui.develwarn("[nonnormalset] %s\n" % _nonnormalset, config='dirstate') -ui.develwarn("[map] %s\n" % nonnormalcomputedmap, config='dirstate') +ui.develwarn(b"%s call to %s\n" % (label, orig), config=b'dirstate') +ui.develwarn(b"inconsistency in nonnormalset\n", config=b'dirstate') +ui.develwarn(b"[nonnormalset] %s\n" % _nonnormalset, config=b'dirstate') +ui.develwarn(b"[map] %s\n" % nonnormalcomputedmap, config=b'dirstate') def _checkdirstate(orig, self, arg): """Check nonnormal set consistency before and after the call to orig""" checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, - "before") + b"before") r = orig(self, arg) -checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, "after") +checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, + b"after") return r def extsetup(ui): """Wrap functions modifying dirstate to check nonnormalset consistency""" dirstatecl = dirstate.dirstate -devel = ui.configbool('devel', 'all-warnings') -paranoid = ui.configbool('experimental', 'nonnormalparanoidcheck') +devel = ui.configbool(b'devel', b'all-warnings') +paranoid = ui.configbool(b'experimental', b'nonnormalparanoidcheck') if devel: extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate) if paranoid: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1919: phabricator: specify API tokens per host, rather than per repo
indygreg added a comment. In https://phab.mercurial-scm.org/D1919#33519, @durin42 wrote: > In https://phab.mercurial-scm.org/D1919#33517, @indygreg wrote: > > > FWIW Mozilla will likely start leaning on this extension pretty soon. Look for a push from us to move it to core before the next release. > > > I've had a...slightly bonkers idea around using docker to stand up a test phabricator server in a .t-test so we can test this extension. I think it might work. > > Most of the reason we dumped this in contrib and not hgext was that it's untested. We could also use Betamax for HTTP record and replay. Then we could create a Python script to run Docker to perform the recording of the HTTP requests we care about. That would remove Docker from test run-time requirements. Having used Docker for testing against actual services, I've learned the hard way that Docker doesn't scale well. Once you start running tests concurrently, Docker container start and stop overhead quick makes test run times unbearable. And there's intermittent failures in Docker :( REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1919 To: tom.prince, #hg-reviewers, durin42 Cc: indygreg, durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1919: phabricator: specify API tokens per host, rather than per repo
durin42 added a comment. In https://phab.mercurial-scm.org/D1919#33517, @indygreg wrote: > FWIW Mozilla will likely start leaning on this extension pretty soon. Look for a push from us to move it to core before the next release. I've had a...slightly bonkers idea around using docker to stand up a test phabricator server in a .t-test so we can test this extension. I think it might work. Most of the reason we dumped this in contrib and not hgext was that it's untested. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1919 To: tom.prince, #hg-reviewers, durin42 Cc: indygreg, durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1974: narrow: import experimental extension from narrowhg revision cb51d673e9c5
indygreg added a comment. In https://phab.mercurial-scm.org/D1974#33514, @durin42 wrote: > Should I add follow-up commits for the feedback? I think I'd slightly prefer doing that so that we import something that's as minimally modified as possible, and then fix it up all at once, but if you'd rather fix things here that's fine too. I think we should keep the import as similar to upstream as possible. That creates a cleaner transition of the code. So please make fixes in follow-up commits. We may want to check in a `todo.rst` file or similar in this initial commit to facilitate tracking known problems from the inception of the code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1974 To: durin42, #hg-reviewers Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1919: phabricator: specify API tokens per host, rather than per repo
indygreg added a comment. In https://phab.mercurial-scm.org/D1919#33462, @durin42 wrote: > I like this, and I'm fine with the backwards incompatible change in contrib. How do others feel? I'm fine with BC in contrib. One thing to bikeshed is if the `[phabricator]` section is the best place for credentials. We already have `[auth]` for storing credentials. But as long as we don't care about breaking BC, this patch is fine for now. Another thing to consider is reading things from `.arcconfig` files and reading the API token however Arcanist does it (as the comment in this file suggests). FWIW Mozilla will likely start leaning on this extension pretty soon. Look for a push from us to move it to core before the next release. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1919 To: tom.prince, #hg-reviewers, durin42 Cc: indygreg, durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1974: narrow: import experimental extension from narrowhg revision cb51d673e9c5
durin42 added a comment. Should I add follow-up commits for the feedback? I think I'd slightly prefer doing that so that we import something that's as minimally modified as possible, and then fix it up all at once, but if you'd rather fix things here that's fine too. (I agree with the things you caught, I just don't have time for them tonight - maybe tomorrow.) INLINE COMMENTS > indygreg wrote in __init__.py:11-14 > This seems inappropriate. Yeah, I noticed this after doing the first big extraction. It's done in https://phab.mercurial-scm.org/D1980, but we can probably trivially fold that here. Do you have a preference? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1974 To: durin42, #hg-reviewers Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1997: wireproto: improve docstring for @wireprotocommand
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I'm about to add more arguments and want them to be documented. Plus, good documentation is nice to have. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1997 AFFECTED FILES mercurial/wireproto.py CHANGE DETAILS diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -638,7 +638,13 @@ commands = {} def wireprotocommand(name, args=''): -"""decorator for wire protocol command""" +"""Decorator to declare a wire protocol command. + +``name`` is the name of the wire protocol command being provided. + +``args`` is a space-delimited list of named arguments that the command +accepts. ``*`` is a special value that says to accept all arguments. +""" def register(func): commands[name] = (func, args) return func 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
D1996: wireproto: remove unnecessary exception trapping
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The `try..except error.Abort` was added in https://phab.mercurial-scm.org/rHG8474be4412ca5eb4e67047a97acb7cb7f3120ff0 back in 2012. The intent was to ensure a failing pushkey hook didn't crash the server. Since that changeset, repo.pushkey() and the hooks mechanism is now much more robust about trapping errors itself. As such, we no longer need this try..except block. So it has been removed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1996 AFFECTED FILES mercurial/wireproto.py CHANGE DETAILS diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -914,11 +914,8 @@ proto.redirect() -try: -r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key), - encoding.tolocal(old), new) or False -except error.Abort: -r = False +r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key), + encoding.tolocal(old), new) or False output = proto.restore() 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
D1998: wireproto: define and use types for wire protocol commands
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Wire protocol commands have historically been declared as 2-tuples in wireproto.commands. There are some additional features I'd like to implement that require going beyond 2-tuples. But because the 2-tuple API (both destructuring assignment and direct assignment into the dict) is used throughout the code base and in 3rd party extensions, we can't do a trivial type change. This commit creates a new "commandentry" type to represent declared wire protocol commands. It implements __getitem__ and __iter__ so it can quack like a 2-tuple. The @wireprotocommand decorator now creates "commandentry" instances. We also create a "commanddict" type to represent the dictionary of declared wire protocol commands. It inherits from "dict" but provides a custom __setitem__ to coerce passed 2-tuples to "commandentry" instances. wireproto.commands is now an instance of this type. Various callers in core rely on the new functionality. And tests pass. So I'm reasonably confident things will "just work" in 3rd party extensions as well. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1998 AFFECTED FILES mercurial/wireproto.py CHANGE DETAILS diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -634,8 +634,64 @@ return compengines -# list of commands -commands = {} +class commandentry(object): +"""Represents a declared wire protocol command.""" +def __init__(self, func, args=''): +self.func = func +self.args = args + +def _merge(self, func, args): +"""Merge this instance with an incoming 2-tuple. + +This is called when a caller using the old 2-tuple API attempts +to replace an instance. The incoming values are merged with +data not captured by the 2-tuple and a new instance containing +the union of the two objects is returned. +""" +return commandentry(func, args) + +# Old code treats instances as 2-tuples. So expose that interface. +def __iter__(self): +yield self.func +yield self.args + +def __getitem__(self, i): +if i == 0: +return self.func +elif i == 1: +return self.args +else: +raise IndexError('can only access elements 0 and 1') + +class commanddict(dict): +"""Container for registered wire protocol commands. + +It behaves like a dict. But __setitem__ is overwritten to allow silent +coercion of values from 2-tuples for API compatibility. +""" +def __setitem__(self, k, v): +if isinstance(v, commandentry): +pass +# Cast 2-tuples to commandentry instances. +elif isinstance(v, tuple): +if len(v) != 2: +raise ValueError('command tuples must have exactly 2 elements') + +# It is common for extensions to wrap wire protocol commands via +# e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers +# doing this aren't aware of the new API that uses objects to store +# command entries, we automatically merge old state with new. +if k in self: +v = self[k]._merge(v[0], v[1]) +else: +v = commandentry(v[0], v[1]) +else: +raise ValueError('command entries must be commandentry instances ' + 'or 2-tuples') + +return super(commanddict, self).__setitem__(k, v) + +commands = commanddict() def wireprotocommand(name, args=''): """Decorator to declare a wire protocol command. @@ -646,7 +702,7 @@ accepts. ``*`` is a special value that says to accept all arguments. """ def register(func): -commands[name] = (func, args) +commands[name] = commandentry(func, args) return func return register 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
D1999: wireproto: function for testing if wire protocol command is available
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Currently, we perform simple membership testing for whether a wire command is available. In the future, not all wire protocol commands will be available on all transports. For example, a legacy transport may not support newer commands. In preparation of this, teach the protocol handlers to call into a function to determine if a wire protocol command is available. That function currently does membership testing like before, so behavior should be identical. In the case of the HTTP server, behavior is a bit wonkier. "cmd" is used by both the wire protocol and hgweb. We do want the protocol handler to handle requests for all commands that look like wire protocol commands, even if they aren't available. Otherwise, the fallback to hgweb would only confuse automated clients and make it easier for hgweb to accidentally implement a "cmd" that is identical to wire protocol commands (since they aren't centrally registered). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1999 AFFECTED FILES mercurial/hgweb/hgweb_mod.py mercurial/wireproto.py mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -220,6 +220,13 @@ yield chunk rsp = wireproto.dispatch(repo, proto, cmd) + +if not wireproto.commands.commandavailable(cmd, proto): +req.respond(HTTP_OK, HGERRTYPE, +body=_('requested wire protocol command is not available ' + 'over HTTP')) +return [] + if isinstance(rsp, bytes): req.respond(HTTP_OK, HGTYPE, body=rsp) return [] @@ -348,7 +355,7 @@ def serve_one(self): cmd = self._fin.readline()[:-1] -if cmd and cmd in wireproto.commands: +if cmd and wireproto.commands.commandavailable(cmd, self): rsp = wireproto.dispatch(self._repo, self, cmd) self._handlers[rsp.__class__](self, rsp) elif cmd: diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -691,6 +691,12 @@ return super(commanddict, self).__setitem__(k, v) +def commandavailable(self, command, proto): +"""Determine if a command is available for the requested protocol.""" +# For now, commands are available for all protocols. So do a simple +# membership test. +return command in self + commands = commanddict() def wireprotocommand(name, args=''): diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -357,6 +357,14 @@ query = req.env[r'QUERY_STRING'].partition(r'&')[0] query = query.partition(r';')[0] +# The ``cmd`` request parameter is used by both the wire protocol +# and hgweb. We route all known wire protocol commands to the +# wire protocol handler, even if the command isn't available for +# this transport. That's better for machine clients in the case +# of an errant request to an unavailable protocol command. And it +# prevents hgweb from accidentally using ``cmd`` values used by +# the wire protocol. + # process this if it's a protocol request # protocol bits don't need to create any URLs # and the clients always use the old URL structure 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
D1995: sshpeer: document the handshake mechanism
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The mechanism by which SSH peers establish connections with remotes is wonky and requires a bit of code archeology to understand. While it is already documented in `hg help internals.wireproto`, it helps to have documentation in the code as well. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1995 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 @@ -210,8 +210,24 @@ hint = self.ui.config("ui", "ssherrorhint") self._abort(error.RepoError(msg, hint=hint)) +# The purpose of the ``between`` command with a null range is to +# reliably get a specific response (``1\n\n`` - a 1 byte reply +# with value ``\n``) from *all* servers, possibly after "noise" +# emitted by the server (e.g. message of the day banners). The +# ``between`` command has existed for as long as the SSH peer has +# existed, which is how we know that we can rely on that command +# working. If we send the ``between`` command, we should see +# ``1\n\n`` in the response. If not, the remote isn't a valid +# Mercurial server. +# +# The ``hello`` command was added in Mercurial 0.9.1 as a mechanism for +# servers to advertise their capabilities. The client sends both +# ``hello`` and ``between`` to tease out old servers. If the server +# doesn't support ``hello``, it will send an empty reply (``0\n``) to +# that command. However, there will always be a reply to the ``between`` +# command allowing us to differentiate between "noise" and command +# response. try: -# skip any noise generated by remote shell self._callstream("hello") r = self._callstream("between", pairs=("%s-%s" % ("0"*40, "0"*40))) except IOError: @@ -234,6 +250,9 @@ else: badresponse() +# Search for the ``hello`` response in reverse wire order. If there +# was e.g. an SSH banner that happened to emit ``capabilities:``, that +# should be before Mercurial's output. self._caps = set() for l in reversed(lines): if l.startswith("capabilities:"): 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
D1919: phabricator: specify API tokens per host, rather than per repo
durin42 accepted this revision as: durin42. durin42 added a comment. I like this, and I'm fine with the backwards incompatible change in contrib. How do others feel? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1919 To: tom.prince, #hg-reviewers, durin42 Cc: durin42, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1911: python3: whitelist another 24 passing tests
This revision was automatically updated to reflect the committed changes. Closed by commit rHGcd1928ca94e4: python3: whitelist another 24 passing tests (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1911?vs=4916=5133 REVISION DETAIL https://phab.mercurial-scm.org/D1911 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 @@ -43,13 +43,36 @@ test-dirstate-nonnormalset.t test-doctest.py test-double-merge.t +test-drawdag.t test-duplicateoptions.py test-empty-dir.t test-empty-file.t test-empty-group.t test-empty.t test-encoding-func.py test-excessive-merge.t +test-exchange-obsmarkers-case-A1.t +test-exchange-obsmarkers-case-A2.t +test-exchange-obsmarkers-case-A3.t +test-exchange-obsmarkers-case-A4.t +test-exchange-obsmarkers-case-A5.t +test-exchange-obsmarkers-case-A6.t +test-exchange-obsmarkers-case-A7.t +test-exchange-obsmarkers-case-B1.t +test-exchange-obsmarkers-case-B2.t +test-exchange-obsmarkers-case-B3.t +test-exchange-obsmarkers-case-B4.t +test-exchange-obsmarkers-case-B5.t +test-exchange-obsmarkers-case-B6.t +test-exchange-obsmarkers-case-B7.t +test-exchange-obsmarkers-case-C1.t +test-exchange-obsmarkers-case-C2.t +test-exchange-obsmarkers-case-C3.t +test-exchange-obsmarkers-case-C4.t +test-exchange-obsmarkers-case-D1.t +test-exchange-obsmarkers-case-D2.t +test-exchange-obsmarkers-case-D3.t +test-exchange-obsmarkers-case-D4.t test-execute-bit.t test-filebranch.t test-flags.t @@ -97,6 +120,7 @@ test-merge8.t test-mq-qimport-fail-cleanup.t test-obshistory.t +test-obsolete-changeset-exchange.t test-obsolete-checkheads.t test-parents.t test-permissions.t @@ -151,6 +175,7 @@ test-sparse-verbose-json.t test-status-terse.t test-strip-cross.t +test-strip.t test-uncommit.t test-unified-test.t test-unrelated-pull.t To: durin42, pulkit, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1909: cmdutil: add a kludge to make bytes repr() the same on 2 and 3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG00466a8b4d13: cmdutil: add a kludge to make bytes repr() the same on 2 and 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1909?vs=4954=5130 REVISION DETAIL https://phab.mercurial-scm.org/D1909 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 @@ -2077,6 +2077,19 @@ return changeset_templater(ui, repo, spec, match, opts, buffered) +class _regrettablereprbytes(bytes): +"""Bytes subclass that makes the repr the same on Python 3 as Python 2. + +This is a huge hack. +""" +def __repr__(self): +return repr(pycompat.sysstr(self)) + +def _maybebytestr(v): +if pycompat.ispy3 and isinstance(v, bytes): +return _regrettablereprbytes(v) +return v + def showmarker(fm, marker, index=None): """utility function to display obsolescence marker in a readable way @@ -2095,7 +2108,8 @@ fm.write('date', '(%s) ', fm.formatdate(marker.date())) meta = marker.metadata().copy() meta.pop('date', None) -fm.write('metadata', '{%s}', fm.formatdict(meta, fmt='%r: %r', sep=', ')) +smeta = {_maybebytestr(k): _maybebytestr(v) for k, v in meta.iteritems()} +fm.write('metadata', '{%s}', fm.formatdict(smeta, fmt='%r: %r', sep=', ')) fm.plain('\n') def finddate(ui, repo, date): 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
D1992: mdiff: use slice instead of index on bytestr when checking single bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2713f62fd898: mdiff: use slice instead of index on bytestr when checking single bytes (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1992?vs=5116=5132 REVISION DETAIL https://phab.mercurial-scm.org/D1992 AFFECTED FILES mercurial/mdiff.py CHANGE DETAILS diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -275,7 +275,7 @@ headerlines = [] hunks = (None, ['Binary file %s has changed\n' % fn1]), elif not a: -without_newline = b[-1] != '\n' +without_newline = b[-1:] != '\n' b = splitnewlines(b) if a is None: l1 = '--- /dev/null%s' % datetag(epoch) @@ -291,7 +291,7 @@ hunklines.append(_missing_newline_marker) hunks = (hunkrange, hunklines), elif not b: -without_newline = a[-1] != '\n' +without_newline = a[-1:] != '\n' a = splitnewlines(a) l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) if b is None: @@ -384,17 +384,17 @@ # a newline, print only one marker. That's the only case in # which the hunk can end in a shared line without a newline. skip = False -if t1[-1] != '\n' and astart + alen == len(l1) + 1: +if t1[-1:] != '\n' and astart + alen == len(l1) + 1: for i in xrange(len(hunklines) - 1, -1, -1): -if hunklines[i][0] in ('-', ' '): -if hunklines[i][0] == ' ': +if hunklines[i][0:1] in ('-', ' '): +if hunklines[i][0:1] == ' ': skip = True hunklines[i] += '\n' hunklines.insert(i + 1, _missing_newline_marker) break -if not skip and t2[-1] != '\n' and bstart + blen == len(l2) + 1: +if not skip and t2[-1:] != '\n' and bstart + blen == len(l2) + 1: for i in xrange(len(hunklines) - 1, -1, -1): -if hunklines[i][0] == '+': +if hunklines[i][0:1] == '+': hunklines[i] += '\n' hunklines.insert(i + 1, _missing_newline_marker) break To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1910: obsutil: work around filter() being a generator in Python 3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG4705dc1500e0: obsutil: work around filter() being a generator in Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1910?vs=4915=5131 REVISION DETAIL https://phab.mercurial-scm.org/D1910 AFFECTED FILES mercurial/obsutil.py CHANGE DETAILS diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py --- a/mercurial/obsutil.py +++ b/mercurial/obsutil.py @@ -421,10 +421,10 @@ # Check if other meta has changed changeextra = changectx.extra().items() -ctxmeta = filter(metanotblacklisted, changeextra) +ctxmeta = list(filter(metanotblacklisted, changeextra)) sourceextra = source.extra().items() -srcmeta = filter(metanotblacklisted, sourceextra) +srcmeta = list(filter(metanotblacklisted, sourceextra)) if ctxmeta != srcmeta: effects |= METACHANGED To: durin42, #hg-reviewers, pulkit, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1984: wireprotoserver: make attributes private
This revision was automatically updated to reflect the committed changes. Closed by commit rHGae7c16df7967: wireprotoserver: make attributes private (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1984?vs=5107=5122 REVISION DETAIL https://phab.mercurial-scm.org/D1984 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -90,8 +90,8 @@ class webproto(abstractserverproto): def __init__(self, req, ui): -self.req = req -self.ui = ui +self._req = req +self._ui = ui self.name = 'http' def getargs(self, args): @@ -110,51 +110,51 @@ return [data[k] for k in keys] def _args(self): -args = self.req.form.copy() +args = self._req.form.copy() if pycompat.ispy3: args = {k.encode('ascii'): [v.encode('ascii') for v in vs] for k, vs in args.items()} -postlen = int(self.req.env.get(r'HTTP_X_HGARGS_POST', 0)) +postlen = int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) if postlen: args.update(cgi.parse_qs( -self.req.read(postlen), keep_blank_values=True)) +self._req.read(postlen), keep_blank_values=True)) return args -argvalue = decodevaluefromheaders(self.req, r'X-HgArg') +argvalue = decodevaluefromheaders(self._req, r'X-HgArg') args.update(cgi.parse_qs(argvalue, keep_blank_values=True)) return args def getfile(self, fp): -length = int(self.req.env[r'CONTENT_LENGTH']) +length = int(self._req.env[r'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(r'HTTP_X_HGARGS_POST', 0)) -for s in util.filechunkiter(self.req, limit=length): +length -= int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) +for s in util.filechunkiter(self._req, limit=length): fp.write(s) def redirect(self): -self.oldio = self.ui.fout, self.ui.ferr -self.ui.ferr = self.ui.fout = stringio() +self._oldio = self._ui.fout, self._ui.ferr +self._ui.ferr = self._ui.fout = stringio() def restore(self): -val = self.ui.fout.getvalue() -self.ui.ferr, self.ui.fout = self.oldio +val = self._ui.fout.getvalue() +self._ui.ferr, self._ui.fout = self._oldio return val def _client(self): return 'remote:%s:%s:%s' % ( -self.req.env.get('wsgi.url_scheme') or 'http', -urlreq.quote(self.req.env.get('REMOTE_HOST', '')), -urlreq.quote(self.req.env.get('REMOTE_USER', ''))) +self._req.env.get('wsgi.url_scheme') or 'http', +urlreq.quote(self._req.env.get('REMOTE_HOST', '')), +urlreq.quote(self._req.env.get('REMOTE_USER', ''))) def responsetype(self, prefer_uncompressed): """Determine the appropriate response type and compression settings. Returns a tuple of (mediatype, compengine, engineopts). """ # Determine the response media type and compression engine based # on the request parameters. -protocaps = decodevaluefromheaders(self.req, r'X-HgProto').split(' ') +protocaps = decodevaluefromheaders(self._req, r'X-HgProto').split(' ') if '0.2' in protocaps: # All clients are expected to support uncompressed data. @@ -169,11 +169,11 @@ break # Now find an agreed upon compression format. -for engine in wireproto.supportedcompengines(self.ui, self, +for engine in wireproto.supportedcompengines(self._ui, self, util.SERVERROLE): if engine.wireprotosupport().name in compformats: opts = {} -level = self.ui.configint('server', +level = self._ui.configint('server', '%slevel' % engine.name()) if level is not None: opts['level'] = level @@ -186,7 +186,7 @@ # Don't allow untrusted settings because disabling compression or # setting a very high compression level could lead to flooding # the server's network or CPU. -opts = {'level': self.ui.configint('server', 'zliblevel')} +opts = {'level': self._ui.configint('server', 'zliblevel')} return HGTYPE, util.compengines['zlib'], opts def iscmd(cmd): To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list
D1986: wireprotoserver: remove lock references
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6edb973da584: wireprotoserver: remove lock references (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1986?vs=5109=5124 REVISION DETAIL https://phab.mercurial-scm.org/D1986 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -250,7 +250,6 @@ def __init__(self, ui, repo): self.ui = ui self.repo = repo -self.lock = None self.fin = ui.fin self.fout = ui.fout self.name = 'ssh' @@ -321,12 +320,8 @@ self.fout.flush() def serve_forever(self): -try: -while self.serve_one(): -pass -finally: -if self.lock is not None: -self.lock.release() +while self.serve_one(): +pass sys.exit(0) handlers = { 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
D1985: wireprotoserver: remove support for do_ handlers (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf87323084271: wireprotoserver: remove support for do_command handlers (API) (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1985?vs=5108=5123 REVISION DETAIL https://phab.mercurial-scm.org/D1985 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -344,13 +344,7 @@ rsp = wireproto.dispatch(self.repo, self, cmd) self.handlers[rsp.__class__](self, rsp) elif cmd: -impl = getattr(self, 'do_' + cmd, None) -if impl: -r = impl() -if r is not None: -self.sendresponse(r) -else: -self.sendresponse("") +self.sendresponse("") return cmd != '' def _client(self): 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
D1990: wireprotoserver: make abstractserverproto a proper abstract base class
This revision was automatically updated to reflect the committed changes. Closed by commit rHG654d1f79b9a6: wireprotoserver: make abstractserverproto a proper abstract base class (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1990?vs=5113=5129 REVISION DETAIL https://phab.mercurial-scm.org/D1990 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -6,6 +6,7 @@ from __future__ import absolute_import +import abc import cgi import struct import sys @@ -37,12 +38,15 @@ Used as reference and documentation. """ +__metaclass__ = abc.ABCMeta + +@abc.abstractmethod def getargs(self, args): """return the value for arguments in returns a list of values (same order as )""" -raise NotImplementedError() +@abc.abstractmethod def getfile(self, fp): """write the whole content of a file into a file like object @@ -52,13 +56,12 @@ chunk size is the ascii version of the int. """ -raise NotImplementedError() +@abc.abstractmethod def redirect(self): """may setup interception for stdout and stderr See also the `restore` method.""" -raise NotImplementedError() # If the `redirect` function does install interception, the `restore` # function MUST be defined. If interception is not used, this function 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
D1987: wireprotoserver: remove sshserver.getarg()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8e949f7f4913: wireprotoserver: remove sshserver.getarg() (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1987?vs=5110=5125 REVISION DETAIL https://phab.mercurial-scm.org/D1987 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -282,9 +282,6 @@ data[arg] = val return [data[k] for k in keys] -def getarg(self, name): -return self.getargs(name)[0] - def getfile(self, fpout): self.sendresponse('') count = int(self.fin.readline()) 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
D1910: obsutil: work around filter() being a generator in Python 3
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. Writing this as a generator expression /might/ be a bit better. But I don't think perf is an issue here. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1910 To: durin42, #hg-reviewers, pulkit, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1981: wireprotoserver: add some blank lines between methods
This revision was automatically updated to reflect the committed changes. Closed by commit rHG397c2a9ba553: wireprotoserver: add some blank lines between methods (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1981?vs=5104=5119 REVISION DETAIL https://phab.mercurial-scm.org/D1981 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -109,6 +109,7 @@ else: data[k] = knownargs[k][0] return [data[k] for k in keys] + def _args(self): args = self.req.form.copy() if pycompat.ispy3: @@ -123,16 +124,19 @@ argvalue = decodevaluefromheaders(self.req, r'X-HgArg') args.update(cgi.parse_qs(argvalue, keep_blank_values=True)) return args + def getfile(self, fp): length = int(self.req.env[r'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(r'HTTP_X_HGARGS_POST', 0)) for s in util.filechunkiter(self.req, limit=length): fp.write(s) + def redirect(self): self.oldio = self.ui.fout, self.ui.ferr self.ui.ferr = self.ui.fout = stringio() + def restore(self): val = self.ui.fout.getvalue() self.ui.ferr, self.ui.fout = self.oldio 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
D1983: wireprotoserver: remove unused response attribute
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6da3f324b9de: wireprotoserver: remove unused response attribute (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1983?vs=5106=5121 REVISION DETAIL https://phab.mercurial-scm.org/D1983 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -91,7 +91,6 @@ class webproto(abstractserverproto): def __init__(self, req, ui): self.req = req -self.response = '' self.ui = ui self.name = 'http' 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
D1982: wireprotoserver: rename p to proto
This revision was automatically updated to reflect the committed changes. Closed by commit rHG9d9d1c248ba3: wireprotoserver: rename p to proto (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1982?vs=5105=5120 REVISION DETAIL https://phab.mercurial-scm.org/D1982 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -194,7 +194,7 @@ return cmd in wireproto.commands def callhttp(repo, req, cmd): -p = webproto(req, repo.ui) +proto = webproto(req, repo.ui) def genversion2(gen, engine, engineopts): # application/mercurial-0.2 always sends a payload header @@ -207,7 +207,7 @@ for chunk in gen: yield chunk -rsp = wireproto.dispatch(repo, p, cmd) +rsp = wireproto.dispatch(repo, proto, cmd) if isinstance(rsp, bytes): req.respond(HTTP_OK, HGTYPE, body=rsp) return [] @@ -220,23 +220,24 @@ # This code for compression should not be streamres specific. It # is here because we only compress streamres at the moment. -mediatype, engine, engineopts = p.responsetype(rsp.prefer_uncompressed) +mediatype, engine, engineopts = proto.responsetype( +rsp.prefer_uncompressed) gen = engine.compressstream(gen, engineopts) if mediatype == HGTYPE2: gen = genversion2(gen, engine, engineopts) req.respond(HTTP_OK, mediatype) return gen elif isinstance(rsp, wireproto.pushres): -val = p.restore() +val = proto.restore() rsp = '%d\n%s' % (rsp.res, val) req.respond(HTTP_OK, HGTYPE, body=rsp) return [] elif isinstance(rsp, wireproto.pusherr): # drain the incoming bundle req.drain() -p.restore() +proto.restore() rsp = '0\n%s\n' % rsp.res req.respond(HTTP_OK, HGTYPE, body=rsp) return [] 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
D1991: wireprotoserver: make name part of protocol interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG4e3cb2830397: wireprotoserver: make name part of protocol interface (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1991?vs=5114=5128 REVISION DETAIL https://phab.mercurial-scm.org/D1991 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -40,6 +40,13 @@ __metaclass__ = abc.ABCMeta +@abc.abstractproperty +def name(self): +"""The name of the protocol implementation. + +Used for uniquely identifying the transport type. +""" + @abc.abstractmethod def getargs(self, args): """return the value for arguments in @@ -95,7 +102,10 @@ def __init__(self, req, ui): self._req = req self._ui = ui -self.name = 'http' + +@property +def name(self): +return 'http' def getargs(self, args): knownargs = self._args() @@ -255,15 +265,18 @@ self._repo = repo self._fin = ui.fin self._fout = ui.fout -self.name = 'ssh' hook.redirect(True) ui.fout = repo.ui.fout = ui.ferr # Prevent insertion/deletion of CRs util.setbinary(self._fin) util.setbinary(self._fout) +@property +def name(self): +return 'ssh' + def getargs(self, args): data = {} keys = args.split() 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
D1988: wireprotoserver: make some instance attributes private
This revision was automatically updated to reflect the committed changes. Closed by commit rHG7ce570643fcc: wireprotoserver: make some instance attributes private (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1988?vs=5111=5126 REVISION DETAIL https://phab.mercurial-scm.org/D1988 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -248,60 +248,60 @@ class sshserver(abstractserverproto): def __init__(self, ui, repo): -self.ui = ui -self.repo = repo -self.fin = ui.fin -self.fout = ui.fout +self._ui = ui +self._repo = repo +self._fin = ui.fin +self._fout = ui.fout self.name = 'ssh' hook.redirect(True) ui.fout = repo.ui.fout = ui.ferr # Prevent insertion/deletion of CRs -util.setbinary(self.fin) -util.setbinary(self.fout) +util.setbinary(self._fin) +util.setbinary(self._fout) def getargs(self, args): data = {} keys = args.split() for n in xrange(len(keys)): -argline = self.fin.readline()[:-1] +argline = self._fin.readline()[:-1] arg, l = argline.split() if arg not in keys: raise error.Abort(_("unexpected parameter %r") % arg) if arg == '*': star = {} for k in xrange(int(l)): -argline = self.fin.readline()[:-1] +argline = self._fin.readline()[:-1] arg, l = argline.split() -val = self.fin.read(int(l)) +val = self._fin.read(int(l)) star[arg] = val data['*'] = star else: -val = self.fin.read(int(l)) +val = self._fin.read(int(l)) data[arg] = val return [data[k] for k in keys] def getfile(self, fpout): self.sendresponse('') -count = int(self.fin.readline()) +count = int(self._fin.readline()) while count: -fpout.write(self.fin.read(count)) -count = int(self.fin.readline()) +fpout.write(self._fin.read(count)) +count = int(self._fin.readline()) def redirect(self): pass def sendresponse(self, v): -self.fout.write("%d\n" % len(v)) -self.fout.write(v) -self.fout.flush() +self._fout.write("%d\n" % len(v)) +self._fout.write(v) +self._fout.flush() def sendstream(self, source): -write = self.fout.write +write = self._fout.write for chunk in source.gen: write(chunk) -self.fout.flush() +self._fout.flush() def sendpushresponse(self, rsp): self.sendresponse('') @@ -311,10 +311,10 @@ self.sendresponse(rsp.res) def sendooberror(self, rsp): -self.ui.ferr.write('%s\n-\n' % rsp.message) -self.ui.ferr.flush() -self.fout.write('\n') -self.fout.flush() +self._ui.ferr.write('%s\n-\n' % rsp.message) +self._ui.ferr.flush() +self._fout.write('\n') +self._fout.flush() def serve_forever(self): while self.serve_one(): @@ -331,9 +331,9 @@ } def serve_one(self): -cmd = self.fin.readline()[:-1] +cmd = self._fin.readline()[:-1] if cmd and cmd in wireproto.commands: -rsp = wireproto.dispatch(self.repo, self, cmd) +rsp = wireproto.dispatch(self._repo, self, cmd) self.handlers[rsp.__class__](self, rsp) elif cmd: self.sendresponse("") 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
D1989: wireprotoserver: make response handling attributes private
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6968eb2579a5: wireprotoserver: make response handling attributes private (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1989?vs=5112=5127 REVISION DETAIL https://phab.mercurial-scm.org/D1989 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -283,34 +283,34 @@ return [data[k] for k in keys] def getfile(self, fpout): -self.sendresponse('') +self._sendresponse('') count = int(self._fin.readline()) while count: fpout.write(self._fin.read(count)) count = int(self._fin.readline()) def redirect(self): pass -def sendresponse(self, v): +def _sendresponse(self, v): self._fout.write("%d\n" % len(v)) self._fout.write(v) self._fout.flush() -def sendstream(self, source): +def _sendstream(self, source): write = self._fout.write for chunk in source.gen: write(chunk) self._fout.flush() -def sendpushresponse(self, rsp): -self.sendresponse('') -self.sendresponse(str(rsp.res)) +def _sendpushresponse(self, rsp): +self._sendresponse('') +self._sendresponse(str(rsp.res)) -def sendpusherror(self, rsp): -self.sendresponse(rsp.res) +def _sendpusherror(self, rsp): +self._sendresponse(rsp.res) -def sendooberror(self, rsp): +def _sendooberror(self, rsp): self._ui.ferr.write('%s\n-\n' % rsp.message) self._ui.ferr.flush() self._fout.write('\n') @@ -321,22 +321,22 @@ pass sys.exit(0) -handlers = { -str: sendresponse, -wireproto.streamres: sendstream, -wireproto.streamres_legacy: sendstream, -wireproto.pushres: sendpushresponse, -wireproto.pusherr: sendpusherror, -wireproto.ooberror: sendooberror, +_handlers = { +str: _sendresponse, +wireproto.streamres: _sendstream, +wireproto.streamres_legacy: _sendstream, +wireproto.pushres: _sendpushresponse, +wireproto.pusherr: _sendpusherror, +wireproto.ooberror: _sendooberror, } def serve_one(self): cmd = self._fin.readline()[:-1] if cmd and cmd in wireproto.commands: rsp = wireproto.dispatch(self._repo, self, cmd) -self.handlers[rsp.__class__](self, rsp) +self._handlers[rsp.__class__](self, rsp) elif cmd: -self.sendresponse("") +self._sendresponse("") return cmd != '' def _client(self): 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
D1992: mdiff: use slice instead of index on bytestr when checking single bytes
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. I'd be curious if there is a perf hit to this. The slicing API is a bit more involved than `__getitem__` at the C layer. But since this is Python code, my guess is run time is dominated by Python function call overhead and we don't notice a perf difference. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1992 To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1994: config: replace a for-else by all()
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/D1994 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 @@ -1657,10 +1657,7 @@ else: paths = rcutil.userrcpath() -for f in paths: -if os.path.exists(f): -break -else: +if not any(os.path.exists(f) for f in paths): if opts.get('global'): samplehgrc = uimod.samplehgrcs['global'] elif opts.get('local'): 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
D1993: discovery: don't reimplement all()
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/D1993 AFFECTED FILES mercurial/discovery.py CHANGE DETAILS diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -53,13 +53,8 @@ return treediscovery.findcommonincoming(repo, remote, heads, force) if heads: -allknown = True knownnode = repo.changelog.hasnode # no nodemap until it is filtered -for h in heads: -if not knownnode(h): -allknown = False -break -if allknown: +if all(knownnode(h) for h in heads): return (heads, False, heads) res = setdiscovery.findcommonheads(repo.ui, repo, remote, heads, 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
D1974: narrow: import experimental extension from narrowhg revision cb51d673e9c5
indygreg added a comment. I glanced at the code and found the first set of needed follow-ups. INLINE COMMENTS > __init__.py:11-14 > +from mercurial import __version__ > +if __version__.version < '3.7': > +raise ImportError( > +'narrowhg requires mercurial 3.7 or newer') This seems inappropriate. > narrowbundle2.py:37-46 > +narrowcap = 'narrow' > +narrowacl_section = 'narrowhgacl' > +changespecpart = narrowcap + ':changespec' > +specpart = narrowcap + ':spec' > +specpart_include = 'include' > +specpart_exclude = 'exclude' > +killnodesignal = 'KILL' I think we'll want to UPPERCASE these since they are constants. > narrowbundle2.py:223 > +getcgkwargs = {} > +if cgversions: # 3.1 and 3.2 ship with an empty value > +cgversions = [v for v in cgversions If this is referring to Mercurial versions, then this code is likely not needed, as a client with narrow support is newer than 3.1 or 3.2. > narrowrepo.py:26 > + > +requirement = 'narrowhg' > + I think we'll want to put `exp` somewhere in the requirement name until we're ready to mark the feature as non-experimental in core. > narrowrevlog.py:16-20 > +ELLIPSIS_NODE_FLAG = 1 << 14 > +revlog.REVIDX_KNOWN_FLAGS |= ELLIPSIS_NODE_FLAG > +if (util.safehasattr(revlog, 'REVIDX_FLAGS_ORDER') and > +ELLIPSIS_NODE_FLAG not in revlog.REVIDX_FLAGS_ORDER): > +revlog.REVIDX_FLAGS_ORDER.append(ELLIPSIS_NODE_FLAG) This needs to move to core because revision flags need to be reserved there. > narrowtemplates.py:45-50 > +def setup(): > +templatekw.keywords['ellipsis'] = ellipsis > +templatekw.keywords['outsidenarrow'] = outsidenarrow > + > +revset.symbols['ellipsis'] = ellipsisrevset > +revset.safesymbols.add('ellipsis') We should be using the `registrar` API for declaring revsets and templates. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1974 To: durin42, #hg-reviewers Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1970: contrib: fix dirstatenonnormalcheck to work in Python 3
durin42 updated this revision to Diff 5115. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1970?vs=5080=5115 REVISION DETAIL https://phab.mercurial-scm.org/D1970 AFFECTED FILES contrib/dirstatenonnormalcheck.py mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1237,9 +1237,12 @@ util.clearcachedproperty(self, "nonnormalset") util.clearcachedproperty(self, "otherparentset") -def iteritems(self): +def items(self): return self._map.iteritems() +# forward for python2,3 compat +iteritems = items + def __len__(self): return len(self._map) diff --git a/contrib/dirstatenonnormalcheck.py b/contrib/dirstatenonnormalcheck.py --- a/contrib/dirstatenonnormalcheck.py +++ b/contrib/dirstatenonnormalcheck.py @@ -17,32 +17,33 @@ """Compute nonnormal entries from dirstate's dmap""" res = set() for f, e in dmap.iteritems(): -if e[0] != 'n' or e[3] == -1: +if e[0] != b'n' or e[3] == -1: res.add(f) return res def checkconsistency(ui, orig, dmap, _nonnormalset, label): """Compute nonnormalset from dmap, check that it matches _nonnormalset""" nonnormalcomputedmap = nonnormalentries(dmap) if _nonnormalset != nonnormalcomputedmap: -ui.develwarn("%s call to %s\n" % (label, orig), config='dirstate') -ui.develwarn("inconsistency in nonnormalset\n", config='dirstate') -ui.develwarn("[nonnormalset] %s\n" % _nonnormalset, config='dirstate') -ui.develwarn("[map] %s\n" % nonnormalcomputedmap, config='dirstate') +ui.develwarn(b"%s call to %s\n" % (label, orig), config=b'dirstate') +ui.develwarn(b"inconsistency in nonnormalset\n", config=b'dirstate') +ui.develwarn(b"[nonnormalset] %s\n" % _nonnormalset, config=b'dirstate') +ui.develwarn(b"[map] %s\n" % nonnormalcomputedmap, config=b'dirstate') def _checkdirstate(orig, self, arg): """Check nonnormal set consistency before and after the call to orig""" checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, - "before") + b"before") r = orig(self, arg) -checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, "after") +checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, + b"after") return r def extsetup(ui): """Wrap functions modifying dirstate to check nonnormalset consistency""" dirstatecl = dirstate.dirstate -devel = ui.configbool('devel', 'all-warnings') -paranoid = ui.configbool('experimental', 'nonnormalparanoidcheck') +devel = ui.configbool(b'devel', b'all-warnings') +paranoid = ui.configbool(b'experimental', b'nonnormalparanoidcheck') if devel: extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate) if paranoid: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1992: mdiff: use slice instead of index on bytestr when checking single bytes
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is portable to Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1992 AFFECTED FILES mercurial/mdiff.py CHANGE DETAILS diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -275,7 +275,7 @@ headerlines = [] hunks = (None, ['Binary file %s has changed\n' % fn1]), elif not a: -without_newline = b[-1] != '\n' +without_newline = b[-1:] != '\n' b = splitnewlines(b) if a is None: l1 = '--- /dev/null%s' % datetag(epoch) @@ -291,7 +291,7 @@ hunklines.append(_missing_newline_marker) hunks = (hunkrange, hunklines), elif not b: -without_newline = a[-1] != '\n' +without_newline = a[-1:] != '\n' a = splitnewlines(a) l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) if b is None: @@ -384,17 +384,17 @@ # a newline, print only one marker. That's the only case in # which the hunk can end in a shared line without a newline. skip = False -if t1[-1] != '\n' and astart + alen == len(l1) + 1: +if t1[-1:] != '\n' and astart + alen == len(l1) + 1: for i in xrange(len(hunklines) - 1, -1, -1): -if hunklines[i][0] in ('-', ' '): -if hunklines[i][0] == ' ': +if hunklines[i][0:1] in ('-', ' '): +if hunklines[i][0:1] == ' ': skip = True hunklines[i] += '\n' hunklines.insert(i + 1, _missing_newline_marker) break -if not skip and t2[-1] != '\n' and bstart + blen == len(l2) + 1: +if not skip and t2[-1:] != '\n' and bstart + blen == len(l2) + 1: for i in xrange(len(hunklines) - 1, -1, -1): -if hunklines[i][0] == '+': +if hunklines[i][0:1] == '+': hunklines[i] += '\n' hunklines.insert(i + 1, _missing_newline_marker) break To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1985: wireprotoserver: remove support for do_ handlers (API)
durin42 accepted this revision. durin42 added a comment. This revision is now accepted and ready to land. Fixing a typo (now instead of no) in log message in flight. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1985 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
D1985: wireprotoserver: remove support for do_ handlers (API)
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Old versions of wire protocol handlers relied on methods named do_ to handle wire protocol commands. The last definition of these methods on sshserver was removed by https://phab.mercurial-scm.org/rHG9f6e0e7ef82884e3ec66455dac7312820c2b35ce ~2 years ago. I think it's time to not support this mechanism for defining command handlers. .. api:: sshserver now longers looks for wire protocol command handlers in methods named do_. Use @wireproto.wireprotocommand to declare wire protocol command handler functions. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1985 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -344,13 +344,7 @@ rsp = wireproto.dispatch(self.repo, self, cmd) self.handlers[rsp.__class__](self, rsp) elif cmd: -impl = getattr(self, 'do_' + cmd, None) -if impl: -r = impl() -if r is not None: -self.sendresponse(r) -else: -self.sendresponse("") +self.sendresponse("") return cmd != '' def _client(self): 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
D1991: wireprotoserver: make name part of protocol interface
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is a required part of the interface. Abstract properties must be defined at type creation time. So we make name a @property. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1991 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -40,6 +40,13 @@ __metaclass__ = abc.ABCMeta +@abc.abstractproperty +def name(self): +"""The name of the protocol implementation. + +Used for uniquely identifying the transport type. +""" + @abc.abstractmethod def getargs(self, args): """return the value for arguments in @@ -95,7 +102,10 @@ def __init__(self, req, ui): self._req = req self._ui = ui -self.name = 'http' + +@property +def name(self): +return 'http' def getargs(self, args): knownargs = self._args() @@ -255,15 +265,18 @@ self._repo = repo self._fin = ui.fin self._fout = ui.fout -self.name = 'ssh' hook.redirect(True) ui.fout = repo.ui.fout = ui.ferr # Prevent insertion/deletion of CRs util.setbinary(self._fin) util.setbinary(self._fout) +@property +def name(self): +return 'ssh' + def getargs(self, args): data = {} keys = args.split() 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
D1990: wireprotoserver: make abstractserverproto a proper abstract base class
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Plug in the abc module so we can have run-time validation of type conformance. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1990 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -6,6 +6,7 @@ from __future__ import absolute_import +import abc import cgi import struct import sys @@ -37,12 +38,15 @@ Used as reference and documentation. """ +__metaclass__ = abc.ABCMeta + +@abc.abstractmethod def getargs(self, args): """return the value for arguments in returns a list of values (same order as )""" -raise NotImplementedError() +@abc.abstractmethod def getfile(self, fp): """write the whole content of a file into a file like object @@ -52,13 +56,12 @@ chunk size is the ascii version of the int. """ -raise NotImplementedError() +@abc.abstractmethod def redirect(self): """may setup interception for stdout and stderr See also the `restore` method.""" -raise NotImplementedError() # If the `redirect` function does install interception, the `restore` # function MUST be defined. If interception is not used, this function 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
D1984: wireprotoserver: make attributes private
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY These aren't part of the protocol interface. So they should be _ prefixed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1984 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -90,8 +90,8 @@ class webproto(abstractserverproto): def __init__(self, req, ui): -self.req = req -self.ui = ui +self._req = req +self._ui = ui self.name = 'http' def getargs(self, args): @@ -110,51 +110,51 @@ return [data[k] for k in keys] def _args(self): -args = self.req.form.copy() +args = self._req.form.copy() if pycompat.ispy3: args = {k.encode('ascii'): [v.encode('ascii') for v in vs] for k, vs in args.items()} -postlen = int(self.req.env.get(r'HTTP_X_HGARGS_POST', 0)) +postlen = int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) if postlen: args.update(cgi.parse_qs( -self.req.read(postlen), keep_blank_values=True)) +self._req.read(postlen), keep_blank_values=True)) return args -argvalue = decodevaluefromheaders(self.req, r'X-HgArg') +argvalue = decodevaluefromheaders(self._req, r'X-HgArg') args.update(cgi.parse_qs(argvalue, keep_blank_values=True)) return args def getfile(self, fp): -length = int(self.req.env[r'CONTENT_LENGTH']) +length = int(self._req.env[r'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(r'HTTP_X_HGARGS_POST', 0)) -for s in util.filechunkiter(self.req, limit=length): +length -= int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) +for s in util.filechunkiter(self._req, limit=length): fp.write(s) def redirect(self): -self.oldio = self.ui.fout, self.ui.ferr -self.ui.ferr = self.ui.fout = stringio() +self._oldio = self._ui.fout, self._ui.ferr +self._ui.ferr = self._ui.fout = stringio() def restore(self): -val = self.ui.fout.getvalue() -self.ui.ferr, self.ui.fout = self.oldio +val = self._ui.fout.getvalue() +self._ui.ferr, self._ui.fout = self._oldio return val def _client(self): return 'remote:%s:%s:%s' % ( -self.req.env.get('wsgi.url_scheme') or 'http', -urlreq.quote(self.req.env.get('REMOTE_HOST', '')), -urlreq.quote(self.req.env.get('REMOTE_USER', ''))) +self._req.env.get('wsgi.url_scheme') or 'http', +urlreq.quote(self._req.env.get('REMOTE_HOST', '')), +urlreq.quote(self._req.env.get('REMOTE_USER', ''))) def responsetype(self, prefer_uncompressed): """Determine the appropriate response type and compression settings. Returns a tuple of (mediatype, compengine, engineopts). """ # Determine the response media type and compression engine based # on the request parameters. -protocaps = decodevaluefromheaders(self.req, r'X-HgProto').split(' ') +protocaps = decodevaluefromheaders(self._req, r'X-HgProto').split(' ') if '0.2' in protocaps: # All clients are expected to support uncompressed data. @@ -169,11 +169,11 @@ break # Now find an agreed upon compression format. -for engine in wireproto.supportedcompengines(self.ui, self, +for engine in wireproto.supportedcompengines(self._ui, self, util.SERVERROLE): if engine.wireprotosupport().name in compformats: opts = {} -level = self.ui.configint('server', +level = self._ui.configint('server', '%slevel' % engine.name()) if level is not None: opts['level'] = level @@ -186,7 +186,7 @@ # Don't allow untrusted settings because disabling compression or # setting a very high compression level could lead to flooding # the server's network or CPU. -opts = {'level': self.ui.configint('server', 'zliblevel')} +opts = {'level': self._ui.configint('server', 'zliblevel')} return HGTYPE, util.compengines['zlib'], opts def iscmd(cmd): To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
D1987: wireprotoserver: remove sshserver.getarg()
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY AFAICT the last consumer of this helper method was removed by https://phab.mercurial-scm.org/rHGd054cc5c77370c345a0c41a002b2ce0aada45389 in 2010. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1987 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -282,9 +282,6 @@ data[arg] = val return [data[k] for k in keys] -def getarg(self, name): -return self.getargs(name)[0] - def getfile(self, fpout): self.sendresponse('') count = int(self.fin.readline()) 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
D1989: wireprotoserver: make response handling attributes private
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The send* methods are specific to sshserver and aren't part of the common protocol interface. So rename them accordingly. The handlers dict is also specific to sshserver and is related to these methods. So give it the same treatment. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1989 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -283,34 +283,34 @@ return [data[k] for k in keys] def getfile(self, fpout): -self.sendresponse('') +self._sendresponse('') count = int(self._fin.readline()) while count: fpout.write(self._fin.read(count)) count = int(self._fin.readline()) def redirect(self): pass -def sendresponse(self, v): +def _sendresponse(self, v): self._fout.write("%d\n" % len(v)) self._fout.write(v) self._fout.flush() -def sendstream(self, source): +def _sendstream(self, source): write = self._fout.write for chunk in source.gen: write(chunk) self._fout.flush() -def sendpushresponse(self, rsp): -self.sendresponse('') -self.sendresponse(str(rsp.res)) +def _sendpushresponse(self, rsp): +self._sendresponse('') +self._sendresponse(str(rsp.res)) -def sendpusherror(self, rsp): -self.sendresponse(rsp.res) +def _sendpusherror(self, rsp): +self._sendresponse(rsp.res) -def sendooberror(self, rsp): +def _sendooberror(self, rsp): self._ui.ferr.write('%s\n-\n' % rsp.message) self._ui.ferr.flush() self._fout.write('\n') @@ -321,22 +321,22 @@ pass sys.exit(0) -handlers = { -str: sendresponse, -wireproto.streamres: sendstream, -wireproto.streamres_legacy: sendstream, -wireproto.pushres: sendpushresponse, -wireproto.pusherr: sendpusherror, -wireproto.ooberror: sendooberror, +_handlers = { +str: _sendresponse, +wireproto.streamres: _sendstream, +wireproto.streamres_legacy: _sendstream, +wireproto.pushres: _sendpushresponse, +wireproto.pusherr: _sendpusherror, +wireproto.ooberror: _sendooberror, } def serve_one(self): cmd = self._fin.readline()[:-1] if cmd and cmd in wireproto.commands: rsp = wireproto.dispatch(self._repo, self, cmd) -self.handlers[rsp.__class__](self, rsp) +self._handlers[rsp.__class__](self, rsp) elif cmd: -self.sendresponse("") +self._sendresponse("") return cmd != '' def _client(self): 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
D1986: wireprotoserver: remove lock references
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY AFAICT sshserver.lock is unused. The last caller of it disappeared in https://phab.mercurial-scm.org/rHG9f6e0e7ef82884e3ec66455dac7312820c2b35ce ~18 months ago as part of removing code to support ancient wire protocol commands. Let's remove some dead code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1986 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -250,7 +250,6 @@ def __init__(self, ui, repo): self.ui = ui self.repo = repo -self.lock = None self.fin = ui.fin self.fout = ui.fout self.name = 'ssh' @@ -321,12 +320,8 @@ self.fout.flush() def serve_forever(self): -try: -while self.serve_one(): -pass -finally: -if self.lock is not None: -self.lock.release() +while self.serve_one(): +pass sys.exit(0) handlers = { 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
D1988: wireprotoserver: make some instance attributes private
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY sshserver attempts to conform to a well-defined interface. The instance attributes changed as part of this commit don't appear to be part of that interface. So prefix them with _ to mark them as private. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1988 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -248,60 +248,60 @@ class sshserver(abstractserverproto): def __init__(self, ui, repo): -self.ui = ui -self.repo = repo -self.fin = ui.fin -self.fout = ui.fout +self._ui = ui +self._repo = repo +self._fin = ui.fin +self._fout = ui.fout self.name = 'ssh' hook.redirect(True) ui.fout = repo.ui.fout = ui.ferr # Prevent insertion/deletion of CRs -util.setbinary(self.fin) -util.setbinary(self.fout) +util.setbinary(self._fin) +util.setbinary(self._fout) def getargs(self, args): data = {} keys = args.split() for n in xrange(len(keys)): -argline = self.fin.readline()[:-1] +argline = self._fin.readline()[:-1] arg, l = argline.split() if arg not in keys: raise error.Abort(_("unexpected parameter %r") % arg) if arg == '*': star = {} for k in xrange(int(l)): -argline = self.fin.readline()[:-1] +argline = self._fin.readline()[:-1] arg, l = argline.split() -val = self.fin.read(int(l)) +val = self._fin.read(int(l)) star[arg] = val data['*'] = star else: -val = self.fin.read(int(l)) +val = self._fin.read(int(l)) data[arg] = val return [data[k] for k in keys] def getfile(self, fpout): self.sendresponse('') -count = int(self.fin.readline()) +count = int(self._fin.readline()) while count: -fpout.write(self.fin.read(count)) -count = int(self.fin.readline()) +fpout.write(self._fin.read(count)) +count = int(self._fin.readline()) def redirect(self): pass def sendresponse(self, v): -self.fout.write("%d\n" % len(v)) -self.fout.write(v) -self.fout.flush() +self._fout.write("%d\n" % len(v)) +self._fout.write(v) +self._fout.flush() def sendstream(self, source): -write = self.fout.write +write = self._fout.write for chunk in source.gen: write(chunk) -self.fout.flush() +self._fout.flush() def sendpushresponse(self, rsp): self.sendresponse('') @@ -311,10 +311,10 @@ self.sendresponse(rsp.res) def sendooberror(self, rsp): -self.ui.ferr.write('%s\n-\n' % rsp.message) -self.ui.ferr.flush() -self.fout.write('\n') -self.fout.flush() +self._ui.ferr.write('%s\n-\n' % rsp.message) +self._ui.ferr.flush() +self._fout.write('\n') +self._fout.flush() def serve_forever(self): while self.serve_one(): @@ -331,9 +331,9 @@ } def serve_one(self): -cmd = self.fin.readline()[:-1] +cmd = self._fin.readline()[:-1] if cmd and cmd in wireproto.commands: -rsp = wireproto.dispatch(self.repo, self, cmd) +rsp = wireproto.dispatch(self._repo, self, cmd) self.handlers[rsp.__class__](self, rsp) elif cmd: self.sendresponse("") 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
D1983: wireprotoserver: remove unused response attribute
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I think the last use of this attribute was removed by https://phab.mercurial-scm.org/rHG2f8adc60e01328523052b1829ca9846ec1285f60 in 2010. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1983 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -91,7 +91,6 @@ class webproto(abstractserverproto): def __init__(self, req, ui): self.req = req -self.response = '' self.ui = ui self.name = 'http' 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
D1982: wireprotoserver: rename p to proto
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY To aid readability. And to make it easier to search the code base for protocol instances. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1982 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -194,7 +194,7 @@ return cmd in wireproto.commands def callhttp(repo, req, cmd): -p = webproto(req, repo.ui) +proto = webproto(req, repo.ui) def genversion2(gen, engine, engineopts): # application/mercurial-0.2 always sends a payload header @@ -207,7 +207,7 @@ for chunk in gen: yield chunk -rsp = wireproto.dispatch(repo, p, cmd) +rsp = wireproto.dispatch(repo, proto, cmd) if isinstance(rsp, bytes): req.respond(HTTP_OK, HGTYPE, body=rsp) return [] @@ -220,23 +220,24 @@ # This code for compression should not be streamres specific. It # is here because we only compress streamres at the moment. -mediatype, engine, engineopts = p.responsetype(rsp.prefer_uncompressed) +mediatype, engine, engineopts = proto.responsetype( +rsp.prefer_uncompressed) gen = engine.compressstream(gen, engineopts) if mediatype == HGTYPE2: gen = genversion2(gen, engine, engineopts) req.respond(HTTP_OK, mediatype) return gen elif isinstance(rsp, wireproto.pushres): -val = p.restore() +val = proto.restore() rsp = '%d\n%s' % (rsp.res, val) req.respond(HTTP_OK, HGTYPE, body=rsp) return [] elif isinstance(rsp, wireproto.pusherr): # drain the incoming bundle req.drain() -p.restore() +proto.restore() rsp = '0\n%s\n' % rsp.res req.respond(HTTP_OK, HGTYPE, body=rsp) return [] 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
D1981: wireprotoserver: add some blank lines between methods
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Let's make this file slightly easier to read. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1981 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -109,6 +109,7 @@ else: data[k] = knownargs[k][0] return [data[k] for k in keys] + def _args(self): args = self.req.form.copy() if pycompat.ispy3: @@ -123,16 +124,19 @@ argvalue = decodevaluefromheaders(self.req, r'X-HgArg') args.update(cgi.parse_qs(argvalue, keep_blank_values=True)) return args + def getfile(self, fp): length = int(self.req.env[r'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(r'HTTP_X_HGARGS_POST', 0)) for s in util.filechunkiter(self.req, limit=length): fp.write(s) + def redirect(self): self.oldio = self.ui.fout, self.ui.ferr self.ui.ferr = self.ui.fout = stringio() + def restore(self): val = self.ui.fout.getvalue() self.ui.ferr, self.ui.fout = self.oldio 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
D1972: tests: start a set of unit tests for mdiff.py, starting with splitnewlines
This revision was automatically updated to reflect the committed changes. Closed by commit rHG119e4dbdeb29: tests: start a set of unit tests for mdiff.py, starting with splitnewlines (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1972?vs=5085=5103 REVISION DETAIL https://phab.mercurial-scm.org/D1972 AFFECTED FILES tests/test-mdiff.py CHANGE DETAILS diff --git a/tests/test-mdiff.py b/tests/test-mdiff.py new file mode 100644 --- /dev/null +++ b/tests/test-mdiff.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import +from __future__ import print_function + +import unittest + +from mercurial import ( +mdiff, +) + +class splitnewlinesTests(unittest.TestCase): + +def test_splitnewlines(self): +cases = {'a\nb\nc\n': ['a\n', 'b\n', 'c\n'], + 'a\nb\nc': ['a\n', 'b\n', 'c'], + 'a\nb\nc\n\n': ['a\n', 'b\n', 'c\n', '\n'], + '': [], + 'abcabc': ['abcabc'], + } +for inp, want in cases.iteritems(): +self.assertEqual(mdiff.splitnewlines(inp), want) + +if __name__ == '__main__': +import silenttestrunner +silenttestrunner.main(__name__) To: durin42, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1971: perf: add a perfunidiff command for benchmarking unified diff speed
This revision was automatically updated to reflect the committed changes. Closed by commit rHG204435ef0a6f: perf: add a perfunidiff command for benchmarking unified diff speed (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1971?vs=5084=5102 REVISION DETAIL https://phab.mercurial-scm.org/D1971 AFFECTED FILES contrib/perf.py tests/test-contrib-perf.t CHANGE DETAILS diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t --- a/tests/test-contrib-perf.t +++ b/tests/test-contrib-perf.t @@ -114,6 +114,7 @@ perftags (no help text available) perftemplating (no help text available) + perfunidiff benchmark a unified diff between revisions perfvolatilesets benchmark the computation of various volatile set perfwalk (no help text available) @@ -126,6 +127,8 @@ $ hg perfannotate a $ hg perfbdiff -c 1 $ hg perfbdiff --alldata 1 + $ hg perfunidiff -c 1 + $ hg perfunidiff --alldata 1 $ hg perfbookmarks $ hg perfbranchmap $ hg perfcca diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -1031,6 +1031,71 @@ with ready: ready.notify_all() +@command('perfunidiff', revlogopts + formatteropts + [ +('', 'count', 1, 'number of revisions to test (when using --startrev)'), +('', 'alldata', False, 'test unidiffs for all associated revisions'), +], '-c|-m|FILE REV') +def perfunidiff(ui, repo, file_, rev=None, count=None, **opts): +"""benchmark a unified diff between revisions + +This doesn't include any copy tracing - it's just a unified diff +of the texts. + +By default, benchmark a diff between its delta parent and itself. + +With ``--count``, benchmark diffs between delta parents and self for N +revisions starting at the specified revision. + +With ``--alldata``, assume the requested revision is a changeset and +measure diffs for all changes related to that changeset (manifest +and filelogs). +""" +if opts['alldata']: +opts['changelog'] = True + +if opts.get('changelog') or opts.get('manifest'): +file_, rev = None, file_ +elif rev is None: +raise error.CommandError('perfunidiff', 'invalid arguments') + +textpairs = [] + +r = cmdutil.openrevlog(repo, 'perfunidiff', file_, opts) + +startrev = r.rev(r.lookup(rev)) +for rev in range(startrev, min(startrev + count, len(r) - 1)): +if opts['alldata']: +# Load revisions associated with changeset. +ctx = repo[rev] +mtext = repo.manifestlog._revlog.revision(ctx.manifestnode()) +for pctx in ctx.parents(): +pman = repo.manifestlog._revlog.revision(pctx.manifestnode()) +textpairs.append((pman, mtext)) + +# Load filelog revisions by iterating manifest delta. +man = ctx.manifest() +pman = ctx.p1().manifest() +for filename, change in pman.diff(man).items(): +fctx = repo.file(filename) +f1 = fctx.revision(change[0][0] or -1) +f2 = fctx.revision(change[1][0] or -1) +textpairs.append((f1, f2)) +else: +dp = r.deltaparent(rev) +textpairs.append((r.revision(dp), r.revision(rev))) + +def d(): +for left, right in textpairs: +# The date strings don't matter, so we pass empty strings. +headerlines, hunks = mdiff.unidiff( +left, '', right, '', 'left', 'right') +# consume iterators in roughly the way patch.py does +b'\n'.join(headerlines) +b''.join(sum((list(hlines) for hrange, hlines in hunks), [])) +timer, fm = gettimer(ui, opts) +timer(d) +fm.end() + @command('perfdiffwd', formatteropts) def perfdiffwd(ui, repo, **opts): """Profile diff of working directory changes""" To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1973: bdiff: write a native version of splitnewlines
indygreg added subscribers: yuja, indygreg. indygreg requested changes to this revision. indygreg added a comment. This revision now requires changes to proceed. This looks mostly good. Needs some minor tweaks. Some of my comments are informative and can probably be ignored as far as reviewing goes. INLINE COMMENTS > bdiff.c:187 > +const char *source, Py_ssize_t len) { > + PyObject *sliced = PyString_FromStringAndSize(source, len); > + if (sliced == NULL) Let's use `PyBytes` here for compatibility with Python 3. Also, `Py_buffer` here would let us avoid a memory allocation. Unfortunately, various C extensions in older versions of Python 2.7 don't recognize the `Py_buffer` interface (I'm looking at you `zlib`). So we need to be careful about where all we use `Py_buffer` tricks :( It would be really nice if *all* of this code were in C so we didn't have to allocate a `PyObject` for every line: we could just pass an array of line offsets around. > bdiff.c:190 > + return false; > + PyList_SetItem(list, destidx, sliced); > + return true; The `PyList` is pre-allocated. That means you can use `PyList_SET_ITEM()` for even faster execution. > bdiff.c:201-202 > + > + if (!PyArg_ParseTuple(args, "s#", , )) > + goto abort; > + if (!size) { Does our style guideline not require braces yet? Seeing this reminds me of `goto fail` :( > bdiff.c:208-212 > + for (i = 0; i < size - 1; ++i) { > + if (text[i] == '\n') { > + ++nelts; > + } > + } For a micro optimization, I bet if you rewrite this to iterate over chunks of size `size_t` and do bit tests that this will be even faster. The searching for newlines is a hot loop in the `bdiff` code. Unfortunately, I never completed my refactor to optimize the line scanning. > bdiff.c:216-217 > + nelts = 0; > + for (i = 0; i < size - 1; ++i) { > + if (text[i] == '\n') { > + if (!sliceintolist( I have a feeling this extra line scan will matter in a benchmark. Could you `perf record` the new `hg perf*` command and verify? If it is a big deal, I would allocate an `int[16384]` array on the stack or something to deal with the common case and store additional newline offsets on the heap so we only do the newline scan once. > mdiff.py:43 > > +splitnewlines = getattr(bdiff, 'splitnewlines', splitnewlines) > + @yuja may have an opinion on this, but mine is that we now have stronger guarantees around C extension versioning, so if the active module policy is to use C extensions, we should ensure we get `splitnewlines` from the C module. I /think/ if we move `splitnewlines` to the `bdiff` module that things will sort themselves out? This could be done as a follow-up easily enough though. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1973 To: durin42, #hg-reviewers, indygreg Cc: indygreg, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1980: narrow: remove old version-checking logic and declare internal
durin42 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/D1980 AFFECTED FILES hgext/narrow/__init__.py CHANGE DETAILS diff --git a/hgext/narrow/__init__.py b/hgext/narrow/__init__.py --- a/hgext/narrow/__init__.py +++ b/hgext/narrow/__init__.py @@ -8,16 +8,11 @@ from __future__ import absolute_import -from mercurial import __version__ -if __version__.version < '3.7': -raise ImportError( -'narrowhg requires mercurial 3.7 or newer') - -try: -from .__versionnum__ import version -__version__ = version -except ImportError: -pass +# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for +# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should +# be specifying the version(s) of Mercurial they are tested with, or +# leave the attribute unspecified. +testedwith = 'ships-with-hg-core' from mercurial import ( extensions, To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5780] New: hg incoming --bundle --quiet uses debilitating amounts of RAM on large repos
https://bz.mercurial-scm.org/show_bug.cgi?id=5780 Bug ID: 5780 Summary: hg incoming --bundle --quiet uses debilitating amounts of RAM on large repos Product: Mercurial Version: 4.4.2 Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: fiendi...@gmail.com CC: mercurial-devel@mercurial-scm.org Trying to apply a generic method to get a bundle from a remote repo without cloning first, because downloading a bundle that I can't save just to make my own from its applied output is super wasteful: > hg incoming --quiet -l 1 --bundle out https://hg.mozilla.org/mozilla-unified/ (because -l can't be 0, and --quiet alone still generates tons of output) After downloading the entire bundle, the process then balloons to use over 12GB of RAM for no reason and then aborts with > abort: Cannot allocate memory -- 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
D1979: tests: fold narrow treemanifest tests into main test file using testcases
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY These tests predate the testcases functionality in run-tests.py, so it was never done in narrowhg. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1979 AFFECTED FILES tests/test-narrow-commit-tree.t tests/test-narrow-commit.t tests/test-narrow-merge-tree.t tests/test-narrow-merge.t tests/test-narrow-patch-tree.t tests/test-narrow-patch.t tests/test-narrow-strip-tree.t tests/test-narrow-strip.t tests/test-narrow-tree.t tests/test-narrow-widen-tree.t tests/test-narrow-widen.t tests/test-narrow.t CHANGE DETAILS diff --git a/tests/test-narrow.t b/tests/test-narrow.t --- a/tests/test-narrow.t +++ b/tests/test-narrow.t @@ -1,5 +1,14 @@ +#testcases flat tree + $ . "$TESTDIR/narrow-library.sh" +#if tree + $ cat << EOF >> $HGRCPATH + > [experimental] + > treemanifest = 1 + > EOF +#endif + $ hg init master $ cd master $ cat >> .hg/hgrc <> d6/f @@ -159,6 +170,7 @@ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob) deleting data/d3/f.i + deleting meta/d3/00manifest.i (tree !) $ hg log -T '{desc}\n' -r . add d10/f Updates to nullid if necessary @@ -178,6 +190,7 @@ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob) deleting data/d3/f.i + deleting meta/d3/00manifest.i (tree !) $ hg id $ cd .. @@ -197,6 +210,7 @@ searching for changes looking for local changes to affected paths deleting data/d0/f.i + deleting meta/d0/00manifest.i (tree !) $ hg tracked $ hg files [1] @@ -252,6 +266,7 @@ searching for changes looking for local changes to affected paths deleting data/d6/f.i + deleting meta/d6/00manifest.i (tree !) $ hg tracked I path:d0 I path:d3 @@ -289,6 +304,7 @@ searching for changes looking for local changes to affected paths deleting data/d0/f.i + deleting meta/d0/00manifest.i (tree !) $ hg tracked I path:d3 I path:d9 diff --git a/tests/test-narrow-widen.t b/tests/test-narrow-widen.t --- a/tests/test-narrow-widen.t +++ b/tests/test-narrow-widen.t @@ -1,5 +1,13 @@ +#testcases flat tree $ . "$TESTDIR/narrow-library.sh" +#if tree + $ cat << EOF >> $HGRCPATH + > [experimental] + > treemanifest = 1 + > EOF +#endif + $ hg init master $ cd master $ cat >> .hg/hgrc < --extra-config-opt experimental.treemanifest=1 test-narrow-widen.t 2>&1 | \ - > grep -v 'unexpected mercurial lib' | egrep -v '\(expected' - - --- */test-narrow-widen.t (glob) - +++ */test-narrow-widen.t.err (glob) - @@ -\d+,\d+ \+\d+,\d+ @@ (re) - $ hg verify - checking changesets - checking manifests - + checking directory manifests - crosschecking files in changesets and manifests - checking files - 4 files, 8 changesets, 4 total revisions - @@ -\d+,\d+ \+\d+,\d+ @@ (re) - $ hg verify - checking changesets - checking manifests - + checking directory manifests - crosschecking files in changesets and manifests - checking files - 5 files, 9 changesets, 5 total revisions - - ERROR: test-narrow-widen.t output changed - ! - Failed test-narrow-widen.t: output changed - # Ran 1 tests, 0 skipped, 1 failed. - python hash seed: * (glob) diff --git a/tests/test-narrow-tree.t b/tests/test-narrow-tree.t deleted file mode 100644 --- a/tests/test-narrow-tree.t +++ /dev/null @@ -1,68 +0,0 @@ - $ cd $TESTDIR && python $RUNTESTDIR/run-tests.py \ - > --extra-config-opt experimental.treemanifest=1 test-narrow-narrow.t 2>&1 | \ - > grep -v 'unexpected mercurial lib' | egrep -v '\(expected' - - --- /*/tests/test-narrow-narrow.t (glob) - +++ /*/tests/test-narrow-narrow.t.err (glob) - @@ -\d+,\d+ \+\d+,\d+ @@ (re) - * (glob) - * (glob) - deleting data/d0/f.i - + deleting meta/d0/00manifest.i - $ hg log -T "{node|short}: {desc} {outsidenarrow}\n" - *: local change to d3 (glob) - *: add d10/f outsidenarrow (glob) - @@ -\d+,\d+ \+\d+,\d+ @@ (re) - looking for local changes to affected paths - saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob) - deleting data/d0/f.i - + deleting meta/d0/00manifest.i - Updates off of stripped commit if necessary - $ hg co -r 'desc("local change to d3")' -q - $ echo local change >> d6/f - @@ -\d+,\d+ \+\d+,\d+ @@ (re) - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob) - deleting data/d3/f.i - + deleting meta/d3/00manifest.i - $ hg log -T '{desc}\n' -r . - add d10/f - Updates to nullid if necessary - @@ -\d+,\d+
D1976: narrow: drop legacy support for getsubsetraw
durin42 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/D1976 AFFECTED FILES hgext/narrow/narrowbundle2.py CHANGE DETAILS diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -237,20 +237,13 @@ outgoing = exchange._computeoutgoing(repo, heads, common) if not outgoing.missing: return -if util.safehasattr(changegroup, 'getsubsetraw'): -# getsubsetraw was replaced with makestream in hg in 92f1e2be8ab6 -# (2017/09/10). -packer = changegroup.getbundler(version, repo) -packer._narrow_matcher = lambda : newmatch -cg = changegroup.getsubsetraw(repo, outgoing, packer, source) -else: -def wrappedgetbundler(orig, *args, **kwargs): -bundler = orig(*args, **kwargs) -bundler._narrow_matcher = lambda : newmatch -return bundler -with extensions.wrappedfunction(changegroup, 'getbundler', -wrappedgetbundler): -cg = changegroup.makestream(repo, outgoing, version, source) +def wrappedgetbundler(orig, *args, **kwargs): +bundler = orig(*args, **kwargs) +bundler._narrow_matcher = lambda : newmatch +return bundler +with extensions.wrappedfunction(changegroup, 'getbundler', +wrappedgetbundler): +cg = changegroup.makestream(repo, outgoing, version, source) part = bundler.newpart('changegroup', data=cg) part.addparam('version', version) if 'treemanifest' in repo.requirements: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1977: narrow: this code should assume REVIDX_FLAGS_ORDER exists
durin42 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/D1977 AFFECTED FILES hgext/narrow/narrowrevlog.py CHANGE DETAILS diff --git a/hgext/narrow/narrowrevlog.py b/hgext/narrow/narrowrevlog.py --- a/hgext/narrow/narrowrevlog.py +++ b/hgext/narrow/narrowrevlog.py @@ -15,9 +15,8 @@ ELLIPSIS_NODE_FLAG = 1 << 14 revlog.REVIDX_KNOWN_FLAGS |= ELLIPSIS_NODE_FLAG -if (util.safehasattr(revlog, 'REVIDX_FLAGS_ORDER') and -ELLIPSIS_NODE_FLAG not in revlog.REVIDX_FLAGS_ORDER): -revlog.REVIDX_FLAGS_ORDER.append(ELLIPSIS_NODE_FLAG) +if ELLIPSIS_NODE_FLAG not in revlog.REVIDX_FLAGS_ORDER: +revlog.REVIDX_FLAGS_ORDER.append(ELLIPSIS_NODE_FLAG) def readtransform(self, text): return text, False To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1978: narrow: assume addflagprocessor will always exist on revlog module
durin42 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/D1978 AFFECTED FILES hgext/narrow/narrowrevlog.py CHANGE DETAILS diff --git a/hgext/narrow/narrowrevlog.py b/hgext/narrow/narrowrevlog.py --- a/hgext/narrow/narrowrevlog.py +++ b/hgext/narrow/narrowrevlog.py @@ -27,9 +27,8 @@ def rawtransform(self, text): return False -if util.safehasattr(revlog, 'addflagprocessor'): -revlog.addflagprocessor(ELLIPSIS_NODE_FLAG, -(readtransform, writetransform, rawtransform)) +revlog.addflagprocessor(ELLIPSIS_NODE_FLAG, +(readtransform, writetransform, rawtransform)) def setup(): # We just wanted to add the flag processor, which is done at module To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1974: narrow: import experimental extension from narrowhg revision cb51d673e9c5
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Adjustments: - renamed src to hgext/narrow - marked extension experimental - added correct copyright header where it was missing - updated hgrc extension enable line in library.sh - renamed library.sh to narrow-library.sh - dropped all files from repo root as they're not interesting - dropped test-pyflakes.t, test-check-code.t and test-check-py3-compat.t - renamed remaining tests to all be test-narrow-* when they didn't already - fixed test-narrow-expanddirstate.t to refer to narrow and not narrowhg - fixed tests that wanted `update -C .` instead of `merge --abort` - corrected a two-space indent in narrowspec.py - added a missing _() in narrowcommands.py - fixed imports to pass the import checker - narrow only adds its --include and --exclude to clone if sparse isn't enabled to avoid breaking test-duplicateoptions.py. This is a kludge, and we'll need to come up with a better solution in the future. These were more or less the minimum to import something that would pass tests and not create a bunch of files we'll never use. Changes I intend to make as followups: - rework the test-narrow-*-tree.t tests to use the new testcases functionality in run-tests.py - remove lots of monkeypatches of core things REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1974 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowbundle2.py hgext/narrow/narrowchangegroup.py hgext/narrow/narrowcommands.py hgext/narrow/narrowcopies.py hgext/narrow/narrowdirstate.py hgext/narrow/narrowmerge.py hgext/narrow/narrowpatch.py hgext/narrow/narrowrepo.py hgext/narrow/narrowrevlog.py hgext/narrow/narrowspec.py hgext/narrow/narrowtemplates.py hgext/narrow/narrowwirepeer.py setup.py tests/narrow-library.sh tests/test-help.t tests/test-narrow-acl.t tests/test-narrow-archive.t tests/test-narrow-clone-no-ellipsis.t tests/test-narrow-clone-non-narrow-server.t tests/test-narrow-clone-nonlinear.t tests/test-narrow-clone.t tests/test-narrow-commit-tree.t tests/test-narrow-commit.t tests/test-narrow-copies.t tests/test-narrow-debugcommands.t tests/test-narrow-debugrebuilddirstate.t tests/test-narrow-exchange-merges.t tests/test-narrow-exchange.t tests/test-narrow-expanddirstate.t tests/test-narrow-merge-tree.t tests/test-narrow-merge.t tests/test-narrow-patch-tree.t tests/test-narrow-patch.t tests/test-narrow-patterns.t tests/test-narrow-pull.t tests/test-narrow-rebase.t tests/test-narrow-shallow-merges.t tests/test-narrow-shallow.t tests/test-narrow-strip-tree.t tests/test-narrow-strip.t tests/test-narrow-tree.t tests/test-narrow-update.t tests/test-narrow-widen-tree.t tests/test-narrow-widen.t tests/test-narrow.t To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1975: narrow: remove support for old match modules
durin42 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/D1975 AFFECTED FILES hgext/narrow/__init__.py CHANGE DETAILS diff --git a/hgext/narrow/__init__.py b/hgext/narrow/__init__.py --- a/hgext/narrow/__init__.py +++ b/hgext/narrow/__init__.py @@ -24,7 +24,6 @@ hg, localrepo, registrar, -util, verify as verifymod, ) @@ -85,15 +84,6 @@ narrowpatch.setup(repo) narrowwirepeer.reposetup(repo) -def _narrowvalidpath(orig, repo, path): -matcher = getattr(repo, 'narrowmatch', None) -if matcher is None: -return orig(repo, path) -matcher = matcher() -if matcher.visitdir(path) or matcher(path): -return orig(repo, path) -return False - def _verifierinit(orig, self, repo, matcher=None): # The verifier's matcher argument was desgined for narrowhg, so it should # be None from core. If another extension passes a matcher (unlikely), @@ -103,9 +93,6 @@ orig(self, repo, matcher) def extsetup(ui): -if util.safehasattr(verifymod, '_validpath'): -extensions.wrapfunction(verifymod, '_validpath', _narrowvalidpath) -else: -extensions.wrapfunction(verifymod.verifier, '__init__', _verifierinit) +extensions.wrapfunction(verifymod.verifier, '__init__', _verifierinit) extensions.wrapfunction(hg, 'postshare', narrowrepo.wrappostshare) extensions.wrapfunction(hg, 'copystore', narrowrepo.unsharenarrowspec) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1968: wireprotoserver: move sshserver into module (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHGe28ae1f4b194: wireprotoserver: move sshserver into module (API) (authored by indygreg, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D1968?vs=5048=5094#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1968?vs=5048=5094 REVISION DETAIL https://phab.mercurial-scm.org/D1968 AFFECTED FILES mercurial/commands.py mercurial/sshserver.py mercurial/wireprotoserver.py tests/test-sshserver.py CHANGE DETAILS diff --git a/tests/test-sshserver.py b/tests/test-sshserver.py --- a/tests/test-sshserver.py +++ b/tests/test-sshserver.py @@ -6,9 +6,9 @@ import silenttestrunner from mercurial import ( -sshserver, util, wireproto, +wireprotoserver, ) class SSHServerGetArgsTests(unittest.TestCase): @@ -29,7 +29,7 @@ def mockserver(inbytes): ui = mockui(inbytes) repo = mockrepo(ui) -return sshserver.sshserver(ui, repo) +return wireprotoserver.sshserver(ui, repo) class mockrepo(object): def __init__(self, ui): diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -8,9 +8,13 @@ import cgi import struct +import sys +from .i18n import _ from . import ( +encoding, error, +hook, pycompat, util, wireproto, @@ -197,3 +201,114 @@ req.respond(HTTP_OK, HGERRTYPE, body=rsp) return [] raise error.ProgrammingError('hgweb.protocol internal failure', rsp) + +class sshserver(wireproto.abstractserverproto): +def __init__(self, ui, repo): +self.ui = ui +self.repo = repo +self.lock = None +self.fin = ui.fin +self.fout = ui.fout +self.name = 'ssh' + +hook.redirect(True) +ui.fout = repo.ui.fout = ui.ferr + +# Prevent insertion/deletion of CRs +util.setbinary(self.fin) +util.setbinary(self.fout) + +def getargs(self, args): +data = {} +keys = args.split() +for n in xrange(len(keys)): +argline = self.fin.readline()[:-1] +arg, l = argline.split() +if arg not in keys: +raise error.Abort(_("unexpected parameter %r") % arg) +if arg == '*': +star = {} +for k in xrange(int(l)): +argline = self.fin.readline()[:-1] +arg, l = argline.split() +val = self.fin.read(int(l)) +star[arg] = val +data['*'] = star +else: +val = self.fin.read(int(l)) +data[arg] = val +return [data[k] for k in keys] + +def getarg(self, name): +return self.getargs(name)[0] + +def getfile(self, fpout): +self.sendresponse('') +count = int(self.fin.readline()) +while count: +fpout.write(self.fin.read(count)) +count = int(self.fin.readline()) + +def redirect(self): +pass + +def sendresponse(self, v): +self.fout.write("%d\n" % len(v)) +self.fout.write(v) +self.fout.flush() + +def sendstream(self, source): +write = self.fout.write +for chunk in source.gen: +write(chunk) +self.fout.flush() + +def sendpushresponse(self, rsp): +self.sendresponse('') +self.sendresponse(str(rsp.res)) + +def sendpusherror(self, rsp): +self.sendresponse(rsp.res) + +def sendooberror(self, rsp): +self.ui.ferr.write('%s\n-\n' % rsp.message) +self.ui.ferr.flush() +self.fout.write('\n') +self.fout.flush() + +def serve_forever(self): +try: +while self.serve_one(): +pass +finally: +if self.lock is not None: +self.lock.release() +sys.exit(0) + +handlers = { +str: sendresponse, +wireproto.streamres: sendstream, +wireproto.streamres_legacy: sendstream, +wireproto.pushres: sendpushresponse, +wireproto.pusherr: sendpusherror, +wireproto.ooberror: sendooberror, +} + +def serve_one(self): +cmd = self.fin.readline()[:-1] +if cmd and cmd in wireproto.commands: +rsp = wireproto.dispatch(self.repo, self, cmd) +self.handlers[rsp.__class__](self, rsp) +elif cmd: +impl = getattr(self, 'do_' + cmd, None) +if impl: +r = impl() +if r is not None: +self.sendresponse(r) +else: +self.sendresponse("") +return cmd != '' + +def _client(self): +client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] +return 'remote:ssh:' + client diff --git a/mercurial/sshserver.py
D1969: wireprotoserver: move abstractserverproto class from wireproto
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd34a01d55133: wireprotoserver: move abstractserverproto class from wireproto (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1969?vs=5049=5093 REVISION DETAIL https://phab.mercurial-scm.org/D1969 AFFECTED FILES mercurial/wireproto.py mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -31,6 +31,46 @@ HGTYPE2 = 'application/mercurial-0.2' HGERRTYPE = 'application/hg-error' +class abstractserverproto(object): +"""abstract class that summarizes the protocol API + +Used as reference and documentation. +""" + +def getargs(self, args): +"""return the value for arguments in + +returns a list of values (same order as )""" +raise NotImplementedError() + +def getfile(self, fp): +"""write the whole content of a file into a file like object + +The file is in the form:: + +(\n)+0\n + +chunk size is the ascii version of the int. +""" +raise NotImplementedError() + +def redirect(self): +"""may setup interception for stdout and stderr + +See also the `restore` method.""" +raise NotImplementedError() + +# If the `redirect` function does install interception, the `restore` +# function MUST be defined. If interception is not used, this function +# MUST NOT be defined. +# +# left commented here on purpose +# +#def restore(self): +#"""reinstall previous stdout and stderr and return intercepted stdout +#""" +#raise NotImplementedError() + def decodevaluefromheaders(req, headerprefix): """Decode a long value from multiple HTTP request headers. @@ -48,7 +88,7 @@ return ''.join(chunks) -class webproto(wireproto.abstractserverproto): +class webproto(abstractserverproto): def __init__(self, req, ui): self.req = req self.response = '' @@ -202,7 +242,7 @@ return [] raise error.ProgrammingError('hgweb.protocol internal failure', rsp) -class sshserver(wireproto.abstractserverproto): +class sshserver(abstractserverproto): def __init__(self, ui, repo): self.ui = ui self.repo = repo diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -41,46 +41,6 @@ 'IncompatibleClient') bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint) -class abstractserverproto(object): -"""abstract class that summarizes the protocol API - -Used as reference and documentation. -""" - -def getargs(self, args): -"""return the value for arguments in - -returns a list of values (same order as )""" -raise NotImplementedError() - -def getfile(self, fp): -"""write the whole content of a file into a file like object - -The file is in the form:: - -(\n)+0\n - -chunk size is the ascii version of the int. -""" -raise NotImplementedError() - -def redirect(self): -"""may setup interception for stdout and stderr - -See also the `restore` method.""" -raise NotImplementedError() - -# If the `redirect` function does install interception, the `restore` -# function MUST be defined. If interception is not used, this function -# MUST NOT be defined. -# -# left commented here on purpose -# -#def restore(self): -#"""reinstall previous stdout and stderr and return intercepted stdout -#""" -#raise NotImplementedError() - class remoteiterbatcher(peer.iterbatcher): def __init__(self, remote): super(remoteiterbatcher, self).__init__() 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
D1965: wireprotoserver: rename hgweb.protocol to wireprotoserver (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1aa42928bb47: wireprotoserver: rename hgweb.protocol to wireprotoserver (API) (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1965?vs=5045=5090 REVISION DETAIL https://phab.mercurial-scm.org/D1965 AFFECTED FILES mercurial/hgweb/hgweb_mod.py mercurial/hgweb/protocol.py mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/hgweb/protocol.py b/mercurial/wireprotoserver.py rename from mercurial/hgweb/protocol.py rename to mercurial/wireprotoserver.py --- a/mercurial/hgweb/protocol.py +++ b/mercurial/wireprotoserver.py @@ -1,4 +1,3 @@ -# # Copyright 21 May 2005 - (c) 2005 Jake Edge# Copyright 2005-2007 Matt Mackall # @@ -10,16 +9,16 @@ import cgi import struct -from .common import ( +from .hgweb.common import ( HTTP_OK, ) - -from .. import ( +from . import ( error, pycompat, util, wireproto, ) + stringio = util.stringio urlerr = util.urlerr diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -36,10 +36,10 @@ templater, ui as uimod, util, +wireprotoserver, ) from . import ( -protocol, webcommands, webutil, wsgicgi, @@ -362,13 +362,13 @@ # and the clients always use the old URL structure cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0]) -if protocol.iscmd(cmd): +if wireprotoserver.iscmd(cmd): try: if query: raise ErrorResponse(HTTP_NOT_FOUND) if cmd in perms: self.check_perm(rctx, req, perms[cmd]) -return protocol.call(rctx.repo, req, cmd) +return wireprotoserver.call(rctx.repo, req, cmd) except ErrorResponse as inst: # A client that sends unbundle without 100-continue will # break if we respond early. @@ -379,7 +379,7 @@ req.drain() else: req.headers.append((r'Connection', r'Close')) -req.respond(inst, protocol.HGTYPE, +req.respond(inst, wireprotoserver.HGTYPE, body='0\n%s\n' % inst) return '' 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
D1967: wireprotoserver: don't import symbol from hgweb.common
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa3a1ffcf5f8c: wireprotoserver: dont import symbol from hgweb.common (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1967?vs=5047=5092 REVISION DETAIL https://phab.mercurial-scm.org/D1967 AFFECTED FILES mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -9,9 +9,6 @@ import cgi import struct -from .hgweb.common import ( -HTTP_OK, -) from . import ( error, pycompat, @@ -24,6 +21,8 @@ urlerr = util.urlerr urlreq = util.urlreq +HTTP_OK = 200 + HGTYPE = 'application/mercurial-0.1' HGTYPE2 = 'application/mercurial-0.2' HGERRTYPE = 'application/hg-error' 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
D1966: wireprotoserver: rename call to callhttp
This revision was automatically updated to reflect the committed changes. Closed by commit rHG86196f91fee8: wireprotoserver: rename call to callhttp (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1966?vs=5046=5091 REVISION DETAIL https://phab.mercurial-scm.org/D1966 AFFECTED FILES mercurial/hgweb/hgweb_mod.py mercurial/wireprotoserver.py CHANGE DETAILS diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -146,7 +146,7 @@ def iscmd(cmd): return cmd in wireproto.commands -def call(repo, req, cmd): +def callhttp(repo, req, cmd): p = webproto(req, repo.ui) def genversion2(gen, engine, engineopts): diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -368,7 +368,7 @@ raise ErrorResponse(HTTP_NOT_FOUND) if cmd in perms: self.check_perm(rctx, req, perms[cmd]) -return wireprotoserver.call(rctx.repo, req, cmd) +return wireprotoserver.callhttp(rctx.repo, req, cmd) except ErrorResponse as inst: # A client that sends unbundle without 100-continue will # break if we respond early. 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
D1971: perf: add a perfunidiff command for benchmarking unified diff speed
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. Nice. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1971 To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1960: testrunner: make reading of test times work with #testcases
This revision was automatically updated to reflect the committed changes. Closed by commit rHG568917059243: testrunner: make reading of test times work with #testcases (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1960?vs=5034=5088 REVISION DETAIL https://phab.mercurial-scm.org/D1960 AFFECTED FILES tests/run-tests.py CHANGE DETAILS diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -2019,8 +2019,9 @@ try: with open(os.path.join(outputdir, b'.testtimes-')) as fp: for line in fp: -ts = line.split() -times.append((ts[0], [float(t) for t in ts[1:]])) +m = re.match('(.*?) ([0-9. ]+)', line) +times.append((m.group(1), + [float(t) for t in m.group(2).split()])) except IOError as err: if err.errno != errno.ENOENT: raise To: martinvonz, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1958: tests: allow [Errno] in output
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2f7ab4fb7711: tests: allow [Errno] in output (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1958?vs=5032=5087 REVISION DETAIL https://phab.mercurial-scm.org/D1958 AFFECTED FILES tests/test-clonebundles.t CHANGE DETAILS diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t --- a/tests/test-clonebundles.t +++ b/tests/test-clonebundles.t @@ -53,7 +53,7 @@ $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest $ hg clone http://localhost:$HGPORT 404-url applying clone bundle from http://does.not.exist/bundle.hg - error fetching bundle: (.* not known|No address associated with hostname) (re) (no-windows !) + error fetching bundle: (.* not known|(\[Errno -?\d+])? No address associated with hostname) (re) (no-windows !) error fetching bundle: [Errno 11004] getaddrinfo failed (windows !) abort: error applying bundle (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false") 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
D1961: testrunner: fix updating of .testtimes file
This revision was automatically updated to reflect the committed changes. Closed by commit rHG32675dbbec99: testrunner: fix updating of .testtimes file (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1961?vs=5035=5089 REVISION DETAIL https://phab.mercurial-scm.org/D1961 AFFECTED FILES tests/run-tests.py CHANGE DETAILS diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -2017,7 +2017,7 @@ def loadtimes(outputdir): times = [] try: -with open(os.path.join(outputdir, b'.testtimes-')) as fp: +with open(os.path.join(outputdir, b'.testtimes')) as fp: for line in fp: m = re.match('(.*?) ([0-9. ]+)', line) times.append((m.group(1), To: martinvonz, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1971: perf: add a perfunidiff command for benchmarking unified diff speed
durin42 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/D1971 AFFECTED FILES contrib/perf.py tests/test-contrib-perf.t CHANGE DETAILS diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t --- a/tests/test-contrib-perf.t +++ b/tests/test-contrib-perf.t @@ -114,6 +114,7 @@ perftags (no help text available) perftemplating (no help text available) + perfunidiff benchmark a unified diff between revisions perfvolatilesets benchmark the computation of various volatile set perfwalk (no help text available) @@ -126,6 +127,8 @@ $ hg perfannotate a $ hg perfbdiff -c 1 $ hg perfbdiff --alldata 1 + $ hg perfunidiff -c 1 + $ hg perfunidiff --alldata 1 $ hg perfbookmarks $ hg perfbranchmap $ hg perfcca diff --git a/contrib/perf.py b/contrib/perf.py --- a/contrib/perf.py +++ b/contrib/perf.py @@ -1031,6 +1031,71 @@ with ready: ready.notify_all() +@command('perfunidiff', revlogopts + formatteropts + [ +('', 'count', 1, 'number of revisions to test (when using --startrev)'), +('', 'alldata', False, 'test unidiffs for all associated revisions'), +], '-c|-m|FILE REV') +def perfunidiff(ui, repo, file_, rev=None, count=None, **opts): +"""benchmark a unified diff between revisions + +This doesn't include any copy tracing - it's just a unified diff +of the texts. + +By default, benchmark a diff between its delta parent and itself. + +With ``--count``, benchmark diffs between delta parents and self for N +revisions starting at the specified revision. + +With ``--alldata``, assume the requested revision is a changeset and +measure diffs for all changes related to that changeset (manifest +and filelogs). +""" +if opts['alldata']: +opts['changelog'] = True + +if opts.get('changelog') or opts.get('manifest'): +file_, rev = None, file_ +elif rev is None: +raise error.CommandError('perfunidiff', 'invalid arguments') + +textpairs = [] + +r = cmdutil.openrevlog(repo, 'perfunidiff', file_, opts) + +startrev = r.rev(r.lookup(rev)) +for rev in range(startrev, min(startrev + count, len(r) - 1)): +if opts['alldata']: +# Load revisions associated with changeset. +ctx = repo[rev] +mtext = repo.manifestlog._revlog.revision(ctx.manifestnode()) +for pctx in ctx.parents(): +pman = repo.manifestlog._revlog.revision(pctx.manifestnode()) +textpairs.append((pman, mtext)) + +# Load filelog revisions by iterating manifest delta. +man = ctx.manifest() +pman = ctx.p1().manifest() +for filename, change in pman.diff(man).items(): +fctx = repo.file(filename) +f1 = fctx.revision(change[0][0] or -1) +f2 = fctx.revision(change[1][0] or -1) +textpairs.append((f1, f2)) +else: +dp = r.deltaparent(rev) +textpairs.append((r.revision(dp), r.revision(rev))) + +def d(): +for left, right in textpairs: +# The date strings don't matter, so we pass empty strings. +headerlines, hunks = mdiff.unidiff( +left, '', right, '', 'left', 'right') +# consume iterators in roughly the way patch.py does +b'\n'.join(headerlines) +b''.join(sum((list(hlines) for hrange, hlines in hunks), [])) +timer, fm = gettimer(ui, opts) +timer(d) +fm.end() + @command('perfdiffwd', formatteropts) def perfdiffwd(ui, repo, **opts): """Profile diff of working directory changes""" To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1973: bdiff: write a native version of splitnewlines
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY ./hg perfunidiff mercurial/manifest.py 0 --count 500 --profile before: ! wall 0.309280 comb 0.35 user 0.29 sys 0.06 (best of 32) ./hg perfunidiff mercurial/manifest.py 0 --count 500 --profile after: ! wall 0.241572 comb 0.26 user 0.24 sys 0.02 (best of 39) so it's about 20% faster. I hate Python. I wish we could usefully write this in Rust, but it doesn't look like that's realistic without using the cpython crate, which I'd still like to avoid. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1973 AFFECTED FILES mercurial/cext/bdiff.c mercurial/mdiff.py CHANGE DETAILS diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -40,6 +40,8 @@ lines[-1] = lines[-1][:-1] return lines +splitnewlines = getattr(bdiff, 'splitnewlines', splitnewlines) + class diffopts(object): '''context is the number of context lines text treats all files as text diff --git a/mercurial/cext/bdiff.c b/mercurial/cext/bdiff.c --- a/mercurial/cext/bdiff.c +++ b/mercurial/cext/bdiff.c @@ -182,13 +182,64 @@ return result ? result : PyErr_NoMemory(); } +bool sliceintolist(PyObject *list, Py_ssize_t destidx, + const char *source, Py_ssize_t len) { + PyObject *sliced = PyString_FromStringAndSize(source, len); + if (sliced == NULL) + return false; + PyList_SetItem(list, destidx, sliced); + return true; +} + +static PyObject *splitnewlines(PyObject *self, PyObject *args) +{ + const char *text; + int i, start = 0; + Py_ssize_t nelts = 0, size; + PyObject *result; + + if (!PyArg_ParseTuple(args, "s#", , )) + goto abort; + if (!size) { + return PyList_New(0); + } + /* This loops to size-1 because if the last byte is a newline, +* we don't want to perform a split there. */ + for (i = 0; i < size - 1; ++i) { + if (text[i] == '\n') { + ++nelts; + } + } + if ((result = PyList_New(nelts+1)) == NULL) + goto abort; + nelts = 0; + for (i = 0; i < size - 1; ++i) { + if (text[i] == '\n') { + if (!sliceintolist( + result, nelts++, text+start, i-start+1)) + goto abort; + start = i+1; + } + } + if (start < size) { + if (!sliceintolist(result, nelts++, text+start, size-start)) + goto abort; + } + return result; +abort: + Py_XDECREF(result); + return NULL; +} + static char mdiff_doc[] = "Efficient binary diff."; static PyMethodDef methods[] = { {"bdiff", bdiff, METH_VARARGS, "calculate a binary diff\n"}, {"blocks", blocks, METH_VARARGS, "find a list of matching lines\n"}, {"fixws", fixws, METH_VARARGS, "normalize diff whitespaces\n"}, + {"splitnewlines", splitnewlines, METH_VARARGS, +"like str.splitlines, but only split on newlines\n"}, {NULL, NULL} }; To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1972: tests: start a set of unit tests for mdiff.py, starting with splitnewlines
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I want to optimize splitnewlines, so writing tests seems prudent. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1972 AFFECTED FILES tests/test-mdiff.py CHANGE DETAILS diff --git a/tests/test-mdiff.py b/tests/test-mdiff.py new file mode 100644 --- /dev/null +++ b/tests/test-mdiff.py @@ -0,0 +1,24 @@ +from __future__ import absolute_import +from __future__ import print_function + +import unittest + +from mercurial import ( +mdiff, +) + +class splitnewlinesTests(unittest.TestCase): + +def test_splitnewlines(self): +cases = {'a\nb\nc\n': ['a\n', 'b\n', 'c\n'], + 'a\nb\nc': ['a\n', 'b\n', 'c'], + 'a\nb\nc\n\n': ['a\n', 'b\n', 'c\n', '\n'], + '': [], + 'abcabc': ['abcabc'], + } +for inp, want in cases.iteritems(): +self.assertEqual(mdiff.splitnewlines(inp), want) + +if __name__ == '__main__': +import silenttestrunner +silenttestrunner.main(__name__) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1940: patch: avoid repeated binary checks if all files in a patch are text
This revision was automatically updated to reflect the committed changes. Closed by commit rHG079b27b5a869: patch: avoid repeated binary checks if all files in a patch are text (authored by joerg.sonnenberger, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1940?vs=5006=5081 REVISION DETAIL https://phab.mercurial-scm.org/D1940 AFFECTED FILES mercurial/mdiff.py mercurial/patch.py CHANGE DETAILS diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -2698,8 +2698,13 @@ if opts.git or losedatafn: flag2 = ctx2.flags(f2) # if binary is True, output "summary" or "base85", but not "text diff" -binary = not opts.text and any(f.isbinary() - for f in [fctx1, fctx2] if f is not None) +if opts.text: +check_binary = True +binary = False +else: +check_binary = any(f.isbinary() + for f in [fctx1, fctx2] if f is not None) +binary = check_binary if losedatafn and not opts.git: if (binary or @@ -2789,7 +2794,8 @@ uheaders, hunks = mdiff.unidiff(content1, date1, content2, date2, -path1, path2, opts=opts) +path1, path2, opts=opts, +check_binary=check_binary) header.extend(uheaders) yield fctx1, fctx2, header, hunks diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -234,13 +234,16 @@ yield s, type yield s1, '=' -def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts): +def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts, check_binary=True): """Return a unified diff as a (headers, hunks) tuple. If the diff is not null, `headers` is a list with unified diff header lines "--- " and "+++ " and `hunks` is a generator yielding (hunkrange, hunklines) coming from _unidiff(). Otherwise, `headers` and `hunks` are empty. + +Setting `check_binary` to false will skip the binary check, i.e. when +it has been done in advance. Files are expected to be text in this case. """ def datetag(date, fn=None): if not opts.git and not opts.nodates: @@ -270,7 +273,7 @@ text += "\n\ No newline at end of file\n" yield text -if not opts.text and (util.binary(a) or util.binary(b)): +if not opts.text and check_binary and (util.binary(a) or util.binary(b)): if a and b and len(a) == len(b) and a == b: return sentinel headerlines = [] To: joerg.sonnenberger, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1942: mdiff: remove rewindhunk by yielding a bool first to indicate data
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6a33e81e4c5e: mdiff: remove rewindhunk by yielding a bool first to indicate data (authored by joerg.sonnenberger, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1942?vs=5009=5083 REVISION DETAIL https://phab.mercurial-scm.org/D1942 AFFECTED FILES mercurial/mdiff.py CHANGE DETAILS diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -307,22 +307,14 @@ hunklines.append(_missing_newline_marker) hunks = (hunkrange, hunklines), else: -diffhunks = _unidiff(a, b, opts=opts) -try: -hunkrange, hunklines = next(diffhunks) -except StopIteration: +hunks = _unidiff(a, b, opts=opts) +if not next(hunks): return sentinel headerlines = [ "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)), "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)), ] -def rewindhunks(): -yield hunkrange, hunklines -for hr, hl in diffhunks: -yield hr, hl - -hunks = rewindhunks() return headerlines, hunks @@ -414,6 +406,7 @@ # hunk = None ignoredlines = 0 +has_hunks = False for s, stype in allblocks(t1, t2, opts, l1, l2): a1, a2, b1, b2 = s if stype != '!': @@ -440,6 +433,9 @@ astart = hunk[1] bstart = hunk[3] else: +if not has_hunks: +has_hunks = True +yield True for x in yieldhunk(hunk): yield x if prev: @@ -456,8 +452,13 @@ delta[len(delta):] = ['+' + x for x in new] if hunk: +if not has_hunks: +has_hunks = True +yield True for x in yieldhunk(hunk): yield x +elif not has_hunks: +yield False def b85diff(to, tn): '''print base85-encoded binary diff''' 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
D1941: mdiff: explicitly compute places for the newline marker
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa9d07bd8f758: mdiff: explicitly compute places for the newline marker (authored by joerg.sonnenberger, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1941?vs=5008=5082 REVISION DETAIL https://phab.mercurial-scm.org/D1941 AFFECTED FILES mercurial/mdiff.py CHANGE DETAILS diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -19,6 +19,8 @@ util, ) +_missing_newline_marker = "\\ No newline at end of file\n" + bdiff = policy.importmod(r'bdiff') mpatch = policy.importmod(r'mpatch') @@ -267,18 +269,13 @@ fn1 = util.pconvert(fn1) fn2 = util.pconvert(fn2) -def checknonewline(lines): -for text in lines: -if text[-1:] != '\n': -text += "\n\ No newline at end of file\n" -yield text - if not opts.text and check_binary and (util.binary(a) or util.binary(b)): if a and b and len(a) == len(b) and a == b: return sentinel headerlines = [] hunks = (None, ['Binary file %s has changed\n' % fn1]), elif not a: +without_newline = b[-1] != '\n' b = splitnewlines(b) if a is None: l1 = '--- /dev/null%s' % datetag(epoch) @@ -289,8 +286,12 @@ size = len(b) hunkrange = (0, 0, 1, size) hunklines = ["@@ -0,0 +1,%d @@\n" % size] + ["+" + e for e in b] -hunks = (hunkrange, checknonewline(hunklines)), +if without_newline: +hunklines[-1] += '\n' +hunklines.append(_missing_newline_marker) +hunks = (hunkrange, hunklines), elif not b: +without_newline = a[-1] != '\n' a = splitnewlines(a) l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) if b is None: @@ -301,7 +302,10 @@ size = len(a) hunkrange = (1, size, 0, 0) hunklines = ["@@ -1,%d +0,0 @@\n" % size] + ["-" + e for e in a] -hunks = (hunkrange, checknonewline(hunklines)), +if without_newline: +hunklines[-1] += '\n' +hunklines.append(_missing_newline_marker) +hunks = (hunkrange, hunklines), else: diffhunks = _unidiff(a, b, opts=opts) try: @@ -314,9 +318,9 @@ "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)), ] def rewindhunks(): -yield hunkrange, checknonewline(hunklines) +yield hunkrange, hunklines for hr, hl in diffhunks: -yield hr, checknonewline(hl) +yield hr, hl hunks = rewindhunks() @@ -330,6 +334,8 @@ form the '@@ -s1,l1 +s2,l2 @@' header and `hunklines` is a list of lines of the hunk combining said header followed by line additions and deletions. + +The hunks are prefixed with a bool. """ l1 = splitnewlines(t1) l2 = splitnewlines(t2) @@ -380,6 +386,26 @@ + delta + [' ' + l1[x] for x in xrange(a2, aend)] ) +# If either file ends without a newline and the last line of +# that file is part of a hunk, a marker is printed. If the +# last line of both files is identical and neither ends in +# a newline, print only one marker. That's the only case in +# which the hunk can end in a shared line without a newline. +skip = False +if t1[-1] != '\n' and astart + alen == len(l1) + 1: +for i in xrange(len(hunklines) - 1, -1, -1): +if hunklines[i][0] in ('-', ' '): +if hunklines[i][0] == ' ': +skip = True +hunklines[i] += '\n' +hunklines.insert(i + 1, _missing_newline_marker) +break +if not skip and t2[-1] != '\n' and bstart + blen == len(l2) + 1: +for i in xrange(len(hunklines) - 1, -1, -1): +if hunklines[i][0] == '+': +hunklines[i] += '\n' +hunklines.insert(i + 1, _missing_newline_marker) +break yield hunkrange, hunklines # bdiff.blocks gives us the matching sequences in the files. The loop To: joerg.sonnenberger, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1970: contrib: fix dirstatenonnormalcheck to work in Python 3
durin42 updated this revision to Diff 5080. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1970?vs=5079=5080 REVISION DETAIL https://phab.mercurial-scm.org/D1970 AFFECTED FILES contrib/dirstatenonnormalcheck.py mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1237,9 +1237,12 @@ util.clearcachedproperty(self, "nonnormalset") util.clearcachedproperty(self, "otherparentset") -def iteritems(self): +def items(self): return self._map.iteritems() +# forward for python2,3 compat +iteritems = items + def __len__(self): return len(self._map) diff --git a/contrib/dirstatenonnormalcheck.py b/contrib/dirstatenonnormalcheck.py --- a/contrib/dirstatenonnormalcheck.py +++ b/contrib/dirstatenonnormalcheck.py @@ -17,32 +17,32 @@ """Compute nonnormal entries from dirstate's dmap""" res = set() for f, e in dmap.iteritems(): -if e[0] != 'n' or e[3] == -1: +if e[0] != b'n' or e[3] == -1: res.add(f) return res def checkconsistency(ui, orig, dmap, _nonnormalset, label): """Compute nonnormalset from dmap, check that it matches _nonnormalset""" nonnormalcomputedmap = nonnormalentries(dmap) if _nonnormalset != nonnormalcomputedmap: -ui.develwarn("%s call to %s\n" % (label, orig), config='dirstate') -ui.develwarn("inconsistency in nonnormalset\n", config='dirstate') -ui.develwarn("[nonnormalset] %s\n" % _nonnormalset, config='dirstate') -ui.develwarn("[map] %s\n" % nonnormalcomputedmap, config='dirstate') +ui.develwarn(b"%s call to %s\n" % (label, orig), config=b'dirstate') +ui.develwarn(b"inconsistency in nonnormalset\n", config=b'dirstate') +ui.develwarn(b"[nonnormalset] %s\n" % _nonnormalset, config=b'dirstate') +ui.develwarn(b"[map] %s\n" % nonnormalcomputedmap, config=b'dirstate') def _checkdirstate(orig, self, arg): """Check nonnormal set consistency before and after the call to orig""" checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, - "before") + b"before") r = orig(self, arg) -checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, "after") +checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, b"after") return r def extsetup(ui): """Wrap functions modifying dirstate to check nonnormalset consistency""" dirstatecl = dirstate.dirstate -devel = ui.configbool('devel', 'all-warnings') -paranoid = ui.configbool('experimental', 'nonnormalparanoidcheck') +devel = ui.configbool(b'devel', b'all-warnings') +paranoid = ui.configbool(b'experimental', b'nonnormalparanoidcheck') if devel: extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate) if paranoid: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1905: strip: use in-place revset formatspec instead of %-formatting ourselves
martinvonz added inline comments. INLINE COMMENTS > martinvonz wrote in strip.py:218 > I would expect "%d" with a revision number (such as uctx.rev()). I saw that > that's also what Yuya suggested on https://phab.mercurial-scm.org/D1884. > Fixing in flight. Oh, that's done in the next patch :P REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1905 To: durin42, #hg-reviewers, pulkit, indygreg Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1905: strip: use in-place revset formatspec instead of %-formatting ourselves
martinvonz added inline comments. INLINE COMMENTS > strip.py:218 > # between the working context and uctx > -descendantrevs = repo.revs("%s::." % uctx.rev()) > +descendantrevs = repo.revs("%s::.", uctx.rev()) > changedfiles = [] I would expect "%d" with a revision number (such as uctx.rev()). I saw that that's also what Yuya suggested on https://phab.mercurial-scm.org/D1884. Fixing in flight. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1905 To: durin42, #hg-reviewers, pulkit, indygreg Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@35821: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/34287c2e3fc4 changeset: 35821:34287c2e3fc4 bookmark:@ tag: tip parent: 35793:4fb2bb61597c parent: 35820:1d60ad093792 user:Augie Facklerdate:Thu Feb 01 14:28:45 2018 -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
D1970: contrib: fix dirstatenonnormalcheck to work in Python 3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is a redo of https://phab.mercurial-scm.org/D1963 that has the added benefit of not breaking Python 2. Oops. 1. skip-blame because this is bytes prefixes and a s/iteritems/items/ REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1970 AFFECTED FILES contrib/dirstatenonnormalcheck.py mercurial/dirstate.py CHANGE DETAILS diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1237,9 +1237,12 @@ util.clearcachedproperty(self, "nonnormalset") util.clearcachedproperty(self, "otherparentset") -def iteritems(self): +def items(self): return self._map.iteritems() +# forward for python2,3 compat +iteritems = items + def __len__(self): return len(self._map) diff --git a/contrib/dirstatenonnormalcheck.py b/contrib/dirstatenonnormalcheck.py --- a/contrib/dirstatenonnormalcheck.py +++ b/contrib/dirstatenonnormalcheck.py @@ -17,32 +17,32 @@ """Compute nonnormal entries from dirstate's dmap""" res = set() for f, e in dmap.iteritems(): -if e[0] != 'n' or e[3] == -1: +if e[0] != b'n' or e[3] == -1: res.add(f) return res def checkconsistency(ui, orig, dmap, _nonnormalset, label): """Compute nonnormalset from dmap, check that it matches _nonnormalset""" nonnormalcomputedmap = nonnormalentries(dmap) if _nonnormalset != nonnormalcomputedmap: -ui.develwarn("%s call to %s\n" % (label, orig), config='dirstate') -ui.develwarn("inconsistency in nonnormalset\n", config='dirstate') -ui.develwarn("[nonnormalset] %s\n" % _nonnormalset, config='dirstate') -ui.develwarn("[map] %s\n" % nonnormalcomputedmap, config='dirstate') +ui.develwarn(b"%s call to %s\n" % (label, orig), config=b'dirstate') +ui.develwarn(b"inconsistency in nonnormalset\n", config=b'dirstate') +ui.develwarn(b"[nonnormalset] %s\n" % _nonnormalset, config=b'dirstate') +ui.develwarn(b"[map] %s\n" % nonnormalcomputedmap, config=b'dirstate') def _checkdirstate(orig, self, arg): """Check nonnormal set consistency before and after the call to orig""" checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, - "before") + b"before") r = orig(self, arg) -checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, "after") +checkconsistency(self._ui, orig, self._map, self._map.nonnormalset, b"after") return r def extsetup(ui): """Wrap functions modifying dirstate to check nonnormalset consistency""" dirstatecl = dirstate.dirstate -devel = ui.configbool('devel', 'all-warnings') -paranoid = ui.configbool('experimental', 'nonnormalparanoidcheck') +devel = ui.configbool(b'devel', b'all-warnings') +paranoid = ui.configbool(b'experimental', b'nonnormalparanoidcheck') if devel: extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate) if paranoid: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1962: setdiscovery: don't call "heads" wire command when heads specified
This revision was automatically updated to reflect the committed changes. Closed by commit rHG98b746a1ebe3: setdiscovery: dont call heads wire command when heads specified (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1962?vs=5036=5078 REVISION DETAIL https://phab.mercurial-scm.org/D1962 AFFECTED FILES mercurial/discovery.py mercurial/setdiscovery.py CHANGE DETAILS diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py +++ b/mercurial/setdiscovery.py @@ -130,7 +130,7 @@ sample = set(random.sample(sample, desiredlen)) return sample -def findcommonheads(ui, local, remote, +def findcommonheads(ui, local, remote, heads=None, initialsamplesize=100, fullsamplesize=200, abortwhenunrelated=True, @@ -155,11 +155,15 @@ sample = _limitsample(ownheads, initialsamplesize) # indices between sample and externalized version must match sample = list(sample) -batch = remote.iterbatch() -batch.heads() -batch.known(dag.externalizeall(sample)) -batch.submit() -srvheadhashes, yesno = batch.results() +if heads: +srvheadhashes = heads +yesno = remote.known(dag.externalizeall(sample)) +else: +batch = remote.iterbatch() +batch.heads() +batch.known(dag.externalizeall(sample)) +batch.submit() +srvheadhashes, yesno = batch.results() if cl.tip() == nullid: if srvheadhashes != [nullid]: diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -62,7 +62,7 @@ if allknown: return (heads, False, heads) -res = setdiscovery.findcommonheads(repo.ui, repo, remote, +res = setdiscovery.findcommonheads(repo.ui, repo, remote, heads, abortwhenunrelated=not force, ancestorsof=ancestorsof) common, anyinc, srvheads = res To: martinvonz, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1962: setdiscovery: don't call "heads" wire command when heads specified
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. I initially thought this would have test fallout. But since we're using a batch command to issue the `heads` wire protocol command, it won't show up in HTTP logs. We'd only catch it in verbose/debug logging, which we don't do a lot of. So no test fallout is expected. FWIW, while computing DAG heads is probably cheap, sending them over the wire may not be. 41 bytes per head can add up pretty quickly and turn what would be a <1kb response into several kb. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1962 To: martinvonz, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1959: testrunner: on error, color the "(case xxx)" part the same as filename
This revision was automatically updated to reflect the committed changes. Closed by commit rHG81c3ad368574: testrunner: on error, color the (case xxx) part the same as filename (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1959?vs=5033=5077 REVISION DETAIL https://phab.mercurial-scm.org/D1959 AFFECTED FILES tests/run-tests.py CHANGE DETAILS diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -120,18 +120,19 @@ } class TestRunnerLexer(lexer.RegexLexer): +testpattern = r'[\w-]+\.(t|py)( \(case [\w-]+\))?' tokens = { 'root': [ (r'^Skipped', token.Generic.Skipped, 'skipped'), (r'^Failed ', token.Generic.Failed, 'failed'), (r'^ERROR: ', token.Generic.Failed, 'failed'), ], 'skipped': [ -(r'[\w-]+\.(t|py)', token.Generic.SName), +(testpattern, token.Generic.SName), (r':.*', token.Generic.Skipped), ], 'failed': [ -(r'[\w-]+\.(t|py)', token.Generic.FName), +(testpattern, token.Generic.FName), (r'(:| ).*', token.Generic.Failed), ] } To: martinvonz, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1903: mq: use bytes() instead of str() to encode statusentries for writing
This revision was automatically updated to reflect the committed changes. Closed by commit rHG577a4d267e0f: mq: use bytes() instead of str() to encode statusentries for writing (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1903?vs=4910=5073 REVISION DETAIL https://phab.mercurial-scm.org/D1903 AFFECTED FILES hgext/mq.py CHANGE DETAILS diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -700,7 +700,7 @@ fp.write("%s\n" % i) fp.close() if self.applieddirty: -writelist(map(str, self.applied), self.statuspath) +writelist(map(bytes, self.applied), self.statuspath) self.applieddirty = False if self.seriesdirty: writelist(self.fullseries, self.seriespath) To: durin42, #hg-reviewers, indygreg Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1908: python3: whitelist an additional 23 passing tests
This revision was automatically updated to reflect the committed changes. Closed by commit rHG94e124e3db1e: python3: whitelist an additional 23 passing tests (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1908?vs=4913=5076 REVISION DETAIL https://phab.mercurial-scm.org/D1908 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 @@ -1,14 +1,17 @@ test-add.t test-addremove-similar.t test-addremove.t +test-amend-subrepo.t test-ancestor.py test-automv.t test-backwards-remove.t test-bheads.t test-bisect2.t test-bookmarks-merge.t test-bookmarks-strip.t +test-branch-option.t test-branch-tag-confict.t +test-bundle-vs-outgoing.t test-casecollision.t test-cat.t test-changelog-exec.t @@ -19,13 +22,16 @@ test-check-pylint.t test-check-shbang.t test-children.t +test-clone-r.t +test-clone-update-order.t test-commit-unresolved.t test-completion.t test-confused-revert.t test-contrib-check-code.t test-contrib-check-commit.t test-debugindexdot.t test-debugrename.t +test-diff-change.t test-diff-copy-depth.t test-diff-hashes.t test-diff-issue2761.t @@ -40,31 +46,41 @@ test-duplicateoptions.py test-empty-dir.t test-empty-file.t +test-empty-group.t test-empty.t test-encoding-func.py test-excessive-merge.t test-execute-bit.t test-filebranch.t +test-flags.t +test-generaldelta.t +test-glog-topological.t test-gpg.t test-hghave.t test-imports-checker.t +test-inherit-mode.t test-issue1089.t test-issue1175.t +test-issue1306.t test-issue1502.t test-issue1802.t test-issue1877.t test-issue1993.t test-issue522.t +test-issue586.t test-issue612.t test-issue619.t test-issue672.t test-issue842.t test-journal-exists.t test-locate.t +test-logexchange.t test-lrucachedict.py +test-manifest-merging.t test-manifest.py -test-manifest-merging.t +test-manifest.t test-match.py +test-merge-commit.t test-merge-default.t test-merge-internal-tools-pattern.t test-merge-local.t @@ -81,8 +97,11 @@ test-merge8.t test-mq-qimport-fail-cleanup.t test-obshistory.t +test-obsolete-checkheads.t test-parents.t test-permissions.t +test-pull-branch.t +test-pull-permission.t test-push-checkheads-partial-C1.t test-push-checkheads-partial-C2.t test-push-checkheads-partial-C3.t @@ -110,6 +129,7 @@ test-push-checkheads-unpushed-D5.t test-push-checkheads-unpushed-D6.t test-push-checkheads-unpushed-D7.t +test-push-warn.t test-record.t test-rename-after-merge.t test-rename-dir-merge.t @@ -120,6 +140,7 @@ test-revlog-group-emptyiter.t test-revlog-mmapindex.t test-revlog-packentry.t +test-revset-outgoing.t test-run-tests.py test-show-stack.t test-simple-update.t @@ -129,9 +150,12 @@ test-sparse-requirement.t test-sparse-verbose-json.t test-status-terse.t +test-strip-cross.t test-uncommit.t test-unified-test.t test-unrelated-pull.t +test-up-local-change.t +test-update-dest.t test-update-issue1456.t test-update-names.t test-update-reverse.t To: durin42, pulkit, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1902: mq: open status file et al in bytes mode
This revision was automatically updated to reflect the committed changes. Closed by commit rHG177eb3847a0a: mq: open status file et al in bytes mode (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1902?vs=4909=5072 REVISION DETAIL https://phab.mercurial-scm.org/D1902 AFFECTED FILES hgext/mq.py CHANGE DETAILS diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -695,7 +695,7 @@ def savedirty(self): def writelist(items, path): -fp = self.opener(path, 'w') +fp = self.opener(path, 'wb') for i in items: fp.write("%s\n" % i) fp.close() To: durin42, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1901: mq: fix up statusentry to be both repr()-able and bytes()-able
This revision was automatically updated to reflect the committed changes. Closed by commit rHG0ba365937220: mq: fix up statusentry to be both repr()-able and bytes()-able (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1901?vs=4908=5071 REVISION DETAIL https://phab.mercurial-scm.org/D1901 AFFECTED FILES hgext/mq.py CHANGE DETAILS diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -148,9 +148,13 @@ class statusentry(object): def __init__(self, node, name): self.node, self.name = node, name -def __repr__(self): + +def __bytes__(self): return hex(self.node) + ':' + self.name +__str__ = encoding.strmethod(__bytes__) +__repr__ = encoding.strmethod(__bytes__) + # The order of the headers in 'hg export' HG patches: HGHEADERS = [ # '# HG changeset patch', To: durin42, #hg-reviewers, pulkit, indygreg Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1907: tests: fix a missed b prefix in a test extension in test-strip.t
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd5030224cada: tests: fix a missed b prefix in a test extension in test-strip.t (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1907?vs=4953=5075 REVISION DETAIL https://phab.mercurial-scm.org/D1907 AFFECTED FILES tests/test-strip.t CHANGE DETAILS diff --git a/tests/test-strip.t b/tests/test-strip.t --- a/tests/test-strip.t +++ b/tests/test-strip.t @@ -899,7 +899,7 @@ > transaction = orig(repo, desc, *args, **kwargs) > # warm up the phase cache > list(repo.revs(b"not public()")) - > if desc != 'strip': + > if desc != b'strip': > transaction.addpostclose(b"phase invalidation test", test) > return transaction > def extsetup(ui): To: durin42, #hg-reviewers, pulkit, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1906: revlog: correct type in check to verify rawtext is immutable
This revision was automatically updated to reflect the committed changes. Closed by commit rHG24dd168d712a: revlog: correct type in check to verify rawtext is immutable (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1906?vs=4952=5074 REVISION DETAIL https://phab.mercurial-scm.org/D1906 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 @@ -2099,7 +2099,7 @@ if alwayscache and rawtext is None: rawtext = deltacomputer._buildtext(revinfo, fh) -if type(rawtext) == str: # only accept immutable objects +if type(rawtext) == bytes: # only accept immutable objects self._cache = (node, curr, rawtext) self._chainbasecache[curr] = chainbase return node To: durin42, indygreg, #hg-reviewers, pulkit Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel