[PATCH] tests: exclude bundled pywatchman from check-code test
# HG changeset patch # User David Soria Parra# Date 1482294521 28800 # Tue Dec 20 20:28:41 2016 -0800 # Node ID 26a5b7f91ec50d20782816b83841bd8087478eb0 # Parent b090cdf0e161af0ac6768cb404cc0e51bb0baf00 tests: exclude bundled pywatchman from check-code test pywatchman is imported from upstream and therefore fails to pass linting. We have added 'no-check-code' manually to every file in the past. This is cumbersome and modifies upstream sources. diff --git a/tests/test-check-code.t b/tests/test-check-code.t --- a/tests/test-check-code.t +++ b/tests/test-check-code.t @@ -7,13 +7,8 @@ New errors are not allowed. Warnings are strongly discouraged. (The writing "no-che?k-code" is for not skipping this file when checking.) - $ hg locate -X contrib/python-zstandard | sed 's-\\-/-g' | - > xargs "$check_code" --warnings --per-file=0 || false - Skipping hgext/fsmonitor/pywatchman/__init__.py it has no-che?k-code (glob) - Skipping hgext/fsmonitor/pywatchman/bser.c it has no-che?k-code (glob) - Skipping hgext/fsmonitor/pywatchman/capabilities.py it has no-che?k-code (glob) - Skipping hgext/fsmonitor/pywatchman/msc_stdint.h it has no-che?k-code (glob) - Skipping hgext/fsmonitor/pywatchman/pybser.py it has no-che?k-code (glob) + $ hg locate -X contrib/python-zstandard -X hgext/fsmonitor/pywatchman | + > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 || false Skipping i18n/polib.py it has no-che?k-code (glob) Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob) Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] match: adding non-recursive directory matching
On Tue, Dec 20, 2016 at 5:47 AM, Pierre-Yves David < pierre-yves.da...@ens-lyon.org> wrote: > > > On 12/20/2016 06:00 AM, Rodrigo Damazio wrote: > >> Unfortunately, while set would match the right files, because of the way >> the code is structured, it provides no way to not try visiting the >> directories inside the non-recursive match - the set needs to first >> collect all the files in all subdirectories (match.py, _expandset) and >> then filter that down to the desired ones. In plain hg repos, that's >> just much slower - in the context of narrowhg, the repo will simply not >> have the manifests for those subdirectories and trying to visit them >> will crash. >> > > Okay, so this seems like the current tools allow you to specify the right > request but shortcoming of the -implementation- are preventing that request > to work probably with narrowhg (and have performance impacts) > > Did I got that right ? Yes. The follow-up change to this one (which I haven't sent yet but is >> written) is updating visitdir to allow non-recursiveness, which btw >> makes something like "hg files -I rootglob:browser/*" about 4-5x faster >> in the firefox repo. >> > > And, If I read you right, the implementation of 'rootglob:' you provided > in your patch have the same implementation issue, but you have another > patch to improve the implementation to behave a way you can use (and is > faster). > > Did I got that right too ? > Yes. If I got these two pieces right, it looks like we could just apply the > improvement to 'visitdir' to 'set:your/glob/*' and have your usecase filled > while not jumping into UI changes. Would that work for you ? > Not without a third set of changes, since set expansion doesn't use visitdir (or the matcher being built) at all - the dependency is that building the matcher depends on expanding the set (and thus the set can't depend on the matcher). It would technically be doable for re:, but I'm wary of getting into the business of parsing and special-casing regexes to assume what they match or don't. > On Fri, Dec 16, 2016 at 6:21 AM, Pierre-Yves David >>> >> wrote: >> >> >> >> On 12/16/2016 02:19 AM, Augie Fackler wrote: >> >> >> On Nov 24, 2016, at 10:28 AM, FUJIWARA Katsunori >> > wrote: >> >> Yes, "files:" was the original version of this patch >> and the case I really >> care about :) I changed it to rootglob after your >> comments. >> Which way would be preferred to move forward? >> >> >> "files:" is "path:" family, and "rootglob:" is "glob:" >> family. As we >> concluded before, "path:" itself can't control recursion of >> matching >> well. >> >> Therefore, I think that "files:" should be implemented if >> needed, >> regardless of implementing "rootglob:". >> >> Of course, we need high point view of this area, at first :-) >> >> >> BTW, it is a little ambiguous (at least, for me) that >> "files:foo" >> matches against both file "foo" and files just under directory >> "foo". Name other than "files:" may resolve this ambiguity, >> but I >> don't have any better (and short enough) name :-< >> >> == === === >> patternfoo foo/bar foo/bar/baz >> == === === >> path:fooo o o >> >> files:foo o o x >> >> file:fooo x x >> dir:foo x o o >> == === === >> >> >> Scanning the plan page, I see that there’s a *lot* of work that >> could be done and no consensus as yet, but that the only >> immediate use case seems to be the rootfile/rootglob case. Is >> there some path forward we could agree on that would unblock >> those immediate needs for narrowhg and not make things harder in >> the future? >> >> Alternatively, would we be okay with a slight refactor of the >> matcher so that narrowhg can introduce a custom filesonly: >> matcher for the time being so we can keep making forward >> progress there? I don’t know the matcher code well enough to be >> able to guess if this is a reasonable path so we can be unblocked. >> >> (It’s very hard for to justify the amount of work implied by >> reaching consensus on FileNamePatternsPlan and then executing >> the entire thing when what we need is solvable today with a >> sub-hour patch to existing code, thus my trying to find a >> solution we can all live with.) >> >>
Re: [PATCH 4 of 4] convert: parse perforce data on-demand
On Tue, Dec 20, 2016 at 10:07:22AM -0800, David Soria Parra wrote: > # HG changeset patch > # User David Soria Parra> # Date 1482254630 28800 > # Tue Dec 20 09:23:50 2016 -0800 > # Node ID a047a142f151709f882361916617e762816db619 > # Parent 77e1912e2e0817a96633568c400450a9566e7e33 > convert: parse perforce data on-demand Queued these, thanks. How does it feel to be the convert maintainer? > > We are using read-only attributes that parse the perforce data on > demand. We are reading the data only once whenever an attribute is > requested and use it throughout the import process. This is equivalent > to the previous behavior, but we are avoiding reading from perforce when > we initialize the object, but instead run it during the actual import > process, when the first attribute is requested (usually getheads(), see > `convertcmd.convert`). > > diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py > --- a/hgext/convert/p4.py > +++ b/hgext/convert/p4.py > @@ -56,13 +56,8 @@ > common.checktool('p4', abort=False) > > self.revmap = {} > -self.heads = [] > -self.changeset = {} > -self.files = {} > -self.copies = {} > self.encoding = self.ui.config('convert', 'p4.encoding', > default=convcmd.orig_encoding) > -self.depotname = {} # mapping from local name to depot name > self.re_type = re.compile( > "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" > "(\+\w+)?$") > @@ -74,7 +69,6 @@ > if revs and len(revs) > 1: > raise error.Abort(_("p4 source does not support specifying " > "multiple revisions")) > -self._parse_once(ui, path) > > def setrevmap(self, revmap): > """Sets the parsed revmap dictionary. > @@ -240,13 +234,29 @@ > 'depotname': depotname, > } > > -def _parse_once(self, ui, path): > -d = self._parse(ui, path) > -self.changeset = d['changeset'] > -self.heads = d['heads'] > -self.files = d['files'] > -self.copies = d['copies'] > -self.depotname = d['depotname'] > +@util.propertycache > +def _parse_once(self): > +return self._parse(self.ui, self.path) > + > +@util.propertycache > +def copies(self): > +return self._parse_once['copies'] > + > +@util.propertycache > +def files(self): > +return self._parse_once['files'] > + > +@util.propertycache > +def changeset(self): > +return self._parse_once['changeset'] > + > +@util.propertycache > +def heads(self): > +return self._parse_once['heads'] > + > +@util.propertycache > +def depotname(self): > +return self._parse_once['depotname'] > > def getheads(self): > return self.heads > diff --git a/tests/test-convert-p4-filetypes.t > b/tests/test-convert-p4-filetypes.t > --- a/tests/test-convert-p4-filetypes.t > +++ b/tests/test-convert-p4-filetypes.t > @@ -307,11 +307,11 @@ > convert >$ hg convert -s p4 $DEPOTPATH dst >initializing destination dst repository > + scanning source... >reading p4 views >collecting p4 changelists >1 initial >2 keywords > - scanning source... >sorting... >converting... >1 initial > diff --git a/tests/test-convert-p4.t b/tests/test-convert-p4.t > --- a/tests/test-convert-p4.t > +++ b/tests/test-convert-p4.t > @@ -67,12 +67,12 @@ > convert >$ hg convert -s p4 $DEPOTPATH dst >initializing destination dst repository > + scanning source... >reading p4 views >collecting p4 changelists >1 initial >2 change a >3 change b/c > - scanning source... >sorting... >converting... >2 initial > @@ -98,13 +98,10 @@ > > convert again >$ hg convert -s p4 $DEPOTPATH dst > + scanning source... >reading p4 views >collecting p4 changelists > - 1 initial > - 2 change a > - 3 change b/c >4 change a b/c > - scanning source... >sorting... >converting... >0 change a b/c > @@ -130,14 +127,10 @@ > > convert again >$ hg convert -s p4 $DEPOTPATH dst > + scanning source... >reading p4 views >collecting p4 changelists > - 1 initial > - 2 change a > - 3 change b/c > - 4 change a b/c >5 add d e f > - scanning source... >sorting... >converting... >0 add d e f > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3] changegroup: simplify logic around enabling changegroup 03
On Mon, Dec 19, 2016 at 07:41:23AM +0100, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David> # Date 1482117918 -3600 > # Mon Dec 19 04:25:18 2016 +0100 > # Node ID e62c766c60a19d89c4e0e50881701135c251fb6f > # Parent fef4a4a522c7ea405d8a036213223dca79fc3f84 > # EXP-Topic cleanup.changegroup > changegroup: simplify logic around enabling changegroup 03 Queued, but there's a (now-obvious) bug (not a regression though) that I'll expect a quick followup for: if treemanifest is in the repo.requirements, 01 and 02 won't work, and so should be discarded. > > There was multiple spot that took care of adding '03' as supported changegroup > version for different condition. We gather them all in one location for > simplicity. > > The 'supportedincomingversions' function is now doing nothing, but I kept it > around because it looks like a great hooking point for extension. > > (Note that we should probably just get changegroup3 out of experimental now, > But > that would be a patch with a much wider scope). > > diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py > --- a/mercurial/changegroup.py > +++ b/mercurial/changegroup.py > @@ -877,16 +877,14 @@ class cg3packer(cg2packer): > def allsupportedversions(repo): > versions = set(_packermap.keys()) > if not (repo.ui.configbool('experimental', 'changegroup3') or > -repo.ui.configbool('experimental', 'treemanifest')): > +repo.ui.configbool('experimental', 'treemanifest') or > +'treemanifest' in repo.requirements): > versions.discard('03') > return versions > > # Changegroup versions that can be applied to the repo > def supportedincomingversions(repo): > -versions = allsupportedversions(repo) > -if 'treemanifest' in repo.requirements: > -versions.add('03') > -return versions > +return allsupportedversions(repo) > > # Changegroup versions that can be created from the repo > def supportedoutgoingversions(repo): > @@ -899,7 +897,6 @@ def supportedoutgoingversions(repo): > # support versions 01 and 02. > versions.discard('01') > versions.discard('02') > -versions.add('03') > return versions > > def safeversion(repo): > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] p4: drop an assignment that is never used
On Mon, Dec 19, 2016 at 10:23:43PM +, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1482186162 0 > # Mon Dec 19 22:22:42 2016 + > # Node ID a99748ec71eb65b50dabf1d73ab9de0c6b9124b2 > # Parent 935092e525b0ee5656d0830162a1c2adf8248de3 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > a99748ec71eb > p4: drop an assignment that is never used Yuya beat you to it: 32a07b8a9f7 (queued so the bot knows this is handled) > > Discovered by pyflakes: > > hgext/convert/p4.py:305: local variable 'shortdesc' is assigned to but > never used > > diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py > --- a/hgext/convert/p4.py > +++ b/hgext/convert/p4.py > @@ -303,6 +303,4 @@ class p4_source(common.converter_source) > """ > desc = self.recode(obj.get("desc", "")) > -shortdesc = desc.split("\n", 1)[0] > - > date = (int(obj["time"]), 0) # timezone not set > if parents is None: > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 hg-website] menu: capitalize the menu options in nav bar
Sean Farleywrites: > Pulkit Goyal <7895pul...@gmail.com> writes: > >> # HG changeset patch >> # User Pulkit Goyal <7895pul...@gmail.com> >> # Date 1481185128 -19800 >> # Thu Dec 08 13:48:48 2016 +0530 >> # Node ID 39b44ed32913cc10bcc93115286262f080a257fb >> # Parent 5d30d7a345692b6656b60c9f4dab86f012b391eb >> menu: capitalize the menu options in nav bar >> >> This patch capitalize the first letter of the options in nav bar. > > Thanks! I'm a bit busy today but will try to swing back around to this > later. Finally got around to this. I am no UI expert but think it looks better :-) Queued (and now pushed)! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@30616: 9 new changesets
9 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/b52e8a4f4c0f changeset: 30608:b52e8a4f4c0f user:Pierre-Yves Daviddate:Mon Dec 12 13:32:45 2016 +0100 summary: registrar: raise a programming error on duplicated registering https://www.mercurial-scm.org/repo/hg/rev/9bf43a72b49d changeset: 30609:9bf43a72b49d user:Jun Wu date:Fri Dec 16 21:02:39 2016 + summary: context: correct metadataonlyctx's parameter https://www.mercurial-scm.org/repo/hg/rev/66cffa87d2f2 changeset: 30610:66cffa87d2f2 user:Martin von Zweigbergk date:Fri Dec 16 09:48:14 2016 -0800 summary: help: make multirevs just an alias for revsets https://www.mercurial-scm.org/repo/hg/rev/cbc61b1b52ea changeset: 30611:cbc61b1b52ea user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 19:36:40 2016 +0530 summary: py3: use %d instead of %s for integers https://www.mercurial-scm.org/repo/hg/rev/d623cc6b3742 changeset: 30612:d623cc6b3742 user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 19:47:17 2016 +0530 summary: py3: replace os.pathsep with pycompat.ospathsep https://www.mercurial-scm.org/repo/hg/rev/1112ff99d965 changeset: 30613:1112ff99d965 user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 19:56:30 2016 +0530 summary: py3: replace os.sep with pycompat.ossep (part 1 of 4) https://www.mercurial-scm.org/repo/hg/rev/cfe66dcf45c0 changeset: 30614:cfe66dcf45c0 user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 20:02:50 2016 +0530 summary: py3: replace os.sep with pycompat.ossep (part 2 of 4) https://www.mercurial-scm.org/repo/hg/rev/bb77654dc7ae changeset: 30615:bb77654dc7ae user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 20:14:24 2016 +0530 summary: py3: replace os.sep with pycompat.ossep (part 3 of 4) https://www.mercurial-scm.org/repo/hg/rev/6f9fcd29e290 changeset: 30616:6f9fcd29e290 bookmark:@ tag: tip user:Pulkit Goyal <7895pul...@gmail.com> date:Sat Dec 17 20:24:46 2016 +0530 summary: py3: replace os.sep with pycompat.ossep (part 4 of 4) -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 5 of 8 evolve-ext, V2] metaedit: use faster setparents instead of full update
On 12/06/2016 05:41 PM, Mateusz Kwapich wrote: # HG changeset patch # User Mateusz Kwapich# Date 1479325623 0 # Wed Nov 16 19:47:03 2016 + # Branch stable # Node ID 651b6258e993f6d45e4ef7b324303201db5639b2 # Parent d4a8c386a14b3e455e60fffec7fb315f9629ff12 metaedit: use faster setparents instead of full update The working copy is not changing so there is no need to extra status call. Urg, not very enthusiastic. Can we have at least number about this speedup ? This makes metaedit work on dirty wc. Note that since the file are identical on both side, we are sure there won't be merge conflict so we could use the update logic (enabling "merging" and that would work as well. I would probably be move comfortable accepting something enable fold from a dirty WC using update and then another one moving to set parent. diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -3303,7 +3303,7 @@ def metaedit(ui, repo, *revs, **opts): if opts['fold']: ui.status('%i changesets folded\n' % len(revs)) if newp1 is not None: -hg.update(repo, newp1) +repo.setparents(newp1) finally: lockmod.release(lock, wlock) diff --git a/tests/test-evolve.t b/tests/test-evolve.t --- a/tests/test-evolve.t +++ b/tests/test-evolve.t @@ -1489,7 +1489,6 @@ check that metaedit respects allowunstab abort: cannot fold chain not ending with a head or with branching [255] $ hg metaedit --user foobar - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log --template '{rev}: {author}\n' -r '42:' --hidden 42: test 43: foobar @@ -1497,7 +1496,6 @@ check that metaedit respects allowunstab 43: foobar $ HGEDITOR="sed -i'' -e 's/safely/quickly/g'" hg metaedit '.^::.' - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ HGEDITOR=cat hg metaedit '.^::.' --fold HG: This is a fold of 2 changesets. @@ -1519,7 +1517,6 @@ check that metaedit respects allowunstab HG: changed a HG: changed newfile 2 changesets folded - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ glog -r . @ 45:ca7a9e928b25@default(draft) amended @@ -1553,7 +1550,6 @@ no new commit is created here because th TODO: don't create a new commit in this case $ hg metaedit --config defaults.metaedit= - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg log -r '.^::.' --template '{rev}: {desc|firstline}\n' 36: add uu 46: amended @@ -1570,8 +1566,11 @@ TODO: don't create a new commit in this 47: foobar2 $ hg diff -r 45 -r 46 --hidden -'fold' one commit +'fold' one commit with dirty wc + $ echo x > newfile $ hg metaedit 39 --fold --user foobar3 1 changesets folded $ hg log -r 48 --template '{rev}: {author}\n' 48: foobar3 + $ hg st -amr + M newfile Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 8 evolve-ext, V2] metaedit: add a helper function for just metadata rewrites
On 12/06/2016 05:41 PM, Mateusz Kwapich wrote: # HG changeset patch # User Mateusz Kwapich# Date 1481028829 28800 # Tue Dec 06 04:53:49 2016 -0800 # Branch stable # Node ID 78b75ed14103cee05ed13948025310919adde559 # Parent 727c7211c810d304ebf92b32db7ecf697ce46ac6 metaedit: add a helper function for just metadata rewrites It will be used by metaedit. I've eventually came to review this. Sorry for the delay. The overall approach seems right, and I'm happy to see the "multiple revs" case implemented. However, I'm not thrilled with the amount of code duplicated. I think we can share more codepath here. I was not too sure of where to explain how, so you get a wall of text in patch 1. Happy reading. About rewrite - The very venerable 'rewrite' function have been in this repository since september 19th 2011. And was actually written by Peter Arrenbrecht in spring 2011 (I just imported it in). It was originally written to handle 'amend'. But is no longer used for this purpose. Its signature is a bit strange. def rewrite(repo, old, updates, head, newbases, commitopts): If will effectively fold "old + updates" and "rebase" the result on "newbases" without actually merging anything. so "updates" MUST be linear direct descendant of "old", and "newbases" must have the same manifest content as the old's parents. "head" seems to just be 'heads(old + updates)' The meta-data of "old" are reused for the resulting commit and mixed with "commitopts" It looks like it could use some cleanup if you feel brave enough. About metarewrite vs rewrite -- metarewrite seems to be doing the same things as rewrite but: 1) For only a single changesets 2) In the case we know we can reuse the manifest revision (and so we do). We can probably detect that directly within 'rewrite' and take a fast path in that case. * We can detect (1) if 'updates' is empty (and therefore head is old), * we check if the manifest is reusable by checking if the manifest nodeid for 'old.p1()' and 'old.p2()' match the one in 'newbases'. If we detect these two conditions, we can skip the expensive 'files' computation in rewrite ctx, and just call memlightctx to create the changeset. These two checkes + small amount of conditional branching seems small enough to me that I don't think we should duplicate the code and just have rewrite be a bit smarter. This would avoid the two code bases to slowly diverge for no good reason. In addition that would benefit other command that use 'rewrite' in compatible situation (eg: fold). What do you think ? About the core fold code The same apply to the code duplication in the body of the metaedit function. We get two entirely new "codebase" for each code path (fold and not fold) while they still have a lot in common. This lead to slow but dangerous code drift. We already see it in your series where fold is properly handling phase preservation while not-fold lost it. So in my opinion we could have a single code base using the fact that: * Having only 1 folding action can still be expressed in a list of actions * Not folding changesets together can be expressed with folding a set of only one changeset. At that point, I'll move the rest into the reply to patch 3. for clarity. Cheers diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -907,6 +907,13 @@ def rewrite(repo, old, updates, head, ne finally: lockmod.release(tr, lock, wlock) +def metarewrite(repo, old, newbases, commitopts): +'''Like rewrite but affects only the changeset metadata.''' +# TODO: reuse the manifest for speed +newid, created = rewrite(repo, old, [old], old, newbases, + commitopts=commitopts) +return newid, created + class MergeFailure(error.Abort): pass ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 7 of 8 evolve-ext, V2] evolve: make the disallowing new unstable more accurate
On 12/06/2016 05:41 PM, Mateusz Kwapich wrote: # HG changeset patch # User Mateusz Kwapich# Date 1481040901 28800 # Tue Dec 06 08:15:01 2016 -0800 # Branch stable # Node ID a7cc11231c424e435252e7388dd05b139e766af2 # Parent 02a29df6827d1dae26b885c9c6c9d56be33ecd00 evolve: make the disallowing new unstable more accurate If the changesets are already unstable don't trigger disallownewunstable Well, yes, such run would not create more unstability. But the point of allow unstable is to prevent people to create unstable situation locally. And this would allow to create more unstability over some existing unstability. I'm curious about your usecase here. Can you elaborate ? diff --git a/hgext/evolve.py b/hgext/evolve.py --- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -3365,7 +3365,7 @@ def _disallowednewunstable(repo, revs): allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) if allowunstable: return revset.baseset() -return repo.revs("(%ld::) - %ld", revs, revs) +return repo.revs("(%ld::) - %ld - unstable() - obsolete()", revs, revs) @eh.wrapcommand('graft') def graftwrapper(orig, ui, repo, *revs, **kwargs): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 4] convert: move localname state to function scope
# HG changeset patch # User David Soria Parra# Date 1482254630 28800 # Tue Dec 20 09:23:50 2016 -0800 # Node ID 6f7154489117ac5cc9f0f876e922fef5c44803d8 # Parent 4cb85a7af6deb30abfd4c40ec8e502560150999e convert: move localname state to function scope diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py --- a/hgext/convert/p4.py +++ b/hgext/convert/p4.py @@ -64,7 +64,6 @@ self.encoding = self.ui.config('convert', 'p4.encoding', default=convcmd.orig_encoding) self.depotname = {} # mapping from local name to depot name -self.localname = {} # mapping from depot name to local name self.re_type = re.compile( "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" "(\+\w+)?$") @@ -168,6 +167,7 @@ files = [] copies = {} copiedfiles = [] +localname = {} i = 0 while ("depotFile%d" % i) in d and ("rev%d" % i) in d: oldname = d["depotFile%d" % i] @@ -181,7 +181,7 @@ self.depotname[filename] = oldname if (d.get("action%d" % i) == "move/add"): copiedfiles.append(filename) -self.localname[oldname] = filename +localname[oldname] = filename i += 1 # Collect information about copied files @@ -208,8 +208,8 @@ j += 1 i += 1 -if copiedoldname and copiedoldname in self.localname: -copiedfilename = self.localname[copiedoldname] +if copiedoldname and copiedoldname in localname: +copiedfilename = localname[copiedoldname] break if copiedfilename: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 4] convert: return calculated values from parse() instead of manpulating state
# HG changeset patch # User David Soria Parra# Date 1482254630 28800 # Tue Dec 20 09:23:50 2016 -0800 # Node ID 77e1912e2e0817a96633568c400450a9566e7e33 # Parent 6f7154489117ac5cc9f0f876e922fef5c44803d8 convert: return calculated values from parse() instead of manpulating state diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py --- a/hgext/convert/p4.py +++ b/hgext/convert/p4.py @@ -56,7 +56,6 @@ common.checktool('p4', abort=False) self.revmap = {} -self.p4changes = {} self.heads = [] self.changeset = {} self.files = {} @@ -75,7 +74,7 @@ if revs and len(revs) > 1: raise error.Abort(_("p4 source does not support specifying " "multiple revisions")) -self._parse(ui, path) +self._parse_once(ui, path) def setrevmap(self, revmap): """Sets the parsed revmap dictionary. @@ -103,11 +102,19 @@ def _parse(self, ui, path): "Prepare list of P4 filenames and revisions to import" +p4changes = {} +changeset = {} +files_map = {} +copies_map = {} +localname = {} +depotname = {} +heads = [] + ui.status(_('reading p4 views\n')) # read client spec or view if "/" in path: -self.p4changes.update(self._parse_view(path)) +p4changes.update(self._parse_view(path)) if path.startswith("//") and path.endswith("/..."): views = {path[:-3]:""} else: @@ -120,7 +127,7 @@ for client in clientspec: if client.startswith("View"): sview, cview = clientspec[client].split() -self.p4changes.update(self._parse_view(sview)) +p4changes.update(self._parse_view(sview)) if sview.endswith("...") and cview.endswith("..."): sview = sview[:-3] cview = cview[:-3] @@ -129,8 +136,8 @@ views[sview] = cview # list of changes that affect our source files -self.p4changes = self.p4changes.keys() -self.p4changes.sort(key=int) +p4changes = p4changes.keys() +p4changes.sort(key=int) # list with depot pathnames, longest first vieworder = views.keys() @@ -142,7 +149,7 @@ # now read the full changelists to get the list of file revisions ui.status(_('collecting p4 changelists\n')) lastid = None -for change in self.p4changes: +for change in p4changes: if startrev and int(change) < int(startrev): continue if self.revs and int(change) > int(self.revs[0]): @@ -167,7 +174,6 @@ files = [] copies = {} copiedfiles = [] -localname = {} i = 0 while ("depotFile%d" % i) in d and ("rev%d" % i) in d: oldname = d["depotFile%d" % i] @@ -178,7 +184,7 @@ break if filename: files.append((filename, d["rev%d" % i])) -self.depotname[filename] = oldname +depotname[filename] = oldname if (d.get("action%d" % i) == "move/add"): copiedfiles.append(filename) localname[oldname] = filename @@ -186,7 +192,7 @@ # Collect information about copied files for filename in copiedfiles: -oldname = self.depotname[filename] +oldname = depotname[filename] flcmd = 'p4 -G filelog %s' \ % util.shellquote(oldname) @@ -218,13 +224,29 @@ ui.warn(_("cannot find source for copied file: %s@%s\n") % (filename, change)) -self.changeset[change] = c -self.files[change] = files -self.copies[change] = copies +changeset[change] = c +files_map[change] = files +copies_map[change] = copies lastid = change -if lastid and len(self.changeset) > 0: -self.heads = [lastid] +if lastid and len(changeset) > 0: +heads = [lastid] + +return { +'changeset': changeset, +'files': files_map, +'copies': copies_map, +'heads': heads, +'depotname': depotname, +} + +def _parse_once(self, ui, path): +d = self._parse(ui, path) +self.changeset = d['changeset'] +self.heads = d['heads'] +self.files = d['files'] +self.copies = d['copies'] +self.depotname = d['depotname'] def getheads(self): return self.heads ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
[PATCH 4 of 4] convert: parse perforce data on-demand
# HG changeset patch # User David Soria Parra# Date 1482254630 28800 # Tue Dec 20 09:23:50 2016 -0800 # Node ID a047a142f151709f882361916617e762816db619 # Parent 77e1912e2e0817a96633568c400450a9566e7e33 convert: parse perforce data on-demand We are using read-only attributes that parse the perforce data on demand. We are reading the data only once whenever an attribute is requested and use it throughout the import process. This is equivalent to the previous behavior, but we are avoiding reading from perforce when we initialize the object, but instead run it during the actual import process, when the first attribute is requested (usually getheads(), see `convertcmd.convert`). diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py --- a/hgext/convert/p4.py +++ b/hgext/convert/p4.py @@ -56,13 +56,8 @@ common.checktool('p4', abort=False) self.revmap = {} -self.heads = [] -self.changeset = {} -self.files = {} -self.copies = {} self.encoding = self.ui.config('convert', 'p4.encoding', default=convcmd.orig_encoding) -self.depotname = {} # mapping from local name to depot name self.re_type = re.compile( "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" "(\+\w+)?$") @@ -74,7 +69,6 @@ if revs and len(revs) > 1: raise error.Abort(_("p4 source does not support specifying " "multiple revisions")) -self._parse_once(ui, path) def setrevmap(self, revmap): """Sets the parsed revmap dictionary. @@ -240,13 +234,29 @@ 'depotname': depotname, } -def _parse_once(self, ui, path): -d = self._parse(ui, path) -self.changeset = d['changeset'] -self.heads = d['heads'] -self.files = d['files'] -self.copies = d['copies'] -self.depotname = d['depotname'] +@util.propertycache +def _parse_once(self): +return self._parse(self.ui, self.path) + +@util.propertycache +def copies(self): +return self._parse_once['copies'] + +@util.propertycache +def files(self): +return self._parse_once['files'] + +@util.propertycache +def changeset(self): +return self._parse_once['changeset'] + +@util.propertycache +def heads(self): +return self._parse_once['heads'] + +@util.propertycache +def depotname(self): +return self._parse_once['depotname'] def getheads(self): return self.heads diff --git a/tests/test-convert-p4-filetypes.t b/tests/test-convert-p4-filetypes.t --- a/tests/test-convert-p4-filetypes.t +++ b/tests/test-convert-p4-filetypes.t @@ -307,11 +307,11 @@ convert $ hg convert -s p4 $DEPOTPATH dst initializing destination dst repository + scanning source... reading p4 views collecting p4 changelists 1 initial 2 keywords - scanning source... sorting... converting... 1 initial diff --git a/tests/test-convert-p4.t b/tests/test-convert-p4.t --- a/tests/test-convert-p4.t +++ b/tests/test-convert-p4.t @@ -67,12 +67,12 @@ convert $ hg convert -s p4 $DEPOTPATH dst initializing destination dst repository + scanning source... reading p4 views collecting p4 changelists 1 initial 2 change a 3 change b/c - scanning source... sorting... converting... 2 initial @@ -98,13 +98,10 @@ convert again $ hg convert -s p4 $DEPOTPATH dst + scanning source... reading p4 views collecting p4 changelists - 1 initial - 2 change a - 3 change b/c 4 change a b/c - scanning source... sorting... converting... 0 change a b/c @@ -130,14 +127,10 @@ convert again $ hg convert -s p4 $DEPOTPATH dst + scanning source... reading p4 views collecting p4 changelists - 1 initial - 2 change a - 3 change b/c - 4 change a b/c 5 add d e f - scanning source... sorting... converting... 0 add d e f ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH RFC v8] scmutil: add a simple key-value file helper
On 12/16/2016 6:45 PM, Augie Fackler wrote: > On Fri, Dec 16, 2016 at 1:35 PM, Augie Facklerwrote: >>> scmutil: add a simple key-value file helper >>> >> At this point, I think I'd like to see obs-shelve too. Is there a >> place I can do that? > (Specifically: before we do a resend of this, I'd like to see the > client, so a link to a pastebin or repo where I could see a client on > this thread would be outstanding. THanks!) Here's a pastebin of my shelve.py: http://pastebin.com/3CYmqf2J Please note that I haven't worked on storing the actual shelved state in this file yet: that is a low-pri for me at the moment, but I want it to be available for when I have time. See obsshelvefile on line 88. The use case in shelve is very primitive - I could just store the node in a text file and it would've been ok. But I wanted to have a potential for growth and a way to move states of other commands as well. > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4] chgserver: move wrapchgui to runcommand
Excerpts from Yuya Nishihara's message of 2016-12-20 23:29:17 +0900: > On Tue, 20 Dec 2016 14:03:04 +, Jun Wu wrote: > > Excerpts from Yuya Nishihara's message of 2016-12-20 21:47:23 +0900: > > > BTW, is there any reason we have to delay the uisetup() call? I think we > > > can > > > just set req.ui in place of req.uisetup: > > > > > > class chgui(uimod.ui): > > > ... > > > req = dispatch.request(ui=chgui.load()) > > > > It's useful if runcommand needs to wrap on top of the side effects of other > > extensions (ex. pager). In my WIP patch, chgcmdserver.uisetup looks like: > > > > def _uisetup(self, ui): > > _wrapui(ui, self._csystem) > > try: > > pager = extensions.find('pager') > > except KeyError: > > pass > > else: > > if util.safehasattr(pager, '_runpager'): > > extensions.wrapfunction(pager, '_runpager', self._runpager) > > > > def _runpager(self, orig, ui, pagercmd): > > self._csystem.write(pagercmd, type='pager') > > while True: > > cmd = self.client.readline()[:-1] > > _log('pager subcommand: %s' % cmd) > > if cmd == 'attachio': > > self.attachio(ui) > > elif cmd == '': > > break > > else: > > raise error.Abort(_('unexpected command %s') % cmd) > > > > _runpager is coupled with chgcmdserver. > > Could it be implemented without req.uisetup() if we had ui.pager() function? > > https://www.mercurial-scm.org/wiki/PagerInCorePlan > > I believe we'll need to refactor the pager handling to fix a couple of pager > issues (e.g. issue5377.) So I'm not enthusiastic about this _runpager() > change. I was aware of the pager refactoring. If we can figure out the final APIs, and decouple the complex pager refactoring so the part needed by chg is small, I can do that. The pager API has 2 levels: - high-level (pagecmd): decide the command of the pager, call low-level - low-level (_runpager): accept a command and run it unconditionally I think ui.pager() should be high-level, and chg only wants to replace the low-level one. Therefore a possible API is: - ui.pager() as the new high-level API which parses config and calls low-level method. - ui._runpager(pagercmd) as the low-level API which will be implemented differently by chg. A possible approach is: 1. Move pager._runpager to uimod.ui._runpager 2. Override ui._runpager in chgui 3. Move part of pagecmd to uimod.ui.pager (or startpager if we plan to have an endpager in the future) 4. Revisit when to call ui.pager (complex) 1 and 2 are easy and related to chg. 3 does not block chg refactoring and is simple enough so I could help by the way. 4 is a complex core part of the pager plan but I'd like to avoid as it has nothing to do with chg. +durin42 because of pager. > > So uisetup is still necessary to wrap _runpager. The _wrapui change is > > unnecessary if we use your proposal. In that case, both Patch 2 and 4 can be > > dropped and Patch 1 and 3 are useful. > > Yep, that's why I haven't pushed these patches yet. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH v2] push: add a message when pushing phases but not changes (issue4232)
On 12/07/2016 04:50 AM, Jeremy Wall (zaphar) wrote: # HG changeset patch # User Jeremy Wall (zaphar)# Date 1480542942 21600 # Wed Nov 30 15:55:42 2016 -0600 # Node ID 6e1ad0fb4f792d01e75f18e41579e52bcceee198 # Parent 9e29d4e4e08b5996adda49cdd0b497d89e2b16ee push: add a message when pushing phases but not changes (issue4232) Thanks for looking into this, there is interesting bit in that proposal and it certainly bootstrap the discussion in a meaningful way. First let me inflict you some generic tough about the BC concerns: -- One of main design idea around phases (back in 2011) was that user who doesn't need to know about them should not know about them. Typically, user using Mercurial before phase and who have not opted in any new feature since then should not see them (With the obvious exception of when phases prevent them to rewrite exchanged history). This principle can be extended to the current work on the message, people doing standard interaction with publishing server are not moving phases outside of the changeset they are pushing and pulling, so they don't need extra message and it is better to keep the output undisturbed in this case. On the other hand, when user start to move toward less "classical" usage that explicitly involved phases (like interacting with a non-publishing server) it seems all right to introduce some output changes. Such logic around output (and behavior) changes also apply to things as our current "topic" experiment, people opt-in in the new feature can be exposed to message and behavior change. The good new, is that your current change seems mostly in line with this principle as the new message will only be included only if we have phase changes without changesets exchange, something rare if you stick to the default publishing server setup. About your new output - It is usually a good practice to include sample of your new output in the the changeset description. Scanning through your test change I seems to pick two possibles new output. > + sending phase public for b740e3e5c05d > + sending phase draft for 967b449fbc94 > + updated 2 phase boundaries It is unclear to me what triggers each of them, so I went and looked at the code change in more details. I can't find trace of the first two anywhere. Are these stalled test change your forgot to update? I'm not too excited about the new message "updated 2 phase boundaries". I'm afraid "phase boundary" is a term a bit too confusing for user. In addition, it is a bit too vagues, "3 phase boundary" can mean 3 changesets changed phase as much as a couple thousand. I've not though too much about it yet, but I would lean more toward something like: 42 changesets moved to public phases, We could also try to leverage the experimental 'journal' extension to give the option to peek into more data about the phase changes. About your implementation - I see a couple of issue with the implementation of your proposal, First, the code introduced to handle "phase change report" live in a function (_pushcheckoutgoing) that live in the "pushing changesets" logic. So that seems wrong and we needs that phase related code in a more phases related code path (or generic one). Second, your phase movement message is only triggered if there is no changeset pushed. We should also mention phases move for changeset that are not included in the push. We need logic outside of a 'if not outgoing.missing:' section to compute which changesets we move phase for and how they overlap with the outgoing changesets. About my interest in this issue --- I'm currently looking into the general issue of reporting more data about these date who currently move silently. This recently got in my todo-list for a paying customer (hooray). So I was planning to make progress on this over the coming handful of weeks. If you want use to work together on the topic I'm very open to it. In all cases I will do my best to help something to happen on that topic. Taking a step back: reporting more data in general -- Your changeset focus on reporting phases change pushed to the server during a push. We have a whole set of related movement currently unreported: - local phase movement on push, - phase movement on pull, - not phase data in incoming/outgoing And we even more unreported data when you start taking things like obsolescence marker into account. At that point, it is probably a good idea to take a step back and start a Plan page on the wiki to gather all things we want to report and thing about a unified rework of there reporting across commands. Let me know if you are interested in looking into that. I've made a couple of extra comments inline the patch diff -r
Re: [PATCH 4 of 4] chgserver: move wrapchgui to runcommand
On Tue, 20 Dec 2016 14:03:04 +, Jun Wu wrote: > Excerpts from Yuya Nishihara's message of 2016-12-20 21:47:23 +0900: > > BTW, is there any reason we have to delay the uisetup() call? I think we can > > just set req.ui in place of req.uisetup: > > > > class chgui(uimod.ui): > > ... > > req = dispatch.request(ui=chgui.load()) > > It's useful if runcommand needs to wrap on top of the side effects of other > extensions (ex. pager). In my WIP patch, chgcmdserver.uisetup looks like: > > def _uisetup(self, ui): > _wrapui(ui, self._csystem) > try: > pager = extensions.find('pager') > except KeyError: > pass > else: > if util.safehasattr(pager, '_runpager'): > extensions.wrapfunction(pager, '_runpager', self._runpager) > > def _runpager(self, orig, ui, pagercmd): > self._csystem.write(pagercmd, type='pager') > while True: > cmd = self.client.readline()[:-1] > _log('pager subcommand: %s' % cmd) > if cmd == 'attachio': > self.attachio(ui) > elif cmd == '': > break > else: > raise error.Abort(_('unexpected command %s') % cmd) > > _runpager is coupled with chgcmdserver. Could it be implemented without req.uisetup() if we had ui.pager() function? https://www.mercurial-scm.org/wiki/PagerInCorePlan I believe we'll need to refactor the pager handling to fix a couple of pager issues (e.g. issue5377.) So I'm not enthusiastic about this _runpager() change. > So uisetup is still necessary to wrap _runpager. The _wrapui change is > unnecessary if we use your proposal. In that case, both Patch 2 and 4 can be > dropped and Patch 1 and 3 are useful. Yep, that's why I haven't pushed these patches yet. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 8 of 9] py3: replace sys.platform with pycompat.sysplatform (part 1 of 2)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482093924 -19800 # Mon Dec 19 02:15:24 2016 +0530 # Node ID 068e2e6fe20712a2624c5b2050aedeb68ab619c2 # Parent 173684dd16962b352416332ee66bd1880497aa16 py3: replace sys.platform with pycompat.sysplatform (part 1 of 2) sys.platform returns unicode on python 3 world. Our code base has most of the things bytes because of the transformer. So we have a bytes version of this as pycompat.sysplatform. This series of 2 patches replaces occurences of sys.platform with pycompat.sysplatform. diff -r 173684dd1696 -r 068e2e6fe207 mercurial/commands.py --- a/mercurial/commands.py Mon Dec 19 00:28:12 2016 +0530 +++ b/mercurial/commands.py Mon Dec 19 02:15:24 2016 +0530 @@ -3891,15 +3891,15 @@ keep = opts.get('system') or [] if len(keep) == 0: -if sys.platform.startswith('win'): +if pycompat.sysplatform.startswith('win'): keep.append('windows') -elif sys.platform == 'OpenVMS': +elif pycompat.sysplatform == 'OpenVMS': keep.append('vms') -elif sys.platform == 'plan9': +elif pycompat.sysplatform == 'plan9': keep.append('plan9') else: keep.append('unix') -keep.append(sys.platform.lower()) +keep.append(pycompat.sysplatform.lower()) if ui.verbose: keep.append('verbose') diff -r 173684dd1696 -r 068e2e6fe207 mercurial/posix.py --- a/mercurial/posix.pyMon Dec 19 00:28:12 2016 +0530 +++ b/mercurial/posix.pyMon Dec 19 02:15:24 2016 +0530 @@ -303,7 +303,7 @@ # fallback normcase function for non-ASCII strings normcasefallback = normcase -if sys.platform == 'darwin': +if pycompat.sysplatform == 'darwin': def normcase(path): ''' @@ -354,7 +354,7 @@ # drop HFS+ ignored characters return encoding.hfsignoreclean(enc) -if sys.platform == 'cygwin': +if pycompat.sysplatform == 'cygwin': # workaround for cygwin, in which mount point part of path is # treated as case sensitive, even though underlying NTFS is case # insensitive. @@ -447,7 +447,7 @@ If command is a basename then PATH is searched for command. PATH isn't searched if command is an absolute or relative path. If command isn't found None is returned.''' -if sys.platform == 'OpenVMS': +if pycompat.sysplatform == 'OpenVMS': return command def findexisting(executable): @@ -459,7 +459,7 @@ if pycompat.ossep in command: return findexisting(command) -if sys.platform == 'plan9': +if pycompat.sysplatform == 'plan9': return findexisting(os.path.join('/bin', command)) for path in encoding.environ.get('PATH', '').split(pycompat.ospathsep): diff -r 173684dd1696 -r 068e2e6fe207 mercurial/scmposix.py --- a/mercurial/scmposix.py Mon Dec 19 00:28:12 2016 +0530 +++ b/mercurial/scmposix.py Mon Dec 19 02:15:24 2016 +0530 @@ -25,7 +25,7 @@ def systemrcpath(): path = [] -if sys.platform == 'plan9': +if pycompat.sysplatform == 'plan9': root = 'lib/mercurial' else: root = 'etc/mercurial' @@ -38,7 +38,7 @@ return path def userrcpath(): -if sys.platform == 'plan9': +if pycompat.sysplatform == 'plan9': return [encoding.environ['home'] + '/lib/hgrc'] else: return [os.path.expanduser('~/.hgrc')] diff -r 173684dd1696 -r 068e2e6fe207 mercurial/sslutil.py --- a/mercurial/sslutil.py Mon Dec 19 00:28:12 2016 +0530 +++ b/mercurial/sslutil.py Mon Dec 19 02:15:24 2016 +0530 @@ -668,7 +668,8 @@ for using system certificate store CAs in addition to the provided cacerts file """ -if sys.platform != 'darwin' or util.mainfrozen() or not sys.executable: +if (pycompat.sysplatform != 'darwin' or +util.mainfrozen() or not sys.executable): return False exe = os.path.realpath(sys.executable).lower() return (exe.startswith('/usr/bin/python') or @@ -725,7 +726,7 @@ # The Apple OpenSSL trick isn't available to us. If Python isn't able to # load system certs, we're out of luck. -if sys.platform == 'darwin': +if pycompat.sysplatform == 'darwin': # FUTURE Consider looking for Homebrew or MacPorts installed certs # files. Also consider exporting the keychain certs to a file during # Mercurial install. diff -r 173684dd1696 -r 068e2e6fe207 mercurial/ui.py --- a/mercurial/ui.py Mon Dec 19 00:28:12 2016 +0530 +++ b/mercurial/ui.py Mon Dec 19 02:15:24 2016 +0530 @@ -1085,7 +1085,7 @@ def geteditor(self): '''return editor to use''' -if sys.platform == 'plan9': +if pycompat.sysplatform == 'plan9': # vi is the MIPS instruction simulator on Plan 9. We # instead default to E to plumb commit messages to # avoid confusion. ___
[PATCH 6 of 9] py3: replace os.name with pycompat.osname (part 1 of 2)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482086812 -19800 # Mon Dec 19 00:16:52 2016 +0530 # Node ID e39ac3774a1c6703231bb5511ce082c50726b2ca # Parent 6dbdae9bb9c6e5a038a2e9c9676fdd6663d235eb py3: replace os.name with pycompat.osname (part 1 of 2) os.name returns unicodes on py3 and we have pycompat.osname which returns bytes. This series of 2 patches will change every ocurrence of os.name with pycompat.osname. diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/hgweb/server.py Mon Dec 19 00:16:52 2016 +0530 @@ -18,6 +18,7 @@ from .. import ( error, +pycompat, util, ) @@ -266,7 +267,7 @@ class MercurialHTTPServer(_mixin, httpservermod.httpserver, object): # SO_REUSEADDR has broken semantics on windows -if os.name == 'nt': +if pycompat.osname == 'nt': allow_reuse_address = 0 def __init__(self, ui, app, addr, handler, **kwargs): diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/i18n.py --- a/mercurial/i18n.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/i18n.py Mon Dec 19 00:16:52 2016 +0530 @@ -29,7 +29,7 @@ unicode = str _languages = None -if (os.name == 'nt' +if (pycompat.osname == 'nt' and 'LANGUAGE' not in encoding.environ and 'LC_ALL' not in encoding.environ and 'LC_MESSAGES' not in encoding.environ diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/pure/osutil.py --- a/mercurial/pure/osutil.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/pure/osutil.py Mon Dec 19 00:16:52 2016 +0530 @@ -159,7 +159,7 @@ else: listdir = listdirpure -if os.name != 'nt': +if pycompat.osname != 'nt': posixfile = open _SCM_RIGHTS = 0x01 diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/scmutil.py --- a/mercurial/scmutil.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/scmutil.py Mon Dec 19 00:16:52 2016 +0530 @@ -34,7 +34,7 @@ util, ) -if os.name == 'nt': +if pycompat.osname == 'nt': from . import scmwindows as scmplatform else: from . import scmposix as scmplatform @@ -281,7 +281,7 @@ val = ui.config('ui', 'portablefilenames', 'warn') lval = val.lower() bval = util.parsebool(val) -abort = os.name == 'nt' or lval == 'abort' +abort = pycompat.osname == 'nt' or lval == 'abort' warn = bval or lval == 'warn' if bval is None and not (warn or abort or lval == 'ignore'): raise error.ConfigError( @@ -1461,7 +1461,7 @@ # Only Windows/NTFS has slow file closing. So only enable by default # on that platform. But allow to be enabled elsewhere for testing. -defaultenabled = os.name == 'nt' +defaultenabled = pycompat.osname == 'nt' enabled = ui.configbool('worker', 'backgroundclose', defaultenabled) if not enabled: diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/sslutil.py --- a/mercurial/sslutil.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/sslutil.py Mon Dec 19 00:16:52 2016 +0530 @@ -18,6 +18,7 @@ from .i18n import _ from . import ( error, +pycompat, util, ) @@ -706,7 +707,7 @@ # because we'll get a certificate verification error later and the lack # of loaded CA certificates will be the reason why. # Assertion: this code is only called if certificates are being verified. -if os.name == 'nt': +if pycompat.osname == 'nt': if not _canloaddefaultcerts: ui.warn(_('(unable to load Windows CA certificates; see ' 'https://mercurial-scm.org/wiki/SecureConnections for ' @@ -737,7 +738,7 @@ # / is writable on Windows. Out of an abundance of caution make sure # we're not on Windows because paths from _systemcacerts could be installed # by non-admin users. -assert os.name != 'nt' +assert pycompat.osname != 'nt' # Try to find CA certificates in well-known locations. We print a warning # when using a found file because we don't want too much silent magic diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/subrepo.py --- a/mercurial/subrepo.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/subrepo.py Mon Dec 19 00:16:52 2016 +0530 @@ -1313,7 +1313,7 @@ notfoundhint = _("check git is installed and in your PATH") if e.errno != errno.ENOENT: raise error.Abort(genericerror % (self._path, e.strerror)) -elif os.name == 'nt': +elif pycompat.osname == 'nt': try: self._gitexecutable = 'git.cmd' out, err = self._gitnodir(['--version']) diff -r 6dbdae9bb9c6 -r e39ac3774a1c mercurial/util.py --- a/mercurial/util.py Sun Dec 18 02:08:59 2016 +0530 +++ b/mercurial/util.py Mon Dec 19 00:16:52 2016 +0530 @@ -63,7 +63,7 @@ urlreq = pycompat.urlreq xmlrpclib = pycompat.xmlrpclib -if os.name == 'nt': +if pycompat.osname == 'nt': from . import windows as
[PATCH 9 of 9] py3: replace sys.platform with pycompat.sysplatform (part 2 of 2)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482094601 -19800 # Mon Dec 19 02:26:41 2016 +0530 # Node ID e0752031ef003151141020f68a2a902080db157b # Parent 068e2e6fe20712a2624c5b2050aedeb68ab619c2 py3: replace sys.platform with pycompat.sysplatform (part 2 of 2) diff -r 068e2e6fe207 -r e0752031ef00 hgext/win32mbcs.py --- a/hgext/win32mbcs.pyMon Dec 19 02:15:24 2016 +0530 +++ b/hgext/win32mbcs.pyMon Dec 19 02:26:41 2016 +0530 @@ -169,7 +169,7 @@ def extsetup(ui): # TODO: decide use of config section for this extension if ((not os.path.supports_unicode_filenames) and -(sys.platform != 'cygwin')): +(pycompat.sysplatform != 'cygwin')): ui.warn(_("[win32mbcs] cannot activate on this platform.\n")) return # determine encoding for filename diff -r 068e2e6fe207 -r e0752031ef00 mercurial/posix.py --- a/mercurial/posix.pyMon Dec 19 02:15:24 2016 +0530 +++ b/mercurial/posix.pyMon Dec 19 02:26:41 2016 +0530 @@ -80,7 +80,7 @@ def parsepatchoutput(output_line): """parses the output produced by patch and returns the filename""" pf = output_line[14:] -if os.sys.platform == 'OpenVMS': +if pycompat.sysplatform == 'OpenVMS': if pf[0] == '`': pf = pf[1:-1] # Remove the quotes else: @@ -404,7 +404,7 @@ _needsshellquote = None def shellquote(s): -if os.sys.platform == 'OpenVMS': +if pycompat.sysplatform == 'OpenVMS': return '"%s"' % s global _needsshellquote if _needsshellquote is None: @@ -423,7 +423,7 @@ def testpid(pid): '''return False if pid dead, True if running or not sure''' -if os.sys.platform == 'OpenVMS': +if pycompat.sysplatform == 'OpenVMS': return True try: os.kill(pid, 0) diff -r 068e2e6fe207 -r e0752031ef00 mercurial/pure/osutil.py --- a/mercurial/pure/osutil.py Mon Dec 19 02:15:24 2016 +0530 +++ b/mercurial/pure/osutil.py Mon Dec 19 02:26:41 2016 +0530 @@ -12,7 +12,6 @@ import os import socket import stat as statmod -import sys from . import ( policy, @@ -70,14 +69,14 @@ return result ffi = None -if modulepolicy not in policynocffi and sys.platform == 'darwin': +if modulepolicy not in policynocffi and pycompat.sysplatform == 'darwin': try: from _osutil_cffi import ffi, lib except ImportError: if modulepolicy == 'cffi': # strict cffi import raise -if sys.platform == 'darwin' and ffi is not None: +if pycompat.sysplatform == 'darwin' and ffi is not None: listdir_batch_size = 4096 # tweakable number, only affects performance, which chunks # of bytes do we get back from getattrlistbulk @@ -165,7 +164,7 @@ _SCM_RIGHTS = 0x01 _socklen_t = ctypes.c_uint -if sys.platform == 'linux2': +if pycompat.sysplatform.startswith('linux'): # socket.h says "the type should be socklen_t but the definition of # the kernel is incompatible with this." _cmsg_len_t = ctypes.c_size_t diff -r 068e2e6fe207 -r e0752031ef00 mercurial/util.py --- a/mercurial/util.py Mon Dec 19 02:15:24 2016 +0530 +++ b/mercurial/util.py Mon Dec 19 02:26:41 2016 +0530 @@ -795,7 +795,7 @@ cmd = cmd.replace('INFILE', inname) cmd = cmd.replace('OUTFILE', outname) code = os.system(cmd) -if sys.platform == 'OpenVMS' and code & 1: +if pycompat.sysplatform == 'OpenVMS' and code & 1: code = 0 if code: raise Abort(_("command '%s' failed: %s") % @@ -998,7 +998,7 @@ return str(val) origcmd = cmd cmd = quotecommand(cmd) -if sys.platform == 'plan9' and (sys.version_info[0] == 2 +if pycompat.sysplatform == 'plan9' and (sys.version_info[0] == 2 and sys.version_info[1] < 7): # subprocess kludge to work around issues in half-baked Python # ports, notably bichued/python: @@ -1020,7 +1020,7 @@ out.write(line) proc.wait() rc = proc.returncode -if sys.platform == 'OpenVMS' and rc & 1: +if pycompat.sysplatform == 'OpenVMS' and rc & 1: rc = 0 if rc and onerr: errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]), @@ -1383,7 +1383,7 @@ def gui(): '''Are we running in a GUI?''' -if sys.platform == 'darwin': +if pycompat.sysplatform == 'darwin': if 'SSH_CONNECTION' in encoding.environ: # handle SSH access to a box where the user is logged in return False ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 9] py3: replace os.environ with encoding.environ (part 4 of 5)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482006960 -19800 # Sun Dec 18 02:06:00 2016 +0530 # Node ID fc020b58c3081d84af150e5ed700bc67b7616c2b # Parent 9cea8eb14d9e7fbf9be2fa6a67c94e6832d57c11 py3: replace os.environ with encoding.environ (part 4 of 5) diff -r 9cea8eb14d9e -r fc020b58c308 mercurial/scmwindows.py --- a/mercurial/scmwindows.py Sun Dec 18 01:54:36 2016 +0530 +++ b/mercurial/scmwindows.py Sun Dec 18 02:06:00 2016 +0530 @@ -3,6 +3,7 @@ import os from . import ( +encoding, osutil, pycompat, util, @@ -48,7 +49,7 @@ home = os.path.expanduser('~') path = [os.path.join(home, 'mercurial.ini'), os.path.join(home, '.hgrc')] -userprofile = os.environ.get('USERPROFILE') +userprofile = encoding.environ.get('USERPROFILE') if userprofile and userprofile != home: path.append(os.path.join(userprofile, 'mercurial.ini')) path.append(os.path.join(userprofile, '.hgrc')) diff -r 9cea8eb14d9e -r fc020b58c308 mercurial/statprof.py --- a/mercurial/statprof.py Sun Dec 18 01:54:36 2016 +0530 +++ b/mercurial/statprof.py Sun Dec 18 02:06:00 2016 +0530 @@ -117,6 +117,7 @@ import time from . import ( +encoding, pycompat, ) @@ -324,7 +325,7 @@ state.accumulate_time(clock()) state.last_start_time = None -statprofpath = os.environ.get('STATPROF_DEST') +statprofpath = encoding.environ.get('STATPROF_DEST') if statprofpath: save_data(statprofpath) @@ -680,7 +681,7 @@ def write_to_flame(data, fp, scriptpath=None, outputfile=None, **kwargs): if scriptpath is None: -scriptpath = os.environ['HOME'] + '/flamegraph.pl' +scriptpath = encoding.environ['HOME'] + '/flamegraph.pl' if not os.path.exists(scriptpath): print("error: missing %s" % scriptpath, file=fp) print("get it here: https://github.com/brendangregg/FlameGraph;, diff -r 9cea8eb14d9e -r fc020b58c308 mercurial/ui.py --- a/mercurial/ui.py Sun Dec 18 01:54:36 2016 +0530 +++ b/mercurial/ui.py Sun Dec 18 02:06:00 2016 +0530 @@ -143,7 +143,7 @@ self.fin = util.stdin # shared read-only environment -self.environ = os.environ +self.environ = encoding.environ self.httppasswordmgrdb = urlreq.httppasswordmgrwithdefaultrealm() diff -r 9cea8eb14d9e -r fc020b58c308 mercurial/util.py --- a/mercurial/util.py Sun Dec 18 01:54:36 2016 +0530 +++ b/mercurial/util.py Sun Dec 18 02:06:00 2016 +0530 @@ -948,14 +948,14 @@ Defaults to $HG or 'hg' in the search path. """ if _hgexecutable is None: -hg = os.environ.get('HG') +hg = encoding.environ.get('HG') mainmod = sys.modules['__main__'] if hg: _sethgexecutable(hg) elif mainfrozen(): if getattr(sys, 'frozen', None) == 'macosx_app': # Env variable set by py2app -_sethgexecutable(os.environ['EXECUTABLEPATH']) +_sethgexecutable(encoding.environ['EXECUTABLEPATH']) else: _sethgexecutable(sys.executable) elif os.path.basename(getattr(mainmod, '__file__', '')) == 'hg': @@ -1006,7 +1006,7 @@ os.chdir(cwd) rc = os.system(cmd) else: -env = dict(os.environ) +env = dict(encoding.environ) env.update((k, py2shell(v)) for k, v in environ.iteritems()) env['HG'] = hgexecutable() if out is None or _isstdout(out): @@ -1384,7 +1384,7 @@ def gui(): '''Are we running in a GUI?''' if sys.platform == 'darwin': -if 'SSH_CONNECTION' in os.environ: +if 'SSH_CONNECTION' in encoding.environ: # handle SSH access to a box where the user is logged in return False elif getattr(osutil, 'isgui', None): @@ -1394,7 +1394,7 @@ # pure build; use a safe default return True else: -return os.name == "nt" or os.environ.get("DISPLAY") +return os.name == "nt" or encoding.environ.get("DISPLAY") def mktempcopy(name, emptyok=False, createmode=None): """Create a temporary file with the same contents from name @@ -2297,7 +2297,7 @@ if mainfrozen(): if getattr(sys, 'frozen', None) == 'macosx_app': # Env variable set by py2app -return [os.environ['EXECUTABLEPATH']] +return [encoding.environ['EXECUTABLEPATH']] else: return [sys.executable] return gethgcmd() diff -r 9cea8eb14d9e -r fc020b58c308 mercurial/win32.py --- a/mercurial/win32.pySun Dec 18 01:54:36 2016 +0530 +++ b/mercurial/win32.pySun Dec 18 02:06:00 2016 +0530 @@ -14,6 +14,8 @@ import random import subprocess +from . import encoding + _kernel32 = ctypes.windll.kernel32 _advapi32 = ctypes.windll.advapi32 _user32 = ctypes.windll.user32 @@ -424,8 +426,8 @@ pi =
[PATCH 2 of 9] py3: replace os.environ with encoding.environ (part 2 of 5)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482005799 -19800 # Sun Dec 18 01:46:39 2016 +0530 # Node ID c1a8b0e2a088a8cd365f7aa6a3f5d609fc57a92f # Parent 961ff24b8c2f9d71ff8f5d6539f760e78d88d07a py3: replace os.environ with encoding.environ (part 2 of 5) diff -r 961ff24b8c2f -r c1a8b0e2a088 mercurial/chgserver.py --- a/mercurial/chgserver.pySun Dec 18 01:34:41 2016 +0530 +++ b/mercurial/chgserver.pySun Dec 18 01:46:39 2016 +0530 @@ -55,6 +55,7 @@ from . import ( cmdutil, commandserver, +encoding, error, extensions, osutil, @@ -102,7 +103,8 @@ for section in _configsections: sectionitems.append(ui.configitems(section)) sectionhash = _hashlist(sectionitems) -envitems = [(k, v) for k, v in os.environ.iteritems() if _envre.match(k)] +envitems = [(k, v) for k, v in encoding.environ.iteritems()\ +if _envre.match(k)] envhash = _hashlist(sorted(envitems)) return sectionhash[:6] + envhash[:6] @@ -177,7 +179,7 @@ if not ui.formatted(): return -p = ui.config("pager", "pager", os.environ.get("PAGER")) +p = ui.config("pager", "pager", encoding.environ.get("PAGER")) usepager = False always = util.parsebool(options['pager']) auto = options['pager'] == 'auto' @@ -237,7 +239,7 @@ if val is True: return '1' return str(val) -env = os.environ.copy() +env = encoding.environ.copy() if environ: env.update((k, py2shell(v)) for k, v in environ.iteritems()) env['HG'] = util.hgexecutable() @@ -515,8 +517,8 @@ except ValueError: raise ValueError('unexpected value in setenv request') _log('setenv: %r\n' % sorted(newenv.keys())) -os.environ.clear() -os.environ.update(newenv) +encoding.environ.clear() +encoding.environ.update(newenv) capabilities = commandserver.server.capabilities.copy() capabilities.update({'attachio': attachio, @@ -626,8 +628,8 @@ def chgunixservice(ui, repo, opts): # CHGINTERNALMARK is temporarily set by chg client to detect if chg will # start another chg. drop it to avoid possible side effects. -if 'CHGINTERNALMARK' in os.environ: -del os.environ['CHGINTERNALMARK'] +if 'CHGINTERNALMARK' in encoding.environ: +del encoding.environ['CHGINTERNALMARK'] if repo: # one chgserver can serve multiple repos. drop repo information diff -r 961ff24b8c2f -r c1a8b0e2a088 mercurial/sshserver.py --- a/mercurial/sshserver.pySun Dec 18 01:34:41 2016 +0530 +++ b/mercurial/sshserver.pySun Dec 18 01:46:39 2016 +0530 @@ -8,11 +8,11 @@ from __future__ import absolute_import -import os import sys from .i18n import _ from . import ( +encoding, error, hook, util, @@ -131,5 +131,5 @@ return cmd != '' def _client(self): -client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0] +client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] return 'remote:ssh:' + client diff -r 961ff24b8c2f -r c1a8b0e2a088 mercurial/subrepo.py --- a/mercurial/subrepo.py Sun Dec 18 01:34:41 2016 +0530 +++ b/mercurial/subrepo.py Sun Dec 18 01:46:39 2016 +0530 @@ -24,6 +24,7 @@ from . import ( cmdutil, config, +encoding, error, exchange, filemerge, @@ -1102,7 +1103,7 @@ path = self.wvfs.reljoin(self._ctx.repo().origroot, self._path, filename) cmd.append(path) -env = dict(os.environ) +env = dict(encoding.environ) # Avoid localized output, preserve current locale for everything else. lc_all = env.get('LC_ALL') if lc_all: @@ -1398,7 +1399,7 @@ """ self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands))) if env is None: -env = os.environ.copy() +env = encoding.environ.copy() # disable localization for Git output (issue5176) env['LC_ALL'] = 'C' # fix for Git CVE-2015-7545 @@ -1633,7 +1634,7 @@ if self._gitmissing(): raise error.Abort(_("subrepo %s is missing") % self._relpath) cmd = ['commit', '-a', '-m', text] -env = os.environ.copy() +env = encoding.environ.copy() if user: cmd += ['--author', user] if date: diff -r 961ff24b8c2f -r c1a8b0e2a088 mercurial/worker.py --- a/mercurial/worker.py Sun Dec 18 01:34:41 2016 +0530 +++ b/mercurial/worker.py Sun Dec 18 01:46:39 2016 +0530 @@ -14,6 +14,7 @@ from .i18n import _ from . import ( +encoding, error, scmutil, util, @@ -32,7 +33,7 @@ # windows try: -n = int(os.environ['NUMBER_OF_PROCESSORS']) +n = int(encoding.environ['NUMBER_OF_PROCESSORS']) if n > 0:
[PATCH 5 of 9] py3: replace os.environ with encoding.environ (part 5 of 5)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482007139 -19800 # Sun Dec 18 02:08:59 2016 +0530 # Node ID 6dbdae9bb9c6e5a038a2e9c9676fdd6663d235eb # Parent fc020b58c3081d84af150e5ed700bc67b7616c2b py3: replace os.environ with encoding.environ (part 5 of 5) diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/color.py --- a/hgext/color.pySun Dec 18 02:06:00 2016 +0530 +++ b/hgext/color.pySun Dec 18 02:08:59 2016 +0530 @@ -171,6 +171,7 @@ cmdutil, commands, dispatch, +encoding, extensions, subrepo, ui as uimod, @@ -245,7 +246,8 @@ if not always and not auto: return None -formatted = always or (os.environ.get('TERM') != 'dumb' and ui.formatted()) +formatted = always or (encoding.environ.get('TERM') != 'dumb'\ +and ui.formatted()) mode = ui.config('color', 'mode', 'auto') @@ -256,7 +258,7 @@ realmode = mode if mode == 'auto': if os.name == 'nt': -term = os.environ.get('TERM') +term = encoding.environ.get('TERM') # TERM won't be defined in a vanilla cmd.exe environment. # UNIX-like environments on Windows such as Cygwin and MSYS will diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/convert/cvs.py --- a/hgext/convert/cvs.py Sun Dec 18 02:06:00 2016 +0530 +++ b/hgext/convert/cvs.py Sun Dec 18 02:08:59 2016 +0530 @@ -189,7 +189,7 @@ if conntype != "pserver": if conntype == "rsh": -rsh = os.environ.get("CVS_RSH") or "ssh" +rsh = encoding.environ.get("CVS_RSH") or "ssh" if user: cmd = [rsh, '-l', user, host] + cmd else: diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/convert/cvsps.py --- a/hgext/convert/cvsps.pySun Dec 18 02:06:00 2016 +0530 +++ b/hgext/convert/cvsps.pySun Dec 18 02:08:59 2016 +0530 @@ -11,6 +11,7 @@ from mercurial.i18n import _ from mercurial import ( +encoding, hook, pycompat, util, @@ -147,7 +148,7 @@ pass if not root: -root = os.environ.get('CVSROOT', '') +root = encoding.environ.get('CVSROOT', '') # read log cache if one exists oldlog = [] diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/logtoprocess.py --- a/hgext/logtoprocess.py Sun Dec 18 02:06:00 2016 +0530 +++ b/hgext/logtoprocess.py Sun Dec 18 02:08:59 2016 +0530 @@ -40,6 +40,8 @@ import subprocess import sys +from mercurial import encoding + # 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 @@ -117,7 +119,7 @@ optpairs = ( ('OPT_{0}'.format(key.upper()), str(value)) for key, value in opts.iteritems()) -env = dict(itertools.chain(os.environ.items(), +env = dict(itertools.chain(encoding.environ.items(), msgpairs, optpairs), EVENT=event, HGPID=str(os.getpid())) # Connect stdin to /dev/null to prevent child processes messing diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/pager.py --- a/hgext/pager.pySun Dec 18 02:06:00 2016 +0530 +++ b/hgext/pager.pySun Dec 18 02:08:59 2016 +0530 @@ -71,6 +71,7 @@ cmdutil, commands, dispatch, +encoding, extensions, util, ) @@ -123,7 +124,7 @@ return def pagecmd(orig, ui, options, cmd, cmdfunc): -p = ui.config("pager", "pager", os.environ.get("PAGER")) +p = ui.config("pager", "pager", encoding.environ.get("PAGER")) usepager = False always = util.parsebool(options['pager']) auto = options['pager'] == 'auto' diff -r fc020b58c308 -r 6dbdae9bb9c6 hgext/patchbomb.py --- a/hgext/patchbomb.pySun Dec 18 02:06:00 2016 +0530 +++ b/hgext/patchbomb.pySun Dec 18 02:08:59 2016 +0530 @@ -75,6 +75,7 @@ from mercurial import ( cmdutil, commands, +encoding, error, hg, mail, @@ -693,8 +694,8 @@ if opts.get('test'): ui.status(_('displaying '), subj, ' ...\n') ui.flush() -if 'PAGER' in os.environ and not ui.plain(): -fp = util.popen(os.environ['PAGER'], 'w') +if 'PAGER' in encoding.environ and not ui.plain(): +fp = util.popen(encoding.environ['PAGER'], 'w') else: fp = ui generator = emailmod.Generator.Generator(fp, mangle_from_=False) diff -r fc020b58c308 -r 6dbdae9bb9c6 tests/test-check-config.t --- a/tests/test-check-config.t Sun Dec 18 02:06:00 2016 +0530 +++ b/tests/test-check-config.t Sun Dec 18 02:08:59 2016 +0530 @@ -7,6 +7,3 @@ $ hg files "set:(**.py or **.txt) - tests/**" | sed 's|\\|/|g' | > python
[PATCH 3 of 9] py3: replace os.environ with encoding.environ (part 3 of 5)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482006276 -19800 # Sun Dec 18 01:54:36 2016 +0530 # Node ID 9cea8eb14d9e7fbf9be2fa6a67c94e6832d57c11 # Parent c1a8b0e2a088a8cd365f7aa6a3f5d609fc57a92f py3: replace os.environ with encoding.environ (part 3 of 5) diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/filemerge.py --- a/mercurial/filemerge.pySun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/filemerge.pySun Dec 18 01:54:36 2016 +0530 @@ -16,6 +16,7 @@ from .node import nullid, short from . import ( +encoding, error, formatter, match, @@ -165,7 +166,7 @@ return (force, force) # HGMERGE takes next precedence -hgmerge = os.environ.get("HGMERGE") +hgmerge = encoding.environ.get("HGMERGE") if hgmerge: if changedelete and not supportscd(hgmerge): return ":prompt", None diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py Sun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/hgweb/common.py Sun Dec 18 01:54:36 2016 +0530 @@ -13,6 +13,7 @@ import os from .. import ( +encoding, pycompat, util, ) @@ -191,7 +192,7 @@ """ return (config("web", "contact") or config("ui", "username") or -os.environ.get("EMAIL") or "") +encoding.environ.get("EMAIL") or "") def caching(web, req): tag = 'W/"%s"' % web.mtime diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Sun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/hgweb/hgweb_mod.py Sun Dec 18 01:54:36 2016 +0530 @@ -286,7 +286,8 @@ Modern servers should be using WSGI and should avoid this method, if possible. """ -if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): +if not encoding.environ.get('GATEWAY_INTERFACE',\ +'').startswith("CGI/1."): raise RuntimeError("This function is only intended to be " "called while running as a CGI script.") wsgicgi.launch(self) diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py Sun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/hgweb/hgwebdir_mod.py Sun Dec 18 01:54:36 2016 +0530 @@ -186,7 +186,8 @@ self.lastrefresh = time.time() def run(self): -if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): +if not encoding.environ.get('GATEWAY_INTERFACE',\ +'').startswith("CGI/1."): raise RuntimeError("This function is only intended to be " "called while running as a CGI script.") wsgicgi.launch(self) diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/hgweb/wsgicgi.py --- a/mercurial/hgweb/wsgicgi.pySun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/hgweb/wsgicgi.pySun Dec 18 01:54:36 2016 +0530 @@ -10,9 +10,8 @@ from __future__ import absolute_import -import os - from .. import ( +encoding, util, ) @@ -24,7 +23,7 @@ util.setbinary(util.stdin) util.setbinary(util.stdout) -environ = dict(os.environ.iteritems()) +environ = dict(encoding.environ.iteritems()) environ.setdefault('PATH_INFO', '') if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'): # IIS includes script_name in PATH_INFO diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/url.py --- a/mercurial/url.py Sun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/url.py Sun Dec 18 01:54:36 2016 +0530 @@ -15,6 +15,7 @@ from .i18n import _ from . import ( +encoding, error, httpconnection as httpconnectionmod, keepalive, @@ -118,8 +119,8 @@ if ui.config("http_proxy", "host"): for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]: try: -if env in os.environ: -del os.environ[env] +if env in encoding.environ: +del encoding.environ[env] except OSError: pass diff -r c1a8b0e2a088 -r 9cea8eb14d9e mercurial/windows.py --- a/mercurial/windows.py Sun Dec 18 01:46:39 2016 +0530 +++ b/mercurial/windows.py Sun Dec 18 01:54:36 2016 +0530 @@ -177,7 +177,7 @@ try: return sys.getwindowsversion()[3] == 1 except AttributeError: -return 'command' in os.environ.get('comspec', '') +return 'command' in encoding.environ.get('comspec', '') def openhardlinks(): return not _is_win_9x() @@ -303,7 +303,7 @@ PATH isn't searched if command is an absolute or relative path. An extension from PATHEXT is found and added if not present. If command isn't found None is returned.''' -pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD') +pathext = encoding.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD') pathexts =
[PATCH 1 of 9] py3: replace os.environ with encoding.environ (part 1 of 5)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482005081 -19800 # Sun Dec 18 01:34:41 2016 +0530 # Node ID 961ff24b8c2f9d71ff8f5d6539f760e78d88d07a # Parent ebca87566128e20c8f044f4e2d9aaec36efef625 py3: replace os.environ with encoding.environ (part 1 of 5) os.environ is a dictionary which has string elements on Python 3. We have encoding.environ which take care of all these things. This is the first patch of 5 patch series which tend to replace the occurences of os.environ with encoding.environ as using os.environ will result in unusual behaviour. diff -r ebca87566128 -r 961ff24b8c2f mercurial/bookmarks.py --- a/mercurial/bookmarks.pySun Dec 18 01:17:12 2016 +0530 +++ b/mercurial/bookmarks.pySun Dec 18 01:34:41 2016 +0530 @@ -8,7 +8,6 @@ from __future__ import absolute_import import errno -import os from .i18n import _ from .node import ( @@ -31,7 +30,7 @@ may need to tweak this behavior further. """ bkfile = None -if 'HG_PENDING' in os.environ: +if 'HG_PENDING' in encoding.environ: try: bkfile = repo.vfs('bookmarks.pending') except IOError as inst: diff -r ebca87566128 -r 961ff24b8c2f mercurial/dirstate.py --- a/mercurial/dirstate.py Sun Dec 18 01:17:12 2016 +0530 +++ b/mercurial/dirstate.py Sun Dec 18 01:34:41 2016 +0530 @@ -67,7 +67,7 @@ This returns '(fp, is_pending_opened)' tuple. ''' -if root == os.environ.get('HG_PENDING'): +if root == encoding.environ.get('HG_PENDING'): try: return (vfs('%s.pending' % filename), True) except IOError as inst: diff -r ebca87566128 -r 961ff24b8c2f mercurial/localrepo.py --- a/mercurial/localrepo.pySun Dec 18 01:17:12 2016 +0530 +++ b/mercurial/localrepo.pySun Dec 18 01:34:41 2016 +0530 @@ -499,8 +499,8 @@ @storecache('00changelog.i') def changelog(self): c = changelog.changelog(self.svfs) -if 'HG_PENDING' in os.environ: -p = os.environ['HG_PENDING'] +if 'HG_PENDING' in encoding.environ: +p = encoding.environ['HG_PENDING'] if p.startswith(self.root): c.readpending('00changelog.i.a') return c @@ -1299,7 +1299,7 @@ # the contents of parentenvvar are used by the underlying lock to # determine whether it can be inherited if parentenvvar is not None: -parentlock = os.environ.get(parentenvvar) +parentlock = encoding.environ.get(parentenvvar) try: l = lockmod.lock(vfs, lockname, 0, releasefn=releasefn, acquirefn=acquirefn, desc=desc, diff -r ebca87566128 -r 961ff24b8c2f mercurial/phases.py --- a/mercurial/phases.py Sun Dec 18 01:17:12 2016 +0530 +++ b/mercurial/phases.py Sun Dec 18 01:34:41 2016 +0530 @@ -103,7 +103,6 @@ from __future__ import absolute_import import errno -import os from .i18n import _ from .node import ( @@ -114,6 +113,7 @@ short, ) from . import ( +encoding, error, ) @@ -137,7 +137,7 @@ roots = [set() for i in allphases] try: f = None -if 'HG_PENDING' in os.environ: +if 'HG_PENDING' in encoding.environ: try: f = repo.svfs('phaseroots.pending') except IOError as inst: diff -r ebca87566128 -r 961ff24b8c2f mercurial/posix.py --- a/mercurial/posix.pySun Dec 18 01:17:12 2016 +0530 +++ b/mercurial/posix.pySun Dec 18 01:34:41 2016 +0530 @@ -462,7 +462,7 @@ if sys.platform == 'plan9': return findexisting(os.path.join('/bin', command)) -for path in os.environ.get('PATH', '').split(pycompat.ospathsep): +for path in encoding.environ.get('PATH', '').split(pycompat.ospathsep): executable = findexisting(os.path.join(path, command)) if executable is not None: return executable ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 9] py3: replace os.name with pycompat.osname (part 2 of 2)
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1482087492 -19800 # Mon Dec 19 00:28:12 2016 +0530 # Node ID 173684dd16962b352416332ee66bd1880497aa16 # Parent e39ac3774a1c6703231bb5511ce082c50726b2ca py3: replace os.name with pycompat.osname (part 2 of 2) diff -r e39ac3774a1c -r 173684dd1696 hgext/color.py --- a/hgext/color.pyMon Dec 19 00:16:52 2016 +0530 +++ b/hgext/color.pyMon Dec 19 00:28:12 2016 +0530 @@ -164,8 +164,6 @@ from __future__ import absolute_import -import os - from mercurial.i18n import _ from mercurial import ( cmdutil, @@ -173,6 +171,7 @@ dispatch, encoding, extensions, +pycompat, subrepo, ui as uimod, util, @@ -257,7 +256,7 @@ realmode = mode if mode == 'auto': -if os.name == 'nt': +if pycompat.osname == 'nt': term = encoding.environ.get('TERM') # TERM won't be defined in a vanilla cmd.exe environment. @@ -583,7 +582,7 @@ ui.write(', '.join(ui.label(e, e) for e in effects.split())) ui.write('\n') -if os.name != 'nt': +if pycompat.osname != 'nt': w32effects = None else: import ctypes diff -r e39ac3774a1c -r 173684dd1696 hgext/convert/subversion.py --- a/hgext/convert/subversion.py Mon Dec 19 00:16:52 2016 +0530 +++ b/hgext/convert/subversion.py Mon Dec 19 00:28:12 2016 +0530 @@ -103,7 +103,7 @@ pass if os.path.isdir(path): path = os.path.normpath(os.path.abspath(path)) -if os.name == 'nt': +if pycompat.osname == 'nt': path = '/' + util.normpath(path) # Module URL is later compared with the repository URL returned # by svn API, which is UTF-8. @@ -254,8 +254,8 @@ try: proto, path = url.split('://', 1) if proto == 'file': -if (os.name == 'nt' and path[:1] == '/' and path[1:2].isalpha() -and path[2:6].lower() == '%3a/'): +if (pycompat.osname == 'nt' and path[:1] == '/'\ +and path[1:2].isalpha() and path[2:6].lower() == '%3a/'): path = path[:2] + ':/' + path[6:] path = urlreq.url2pathname(path) except ValueError: diff -r e39ac3774a1c -r 173684dd1696 hgext/largefiles/lfutil.py --- a/hgext/largefiles/lfutil.pyMon Dec 19 00:16:52 2016 +0530 +++ b/hgext/largefiles/lfutil.pyMon Dec 19 00:28:12 2016 +0530 @@ -23,6 +23,7 @@ httpconnection, match as matchmod, node, +pycompat, scmutil, util, ) @@ -72,7 +73,7 @@ path = ui.configpath(longname, 'usercache', None) if path: return path -if os.name == 'nt': +if pycompat.osname == 'nt': appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA')) if appdata: return os.path.join(appdata, longname) @@ -80,7 +81,7 @@ home = os.getenv('HOME') if home: return os.path.join(home, 'Library', 'Caches', longname) -elif os.name == 'posix': +elif pycompat.osname == 'posix': path = os.getenv('XDG_CACHE_HOME') if path: return os.path.join(path, longname) @@ -88,7 +89,8 @@ if home: return os.path.join(home, '.cache', longname) else: -raise error.Abort(_('unknown operating system: %s\n') % os.name) +raise error.Abort(_('unknown operating system: %s\n') %\ +pycompat.osname) raise error.Abort(_('unknown %s usercache location') % longname) def inusercache(ui, hash): diff -r e39ac3774a1c -r 173684dd1696 hgext/schemes.py --- a/hgext/schemes.py Mon Dec 19 00:16:52 2016 +0530 +++ b/hgext/schemes.py Mon Dec 19 00:28:12 2016 +0530 @@ -50,6 +50,7 @@ error, extensions, hg, +pycompat, templater, util, ) @@ -114,7 +115,7 @@ schemes.update(dict(ui.configitems('schemes'))) t = templater.engine(lambda x: x) for scheme, url in schemes.items(): -if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha() +if (pycompat.osname == 'nt' and len(scheme) == 1 and scheme.isalpha() and os.path.exists('%s:\\' % scheme)): raise error.Abort(_('custom scheme %s:// conflicts with drive ' 'letter %s:\\\n') % (scheme, scheme.upper())) diff -r e39ac3774a1c -r 173684dd1696 hgext/win32mbcs.py --- a/hgext/win32mbcs.pyMon Dec 19 00:16:52 2016 +0530 +++ b/hgext/win32mbcs.pyMon Dec 19 00:28:12 2016 +0530 @@ -179,7 +179,7 @@ if _encoding.lower() in problematic_encodings.split(): for f in funcs.split(): wrapname(f, wrapper) -if os.name == 'nt': +if pycompat.osname == 'nt': for f in winfuncs.split(): wrapname(f, wrapper) wrapname("mercurial.osutil.listdir", wrapperforlistdir) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
Re: [PATCH 4 of 4] chgserver: move wrapchgui to runcommand
Excerpts from Yuya Nishihara's message of 2016-12-20 21:47:23 +0900: > On Mon, 19 Dec 2016 16:32:16 +, Jun Wu wrote: > > Excerpts from Yuya Nishihara's message of 2016-12-19 23:46:26 +0900: > > > On Sun, 18 Dec 2016 18:24:45 +, Jun Wu wrote: > > > > The direction is to eventually lose control on "ui" used in runcommand, > > > > and > > > > let dispatch construct a "ui" object on its own. > > > > > > I got it. > > > > > > > And we then use a special > > > > "uisetup" which calls "wrapui" to modify the ui object created by > > > > dispatch. > > > > > > Who will call this "uisetup"? dispatch or chgserver.runcommand? > > > > The plan is to add a "uisetup" argument to dispatch.request: > > > > diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py > > --- a/mercurial/dispatch.py > > +++ b/mercurial/dispatch.py > > @@ -49,5 +49,5 @@ from . import ( > >class request(object): > >def __init__(self, args, ui=None, repo=None, fin=None, fout=None, > > - ferr=None): > > + ferr=None, uisetup=None): > >self.args = args > >self.ui = ui > > @@ -59,4 +59,7 @@ class request(object): > >self.ferr = ferr > > > > +# an extra uisetup unrelated to extensions, used by chg > > +self.uisetup = uisetup > > + > >def run(): > >"run the command in sys.argv" > > @@ -660,4 +663,9 @@ def _dispatch(req): > >extensions.loadall(lui) > >exts = [ext for ext in extensions.extensions() if ext[0] not in > > _loaded] > > + > > +# An extra uisetup of the request, currently used by chg > > +if req.uisetup is not None: > > +req.uisetup(lui) > > + > ># Propagate any changes to lui.__class__ by extensions > >ui.__class__ = lui.__class__ > > Ah, that seems okay. > > BTW, is there any reason we have to delay the uisetup() call? I think we can > just set req.ui in place of req.uisetup: > > class chgui(uimod.ui): > ... > req = dispatch.request(ui=chgui.load()) It's useful if runcommand needs to wrap on top of the side effects of other extensions (ex. pager). In my WIP patch, chgcmdserver.uisetup looks like: def _uisetup(self, ui): _wrapui(ui, self._csystem) try: pager = extensions.find('pager') except KeyError: pass else: if util.safehasattr(pager, '_runpager'): extensions.wrapfunction(pager, '_runpager', self._runpager) def _runpager(self, orig, ui, pagercmd): self._csystem.write(pagercmd, type='pager') while True: cmd = self.client.readline()[:-1] _log('pager subcommand: %s' % cmd) if cmd == 'attachio': self.attachio(ui) elif cmd == '': break else: raise error.Abort(_('unexpected command %s') % cmd) _runpager is coupled with chgcmdserver. So uisetup is still necessary to wrap _runpager. The _wrapui change is unnecessary if we use your proposal. In that case, both Patch 2 and 4 can be dropped and Patch 1 and 3 are useful. > > > I'm slightly afraid of modifying ui class in the middle of the server > > > session > > > since the ui might be used after runcommand(). That could lead to a > > > subtle bug. > > > > I agree. So patch 4 should be deferred until the uisetup work is done. Since > > that depends on a lot of other things. Patch 4 should be dropped now. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] bookmarks: introduce binary encoding
Excerpts from Stanislau Hlebik's message of 2016-12-20 13:49:37 +: > Excerpts from Pierre-Yves David's message of 2016-12-17 08:39:18 +0100: > > > > On 12/09/2016 12:16 PM, Stanislau Hlebik wrote: > > > # HG changeset patch > > > # User Stanislau Hlebik> > > # Date 1481281951 28800 > > > # Fri Dec 09 03:12:31 2016 -0800 > > > # Node ID 001ceadc2bc36699bdf816370899a27203bf1818 > > > # Parent 9e29d4e4e08b5996adda49cdd0b497d89e2b16ee > > > bookmarks: introduce binary encoding > > > > > > Bookmarks binary encoding will be used for `bookmarks` bundle2 part. > > > The format is: <4 bytes - bookmark size, big-endian> > > ><1 byte - 0 if node is empty 1 otherwise><20 bytes node> > > > ValueError maybe thrown if input is incorrect. > > > > > > diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py > > > --- a/mercurial/bookmarks.py > > > +++ b/mercurial/bookmarks.py > > > @@ -8,7 +8,9 @@ > > > from __future__ import absolute_import > > > > > > import errno > > > +import io > > > import os > > > +import struct > > > > > > from .i18n import _ > > > from .node import ( > > > @@ -23,6 +25,72 @@ > > > util, > > > ) > > > > > > +_NONEMPTYNODE = struct.pack('?', False) > > > +_EMPTYNODE = struct.pack('?', True) > > > > Our constant are still lower case ;-) > > > > > +def _unpackbookmarksize(stream): > > > +"""Returns 0 if stream is empty. > > > +""" > > > + > > > +intstruct = struct.Struct('>i') > > > +expectedsize = intstruct.size > > > +encodedbookmarksize = stream.read(expectedsize) > > > +if not encodedbookmarksize: > > > +return 0 > > > > [small nits] > > > > What does this "stream" empty case means? > > > > If this is an error we should probably just error. > > > > If this is an end condition, we could make that more explicit by > > returning None. > > > > It's an end condition, I'll change to None and update comment Oh, and I won't be able to use changegroup.readexactly here because it will throw exception if stream is empty > > > > +if len(encodedbookmarksize) != expectedsize: > > > +raise ValueError( > > > +_('cannot decode bookmark size: ' > > > + 'expected size: %d, actual size: %d') % > > > +(expectedsize, len(encodedbookmarksize))) > > > > Check "changegroup.readexactly" it does this check for you. > > > > Thanks for the pointer. I noticed that it's used in couple of files > already so it's not specific to changegroup. I think it makes sense to > move it from changegroup.py to other file (maybe util.py?) What do you > think? > > > > +return intstruct.unpack(encodedbookmarksize)[0] > > > + > > > +def encodebookmarks(bookmarks): > > > +"""Encodes bookmark to node mapping to the byte string. > > > + > > > +Format: <4 bytes - bookmark size> > > > +<1 byte - 0 if node is empty 1 otherwise><20 bytes node> > > > +Node may be 20 byte binary string or empty > > > +""" > > > + > > > +intstruct = struct.Struct('>i') > > > +for bookmark, node in sorted(bookmarks.iteritems()): > > > +encodedbookmark = encoding.fromlocal(bookmark) > > > +yield intstruct.pack(len(encodedbookmark)) > > > +yield encodedbookmark > > > +if node: > > > +if len(node) != 20: > > > +raise ValueError(_('node must be 20 or bytes long')) > > > > Is there case where the content of the node can be wrong ? if not, I > > would probably just use an assert. > > Will fix > > > > > > +yield _NONEMPTYNODE > > > +yield node > > > +else: > > > +yield _EMPTYNODE > > > + > > > +def decodebookmarks(buf): > > > +"""Decodes buffer into bookmark to node mapping. > > > + > > > +Node is either 20 bytes or empty. > > > +""" > > > + > > > +stream = io.BytesIO(buf) > > > +bookmarks = {} > > > +bookmarksize = _unpackbookmarksize(stream) > > > +boolstruct = struct.Struct('?') > > > +while bookmarksize: > > > +bookmark = stream.read(bookmarksize) > > > +if len(bookmark) != bookmarksize: > > > +raise ValueError( > > > +_('cannot decode bookmark: expected size: %d, ' > > > +'actual size: %d') % (bookmarksize, len(bookmark))) > > > > CF previous comment about changegroup.readexactly. > > > > > +bookmark = encoding.tolocal(bookmark) > > > +packedemptynodeflag = stream.read(boolstruct.size) > > > +emptynode = boolstruct.unpack(packedemptynodeflag)[0] > > > +node = '' > > > +if not emptynode: > > > +node = stream.read(20) > > > > lalala, changegroup.readexactly. > > > > > +bookmarks[bookmark] = node > > > +bookmarksize = _unpackbookmarksize(stream) > > > +return bookmarks > > > + > > > def _getbkfile(repo): > > > """Hook so that extensions that mess with the store can hook bm > > > storage. > > > > Cheers, >
Re: [PATCH] bookmarks: introduce binary encoding
Excerpts from Pierre-Yves David's message of 2016-12-17 08:39:18 +0100: > > On 12/09/2016 12:16 PM, Stanislau Hlebik wrote: > > # HG changeset patch > > # User Stanislau Hlebik> > # Date 1481281951 28800 > > # Fri Dec 09 03:12:31 2016 -0800 > > # Node ID 001ceadc2bc36699bdf816370899a27203bf1818 > > # Parent 9e29d4e4e08b5996adda49cdd0b497d89e2b16ee > > bookmarks: introduce binary encoding > > > > Bookmarks binary encoding will be used for `bookmarks` bundle2 part. > > The format is: <4 bytes - bookmark size, big-endian> > ><1 byte - 0 if node is empty 1 otherwise><20 bytes node> > > ValueError maybe thrown if input is incorrect. > > > > diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py > > --- a/mercurial/bookmarks.py > > +++ b/mercurial/bookmarks.py > > @@ -8,7 +8,9 @@ > > from __future__ import absolute_import > > > > import errno > > +import io > > import os > > +import struct > > > > from .i18n import _ > > from .node import ( > > @@ -23,6 +25,72 @@ > > util, > > ) > > > > +_NONEMPTYNODE = struct.pack('?', False) > > +_EMPTYNODE = struct.pack('?', True) > > Our constant are still lower case ;-) > > > +def _unpackbookmarksize(stream): > > +"""Returns 0 if stream is empty. > > +""" > > + > > +intstruct = struct.Struct('>i') > > +expectedsize = intstruct.size > > +encodedbookmarksize = stream.read(expectedsize) > > +if not encodedbookmarksize: > > +return 0 > > [small nits] > > What does this "stream" empty case means? > > If this is an error we should probably just error. > > If this is an end condition, we could make that more explicit by > returning None. > It's an end condition, I'll change to None and update comment > > +if len(encodedbookmarksize) != expectedsize: > > +raise ValueError( > > +_('cannot decode bookmark size: ' > > + 'expected size: %d, actual size: %d') % > > +(expectedsize, len(encodedbookmarksize))) > > Check "changegroup.readexactly" it does this check for you. > Thanks for the pointer. I noticed that it's used in couple of files already so it's not specific to changegroup. I think it makes sense to move it from changegroup.py to other file (maybe util.py?) What do you think? > > +return intstruct.unpack(encodedbookmarksize)[0] > > + > > +def encodebookmarks(bookmarks): > > +"""Encodes bookmark to node mapping to the byte string. > > + > > +Format: <4 bytes - bookmark size> > > +<1 byte - 0 if node is empty 1 otherwise><20 bytes node> > > +Node may be 20 byte binary string or empty > > +""" > > + > > +intstruct = struct.Struct('>i') > > +for bookmark, node in sorted(bookmarks.iteritems()): > > +encodedbookmark = encoding.fromlocal(bookmark) > > +yield intstruct.pack(len(encodedbookmark)) > > +yield encodedbookmark > > +if node: > > +if len(node) != 20: > > +raise ValueError(_('node must be 20 or bytes long')) > > Is there case where the content of the node can be wrong ? if not, I > would probably just use an assert. Will fix > > > +yield _NONEMPTYNODE > > +yield node > > +else: > > +yield _EMPTYNODE > > + > > +def decodebookmarks(buf): > > +"""Decodes buffer into bookmark to node mapping. > > + > > +Node is either 20 bytes or empty. > > +""" > > + > > +stream = io.BytesIO(buf) > > +bookmarks = {} > > +bookmarksize = _unpackbookmarksize(stream) > > +boolstruct = struct.Struct('?') > > +while bookmarksize: > > +bookmark = stream.read(bookmarksize) > > +if len(bookmark) != bookmarksize: > > +raise ValueError( > > +_('cannot decode bookmark: expected size: %d, ' > > +'actual size: %d') % (bookmarksize, len(bookmark))) > > CF previous comment about changegroup.readexactly. > > > +bookmark = encoding.tolocal(bookmark) > > +packedemptynodeflag = stream.read(boolstruct.size) > > +emptynode = boolstruct.unpack(packedemptynodeflag)[0] > > +node = '' > > +if not emptynode: > > +node = stream.read(20) > > lalala, changegroup.readexactly. > > > +bookmarks[bookmark] = node > > +bookmarksize = _unpackbookmarksize(stream) > > +return bookmarks > > + > > def _getbkfile(repo): > > """Hook so that extensions that mess with the store can hook bm > > storage. > > Cheers, > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 3 V2] chg: start server at a unique address
On Mon, 19 Dec 2016 22:19:24 +, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1482185389 0 > # Mon Dec 19 22:09:49 2016 + > # Node ID 24534dee38fe515f2c406e18153f623a074148b3 > # Parent c543f9fd1a5b7657d4114e61e87a8d9bc32f7617 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 24534dee38fe > chg: start server at a unique address Updated test-chg.t and queued the series, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4] py3: make sure encoding.encoding is a bytes variable
On Sun, 18 Dec 2016 17:31:31 +0530, Pulkit Goyal wrote: > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1481999125 -19800 > # Sat Dec 17 23:55:25 2016 +0530 > # Node ID af87471131e2fecc9e6edeb2a5c2e155953da4bb > # Parent 1c8efe62f1f36fdf1a1bd6fcc5924cf557141d4a > py3: make sure encoding.encoding is a bytes variable Looks good. Queued the series, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] match: adding non-recursive directory matching
On 12/20/2016 06:00 AM, Rodrigo Damazio wrote: Unfortunately, while set would match the right files, because of the way the code is structured, it provides no way to not try visiting the directories inside the non-recursive match - the set needs to first collect all the files in all subdirectories (match.py, _expandset) and then filter that down to the desired ones. In plain hg repos, that's just much slower - in the context of narrowhg, the repo will simply not have the manifests for those subdirectories and trying to visit them will crash. Okay, so this seems like the current tools allow you to specify the right request but shortcoming of the -implementation- are preventing that request to work probably with narrowhg (and have performance impacts) Did I got that right ? The follow-up change to this one (which I haven't sent yet but is written) is updating visitdir to allow non-recursiveness, which btw makes something like "hg files -I rootglob:browser/*" about 4-5x faster in the firefox repo. And, If I read you right, the implementation of 'rootglob:' you provided in your patch have the same implementation issue, but you have another patch to improve the implementation to behave a way you can use (and is faster). Did I got that right too ? If I got these two pieces right, it looks like we could just apply the improvement to 'visitdir' to 'set:your/glob/*' and have your usecase filled while not jumping into UI changes. Would that work for you ? On Fri, Dec 16, 2016 at 6:21 AM, Pierre-Yves David> wrote: On 12/16/2016 02:19 AM, Augie Fackler wrote: On Nov 24, 2016, at 10:28 AM, FUJIWARA Katsunori > wrote: Yes, "files:" was the original version of this patch and the case I really care about :) I changed it to rootglob after your comments. Which way would be preferred to move forward? "files:" is "path:" family, and "rootglob:" is "glob:" family. As we concluded before, "path:" itself can't control recursion of matching well. Therefore, I think that "files:" should be implemented if needed, regardless of implementing "rootglob:". Of course, we need high point view of this area, at first :-) BTW, it is a little ambiguous (at least, for me) that "files:foo" matches against both file "foo" and files just under directory "foo". Name other than "files:" may resolve this ambiguity, but I don't have any better (and short enough) name :-< == === === patternfoo foo/bar foo/bar/baz == === === path:fooo o o files:foo o o x file:fooo x x dir:foo x o o == === === Scanning the plan page, I see that there’s a *lot* of work that could be done and no consensus as yet, but that the only immediate use case seems to be the rootfile/rootglob case. Is there some path forward we could agree on that would unblock those immediate needs for narrowhg and not make things harder in the future? Alternatively, would we be okay with a slight refactor of the matcher so that narrowhg can introduce a custom filesonly: matcher for the time being so we can keep making forward progress there? I don’t know the matcher code well enough to be able to guess if this is a reasonable path so we can be unblocked. (It’s very hard for to justify the amount of work implied by reaching consensus on FileNamePatternsPlan and then executing the entire thing when what we need is solvable today with a sub-hour patch to existing code, thus my trying to find a solution we can all live with.) As far as I understand, Foozy finding shows that the feature narrowhg needs is already there and nothing new is necessary. You can add "set:" in front of your glob to make it non recursive in all cases "set:your/directory/you/want/to/match/files/in/*" If this does not fits your needs, this probably mean I got your usecase wrong. In that case can you re-explain the issue you are trying to solve here? At the project level, it will make sense to clean up the Pattern Matching at some point, and Foozy wiki work will help us to do that. Cheers. -- Pierre-Yves David -- Pierre-Yves David ___ Mercurial-devel mailing list
Re: [PATCH 2 of 2] bookmarks: make bookmarks.comparebookmarks accept binary nodes (API)
Excerpts from Pierre-Yves David's message of 2016-12-17 08:33:20 +0100: > > On 12/09/2016 12:31 PM, Stanislau Hlebik wrote: > > # HG changeset patch > > # User Stanislau Hlebik> > # Date 1481282546 28800 > > # Fri Dec 09 03:22:26 2016 -0800 > > # Node ID df861963a18c00d72362b415a77a62d2c18660bf > > # Parent 08ab8f9d0abcbd1b2405ecb0a8670d212866af1f > > bookmarks: make bookmarks.comparebookmarks accept binary nodes (API) > > > > Binary bookmark format should be used internally. It doesn't make sense to > > have > > optional parameters `srchex` and `dsthex`. This patch removes them. It will > > also be useful for `bookmarks` bundle2 part because unnecessary conversions > > between hex and bin nodes will be avoided. > > Great, I've put a second acceptance stamp on this changeset and it > should show as public shortly. > > There is a couple thing in this patch that highlight the need for extra > work on that topic to remove all list key call from the client/server > exchange. I'm not sure if we should have something special to track > these, but see my comment below. > > > diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py > > --- a/mercurial/bookmarks.py > > +++ b/mercurial/bookmarks.py > > @@ -391,8 +391,7 @@ > > finally: > > lockmod.release(tr, l, w) > > > > -def comparebookmarks(repo, srcmarks, dstmarks, > > - srchex=None, dsthex=None, targets=None): > > +def comparebookmarks(repo, srcmarks, dstmarks, targets=None): > > '''Compare bookmarks between srcmarks and dstmarks > > > > This returns tuple "(addsrc, adddst, advsrc, advdst, diverge, > > @@ -415,19 +414,9 @@ > > Changeset IDs of tuples in "addsrc", "adddst", "differ" or > > "invalid" list may be unknown for repo. > > > > -This function expects that "srcmarks" and "dstmarks" return > > -changeset ID in 40 hexadecimal digit string for specified > > -bookmark. If not so (e.g. bmstore "repo._bookmarks" returning > > -binary value), "srchex" or "dsthex" should be specified to convert > > -into such form. > > - > > If "targets" is specified, only bookmarks listed in it are > > examined. > > ''' > > -if not srchex: > > -srchex = lambda x: x > > -if not dsthex: > > -dsthex = lambda x: x > > > > if targets: > > bset = set(targets) > > @@ -449,14 +438,14 @@ > > for b in sorted(bset): > > if b not in srcmarks: > > if b in dstmarks: > > -adddst((b, None, dsthex(dstmarks[b]))) > > +adddst((b, None, dstmarks[b])) > > else: > > invalid((b, None, None)) > > elif b not in dstmarks: > > -addsrc((b, srchex(srcmarks[b]), None)) > > +addsrc((b, srcmarks[b], None)) > > else: > > -scid = srchex(srcmarks[b]) > > -dcid = dsthex(dstmarks[b]) > > +scid = srcmarks[b] > > +dcid = dstmarks[b] > > if scid == dcid: > > same((b, scid, dcid)) > > elif scid in repo and dcid in repo: > > @@ -507,11 +496,17 @@ > > > > return None > > > > +def unhexlifybookmarks(marks): > > +binremotemarks = {} > > +for name, node in marks.items(): > > +binremotemarks[name] = bin(node) > > +return binremotemarks > > + > > This function looked suspicious and was the start of my quest to know > more. My thinking seeing this was, "wait", if we moved internal to > binary why do we still needs it? > > Keep scrolling for the result of that investigation. > > > def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()): > > ui.debug("checking for updated bookmarks\n") > > localmarks = repo._bookmarks > > (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same > > - ) = comparebookmarks(repo, remotemarks, localmarks, dsthex=hex) > > +) = comparebookmarks(repo, remotemarks, localmarks) > > > > status = ui.status > > warn = ui.warn > > @@ -522,15 +517,15 @@ > > changed = [] > > for b, scid, dcid in addsrc: > > if scid in repo: # add remote bookmarks for changes we already have > > -changed.append((b, bin(scid), status, > > +changed.append((b, scid, status, > > _("adding remote bookmark %s\n") % (b))) > > elif b in explicit: > > explicit.remove(b) > > ui.warn(_("remote bookmark %s points to locally missing %s\n") > > -% (b, scid[:12])) > > +% (b, hex(scid)[:12])) > > > > for b, scid, dcid in advsrc: > > -changed.append((b, bin(scid), status, > > +changed.append((b, scid, status, > > _("updating bookmark %s\n") % (b))) > > # remove normal movement from explicit set > > explicit.difference_update(d[0] for d in changed) > > @@ -538,13 +533,12 @@ > >
[PATCH STABLE V2] demandimport: do not raise ImportError for unknown item in fromlist
# HG changeset patch # User Yuya Nishihara# Date 1482155160 -32400 # Mon Dec 19 22:46:00 2016 +0900 # Branch stable # Node ID 09d785da911964c3282768438024a3b8e63dbd53 # Parent 7817df5585db1d87d3f6c7f496085c86d87e2e9a demandimport: do not raise ImportError for unknown item in fromlist This is the behavior of the default __import__() function, which doesn't validate the existence of the fromlist items. Later on, the missing attribute is detected while processing the import statement. https://hg.python.org/cpython/file/v2.7.13/Python/import.c#l2575 The comtypes library relies on this (maybe) undocumented behavior, and we got a bug report to TortoiseHg, sigh. https://bitbucket.org/tortoisehg/thg/issues/4647/ The test added at 26a4e46af2bc verifies the behavior of the import statement, so this patch only adds the test of __import__() function and works around CPython/PyPy difference. diff --git a/mercurial/demandimport.py b/mercurial/demandimport.py --- a/mercurial/demandimport.py +++ b/mercurial/demandimport.py @@ -199,8 +199,11 @@ def _demandimport(name, globals=None, lo nonpkg = getattr(mod, '__path__', nothing) is nothing if symbol is nothing: if nonpkg: -# do not try relative import, which would raise ValueError -raise ImportError('cannot import name %s' % attr) +# do not try relative import, which would raise ValueError, +# and leave unknown attribute as the default __import__() +# would do. the missing attribute will be detected later +# while processing the import statement. +return mn = '%s.%s' % (mod.__name__, attr) if mn in ignore: importfunc = _origimport diff --git a/tests/test-demandimport.py b/tests/test-demandimport.py --- a/tests/test-demandimport.py +++ b/tests/test-demandimport.py @@ -70,7 +70,16 @@ try: print('no demandmod should be created for attribute of non-package ' 'module:\ncontextlib.unknownattr =', f(unknownattr)) except ImportError as inst: -print('contextlib.unknownattr = ImportError: %s' % inst) +print('contextlib.unknownattr = ImportError: %s' + % rsub(r"'", '', str(inst))) + +# Unlike the import statement, __import__() function should not raise +# ImportError even if fromlist has an unknown item +# (see Python/import.c:import_module_level() and ensure_fromlist()) +contextlibimp = __import__('contextlib', globals(), locals(), ['unknownattr']) +print("__import__('contextlib', ..., ['unknownattr']) =", f(contextlibimp)) +print("hasattr(contextlibimp, 'unknownattr') =", + util.safehasattr(contextlibimp, 'unknownattr')) demandimport.disable() os.environ['HGDEMANDIMPORT'] = 'disable' diff --git a/tests/test-demandimport.py.out b/tests/test-demandimport.py.out --- a/tests/test-demandimport.py.out +++ b/tests/test-demandimport.py.out @@ -18,4 +18,6 @@ re.stderr = ', mod re = contextlib = contextlib.unknownattr = ImportError: cannot import name unknownattr +__import__('contextlib', ..., ['unknownattr']) = +hasattr(contextlibimp, 'unknownattr') = False node = ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel