Re: [PATCH 1 of 4 V2] histedit: add a method to cleanup nodes safely
On Fri, 17 Mar 2017 20:17:48 -0700, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1489464645 25200 > # Mon Mar 13 21:10:45 2017 -0700 > # Node ID 19a0f5164fcd28240327beffc3c90cdddfb17123 > # Parent 96929bd6e58d29bc3d44e1db7c1283f224bd1dc1 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 19a0f5164fcd > histedit: add a method to cleanup nodes safely > > The new method will decide between: > > - cleanupnode, which calls the unsafe repair.strip > - create obsmarkers > > Ideally, nobody calls "cleanupnode" directly except for "safecleanupnode". > > diff --git a/hgext/histedit.py b/hgext/histedit.py > --- a/hgext/histedit.py > +++ b/hgext/histedit.py > @@ -1575,4 +1575,32 @@ def cleanupnode(ui, repo, name, nodes): > repair.strip(ui, repo, c) > > +def safecleanupnode(ui, repo, name, nodes): > +"""strip or obsolete nodes > + > +nodes could be either a set or dict which maps to replacements. > +nodes could be unknown (outside the repo). > +""" > +supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt) > +if supportsmarkers: > +if util.safehasattr(nodes, 'get'): > +# nodes is a dict-like mapping > +# use unfiltered repo for successors in case they are hidden > +urepo = repo.unfiltered() > +def getmarker(prec): > +succs = (urepo[n] for n in nodes.get(prec, ())) > +return (repo[prec], succs) Still a generator? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH config easy] ui: move configlist parser to config.py
On Fri, 17 Mar 2017 09:34:09 -0700, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1489767596 25200 > # Fri Mar 17 09:19:56 2017 -0700 > # Node ID 012156d455f06480e3825edb450fcb37b63e9a1c > # Parent 96929bd6e58d29bc3d44e1db7c1283f224bd1dc1 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 012156d455f0 > ui: move configlist parser to config.py Nice. Queued, thanks. I've updated test-doctest.py to include config.py. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 7:01 PM, Yuya Nishiharawrote: > On Fri, 17 Mar 2017 11:42:03 -0700, Martin von Zweigbergk via Mercurial-devel > wrote: >> On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan >> wrote: >> >> > The replace() function for py3 wasn't working when `value` was being >> > typecasted as str. When I used pycompat.bytestr the error was resolved. >> > So I guess it is preserved by such methods. >> > >> >> Do you know how that works? Since it's not pycompat.bytestr, I don't >> understand what makes it work. So if you add something like this at the end >> of the "if fm.isplain():" block: >> >> if pycompat.ispy3: >>print 'value is bytestr', isinstance(value, pycompat.bytestr) >> >> it prints "value is bytestr: True"? Or is that actually false and it >> somehow doesn't rely on the __iter__ or __getitem__ methods to work >> correctly when fm.isplain()? > > The bytestr-ness isn't important here. We just need to stringify arbitrary > objects (e.g. booleans, integers) and we can't use bytes() as it would create > an n-length zeroed bytes. Aha! I had thought the whole point of pycompat.bytestr was the overridden __getitem__ and __iter__, but it's also useful for stringifying. So we could also use it instead of the "b'%d' % x" pattern we've used in some places. That would more clearly express the intent, but it is longer, so I guess that's why we haven't done it. Thanks for explaining. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4 V2] histedit: add a method to cleanup nodes safely
# HG changeset patch # User Jun Wu# Date 1489464645 25200 # Mon Mar 13 21:10:45 2017 -0700 # Node ID 19a0f5164fcd28240327beffc3c90cdddfb17123 # Parent 96929bd6e58d29bc3d44e1db7c1283f224bd1dc1 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 19a0f5164fcd histedit: add a method to cleanup nodes safely The new method will decide between: - cleanupnode, which calls the unsafe repair.strip - create obsmarkers Ideally, nobody calls "cleanupnode" directly except for "safecleanupnode". diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1575,4 +1575,32 @@ def cleanupnode(ui, repo, name, nodes): repair.strip(ui, repo, c) +def safecleanupnode(ui, repo, name, nodes): +"""strip or obsolete nodes + +nodes could be either a set or dict which maps to replacements. +nodes could be unknown (outside the repo). +""" +supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt) +if supportsmarkers: +if util.safehasattr(nodes, 'get'): +# nodes is a dict-like mapping +# use unfiltered repo for successors in case they are hidden +urepo = repo.unfiltered() +def getmarker(prec): +succs = (urepo[n] for n in nodes.get(prec, ())) +return (repo[prec], succs) +else: +# nodes is a set-like +def getmarker(prec): +return (repo[prec], ()) +# sort by revision number because it sound "right" +sortednodes = sorted([n for n in nodes if n in repo], + key=repo.changelog.rev) +markers = [getmarker(t) for t in sortednodes] +if markers: +obsolete.createmarkers(repo, markers) +else: +return cleanupnode(ui, repo, name, nodes) + def stripwrapper(orig, ui, repo, nodelist, *args, **kwargs): if isinstance(nodelist, str): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 4 V2] histedit: use safecleanupnode in _aborthistedit (issue5500)
# HG changeset patch # User Jun Wu# Date 1489468938 25200 # Mon Mar 13 22:22:18 2017 -0700 # Node ID 4b3b1a9932d9af65893d293a92684649f0d25772 # Parent e9c84e5081e18d67e061bae2a77e7465d8a6f685 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 4b3b1a9932d9 histedit: use safecleanupnode in _aborthistedit (issue5500) Now nobody in histedit calls the unsafe cleanupnode directly. diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1166,6 +1166,6 @@ def _aborthistedit(ui, repo, state): state.parentctxnode, leafs | tmpnodes): hg.clean(repo, state.topmost, show_stats=True, quietempty=True) -cleanupnode(ui, repo, 'created', tmpnodes) -cleanupnode(ui, repo, 'temp', leafs) +safecleanupnode(ui, repo, 'created', tmpnodes) +safecleanupnode(ui, repo, 'temp', leafs) except Exception: if state.inprogress(): diff --git a/tests/test-histedit-obsolete.t b/tests/test-histedit-obsolete.t --- a/tests/test-histedit-obsolete.t +++ b/tests/test-histedit-obsolete.t @@ -504,2 +504,48 @@ Note that there is a few reordering in t [255] $ cd .. + +Abort +--- + + $ cp -R base abort + $ cd abort + $ hg histedit -r 'b449568bf7fc' --commands - << EOF + > pick b449568bf7fc 13 f + > pick 7395e1ff83bd 15 h + > pick 6b70183d2492 14 g + > pick b605fb7503f2 16 i + > pick 3a6c53ee7f3d 17 j + > edit ee118ab9fa44 18 k + > EOF + Editing (ee118ab9fa44), you may commit or record as needed now. + (hg histedit --continue to resume) + [1] + + $ hg histedit --abort + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ hg log -G --hidden -r '::. + .:' + x 22:44ca09d59ae4 (secret) j + | + x 21:31747692a644 (secret) i + | + x 20:9985cd4f21fa (draft) g + | + x 19:4dc06258baa6 (draft) h + | + | @ 18:ee118ab9fa44 (secret) k + | | + | o 17:3a6c53ee7f3d (secret) j + | | + | o 16:b605fb7503f2 (secret) i + | | + | o 15:7395e1ff83bd (draft) h + | | + | o 14:6b70183d2492 (draft) g + |/ + o 13:b449568bf7fc (draft) f + | + o 12:40db8afa467b (public) c + | + o 0:cb9a9f314b8b (public) a + ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 4 V2] histedit: use safecleanupnode in _finishhistedit
# HG changeset patch # User Jun Wu# Date 1489468746 25200 # Mon Mar 13 22:19:06 2017 -0700 # Node ID e9c84e5081e18d67e061bae2a77e7465d8a6f685 # Parent 19a0f5164fcd28240327beffc3c90cdddfb17123 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r e9c84e5081e1 histedit: use safecleanupnode in _finishhistedit This simplifies code a lot. diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1126,11 +1126,5 @@ def _finishhistedit(ui, repo, state): ui.debug(m % node.short(n)) -supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt) -if supportsmarkers: -# Only create markers if the temp nodes weren't already removed. -obsolete.createmarkers(repo, ((repo[t],()) for t in sorted(tmpnodes) - if t in repo)) -else: -cleanupnode(ui, repo, 'temp', tmpnodes) +safecleanupnode(ui, repo, 'temp', tmpnodes) if not state.keep: @@ -1138,15 +1132,5 @@ def _finishhistedit(ui, repo, state): movebookmarks(ui, repo, mapping, state.topmost, ntm) # TODO update mq state -if supportsmarkers: -markers = [] -# sort by revision number because it sound "right" -for prec in sorted(mapping, key=repo.changelog.rev): -succs = mapping[prec] -markers.append((repo[prec], -tuple(repo[s] for s in succs))) -if markers: -obsolete.createmarkers(repo, markers) -else: -cleanupnode(ui, repo, 'replaced', mapping) +safecleanupnode(ui, repo, 'replaced', mapping) state.clear() ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@31472: 18 new changesets
18 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/7b5fb4b0c0e8 changeset: 31455:7b5fb4b0c0e8 user:Jun Wudate:Thu Mar 16 14:15:20 2017 -0700 summary: commit: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/2545ee88a57e changeset: 31456:2545ee88a57e user:Jun Wu date:Thu Mar 16 14:18:50 2017 -0700 summary: clone: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/707f9fd2dcad changeset: 31457:707f9fd2dcad user:Jun Wu date:Thu Mar 16 14:23:49 2017 -0700 summary: import: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/2017b5a5685b changeset: 31458:2017b5a5685b user:Jun Wu date:Thu Mar 16 14:34:35 2017 -0700 summary: record: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/f84fbd27b6d3 changeset: 31459:f84fbd27b6d3 user:Jun Wu date:Thu Mar 16 14:36:35 2017 -0700 summary: histedit: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/03d99d08147b changeset: 31460:03d99d08147b user:Jun Wu date:Thu Mar 16 14:39:18 2017 -0700 summary: mq: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/f255b1811f5e changeset: 31461:f255b1811f5e user:Jun Wu date:Thu Mar 16 14:40:34 2017 -0700 summary: rebase: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/d1ce2124ec83 changeset: 31462:d1ce2124ec83 user:Jun Wu date:Thu Mar 16 14:27:41 2017 -0700 summary: shelve: get rid of ui.backupconfig https://www.mercurial-scm.org/repo/hg/rev/55df8fa15b09 changeset: 31463:55df8fa15b09 user:Pulkit Goyal <7895pul...@gmail.com> date:Thu Mar 16 09:13:13 2017 +0530 summary: py3: make sure using bytes status char rather than ascii values https://www.mercurial-scm.org/repo/hg/rev/0e7a6279ff6e changeset: 31464:0e7a6279ff6e user:Pierre-Yves David date:Wed Mar 15 15:38:02 2017 -0700 summary: context: simplify call to icase matcher in 'match()' https://www.mercurial-scm.org/repo/hg/rev/da83f12d7a88 changeset: 31465:da83f12d7a88 user:Pierre-Yves David date:Wed Mar 15 15:07:14 2017 -0700 summary: util: explicitly tests for None https://www.mercurial-scm.org/repo/hg/rev/b6bbfbaa205a changeset: 31466:b6bbfbaa205a user:Pierre-Yves David date:Thu Mar 16 11:17:55 2017 -0700 summary: localrepo: fix deprecation warning version of wfile https://www.mercurial-scm.org/repo/hg/rev/08ecec297521 changeset: 31467:08ecec297521 user:Gregory Szorc date:Thu Mar 09 11:54:25 2017 -0800 summary: bdiff: use Python memory allocator in fixws https://www.mercurial-scm.org/repo/hg/rev/b9dd03ed564f changeset: 31468:b9dd03ed564f user:Gregory Szorc date:Thu Mar 09 11:56:47 2017 -0800 summary: osutil: use Python memory allocator in _listdir https://www.mercurial-scm.org/repo/hg/rev/a43fd9ec2a39 changeset: 31469:a43fd9ec2a39 user:Gregory Szorc date:Thu Mar 09 12:02:59 2017 -0800 summary: parsers: use Python memory allocator in commonancestorsheads() https://www.mercurial-scm.org/repo/hg/rev/bc445c556d3c changeset: 31470:bc445c556d3c user:Gregory Szorc date:Thu Mar 09 12:09:31 2017 -0800 summary: parsers: use Python memory allocator for indexObject->offsets https://www.mercurial-scm.org/repo/hg/rev/95be8b7181d3 changeset: 31471:95be8b7181d3 user:Jun Wu date:Wed Mar 15 20:43:12 2017 -0700 summary: osutil: fix potential wrong fd close https://www.mercurial-scm.org/repo/hg/rev/75e4bae56068 changeset: 31472:75e4bae56068 bookmark:@ tag: tip user:Martijn Pieters date:Sun Mar 12 11:43:31 2017 -0700 summary: config: honour the trusted flag in ui.configbytes -- 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 6 of 8] mq: get rid of ui.backupconfig
Excerpts from Yuya Nishihara's message of 2017-03-18 11:34:21 +0900: > On Thu, 16 Mar 2017 14:57:01 -0700, Jun Wu wrote: > > # HG changeset patch > > # User Jun Wu> > # Date 1489700358 25200 > > # Thu Mar 16 14:39:18 2017 -0700 > > # Node ID 8b086a28d1b605d6c0726d77c21f8d13188691fa > > # Parent 93772a7ad2c443b7c92d0d23e85405f5b0d1a800 > > # Available At https://bitbucket.org/quark-zju/hg-draft > > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > > 8b086a28d1b6 > > mq: get rid of ui.backupconfig > > > > diff --git a/hgext/mq.py b/hgext/mq.py > > --- a/hgext/mq.py > > +++ b/hgext/mq.py > > @@ -406,16 +406,10 @@ def newcommit(repo, phase, *args, **kwar > > if repo.ui.configbool('mq', 'secret', False): > > phase = phases.secret > > +override = {('ui', 'allowemptycommit'): True} > > if phase is not None: > > -phasebackup = repo.ui.backupconfig('phases', 'new-commit') > > -allowemptybackup = repo.ui.backupconfig('ui', 'allowemptycommit') > > -try: > > -if phase is not None: > > -repo.ui.setconfig('phases', 'new-commit', phase, 'mq') > > +override[('phases', 'new-commit')] = phase > > +with repo.ui.configoverride(override, 'mq'): > > repo.ui.setconfig('ui', 'allowemptycommit', True) > > This setconfig() would be no longer needed. My fault. I'll scan all "setconfig" usage and do a clean-up. If we have immutable configs, it's also better to avoid "setconfig"s. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4] histedit: add a method to cleanup nodes safely
Excerpts from Yuya Nishihara's message of 2017-03-18 11:48:30 +0900: > (+CC Pierre-Yves) I guess he may be busy with other stuffs. > I meant they both could be iterators/generators now, but 'sucs' wouldn't > be by design. I'm saying that because it seems not common to take a nested > iterator as an argument. I'll send a non-generator version. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 8] mq: get rid of ui.backupconfig
On Thu, 16 Mar 2017 14:57:01 -0700, Jun Wu wrote: > # HG changeset patch > # User Jun Wu> # Date 1489700358 25200 > # Thu Mar 16 14:39:18 2017 -0700 > # Node ID 8b086a28d1b605d6c0726d77c21f8d13188691fa > # Parent 93772a7ad2c443b7c92d0d23e85405f5b0d1a800 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 8b086a28d1b6 > mq: get rid of ui.backupconfig > > diff --git a/hgext/mq.py b/hgext/mq.py > --- a/hgext/mq.py > +++ b/hgext/mq.py > @@ -406,16 +406,10 @@ def newcommit(repo, phase, *args, **kwar > if repo.ui.configbool('mq', 'secret', False): > phase = phases.secret > +override = {('ui', 'allowemptycommit'): True} > if phase is not None: > -phasebackup = repo.ui.backupconfig('phases', 'new-commit') > -allowemptybackup = repo.ui.backupconfig('ui', 'allowemptycommit') > -try: > -if phase is not None: > -repo.ui.setconfig('phases', 'new-commit', phase, 'mq') > +override[('phases', 'new-commit')] = phase > +with repo.ui.configoverride(override, 'mq'): > repo.ui.setconfig('ui', 'allowemptycommit', True) This setconfig() would be no longer needed. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4] histedit: add a method to cleanup nodes safely
Excerpts from Yuya Nishihara's message of 2017-03-18 11:13:36 +0900: > On Fri, 17 Mar 2017 08:37:14 -0700, Jun Wu wrote: > > Excerpts from Yuya Nishihara's message of 2017-03-17 22:32:45 +0900: > > > On Mon, 13 Mar 2017 22:36:16 -0700, Jun Wu wrote: > > > > # HG changeset patch > > > > # User Jun Wu> > > > # Date 1489464645 25200 > > > > # Mon Mar 13 21:10:45 2017 -0700 > > > > # Node ID b4cf155f7a41ebf314407000f6948716ae0a64e2 > > > > # Parent 3d3109339b57341b333c1112beb41dd281fa944a > > > > # Available At https://bitbucket.org/quark-zju/hg-draft > > > > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > > > > b4cf155f7a41 > > > > histedit: add a method to cleanup nodes safely > > > > > > The series looks good to me, but one nit. > > > > > > > diff --git a/hgext/histedit.py b/hgext/histedit.py > > > > --- a/hgext/histedit.py > > > > +++ b/hgext/histedit.py > > > > @@ -1582,4 +1582,29 @@ def cleanupnode(ui, repo, name, nodes): > > > > repair.strip(ui, repo, c) > > > > > > > > +def safecleanupnode(ui, repo, name, nodes): > > > > +"""strip or obsolete nodes > > > > + > > > > +nodes could be either a set or dict which maps to replacements. > > > > +nodes could be unknown (outside the repo). > > > > +""" > > > > +supportsmarkers = obsolete.isenabled(repo, > > > > obsolete.createmarkersopt) > > > > +if supportsmarkers: > > > > +if util.safehasattr(nodes, 'get'): > > > > +# nodes is a dict-like mapping > > > > +# use unfiltered repo for successors in case they are > > > > hidden > > > > +urepo = repo.unfiltered() > > > > +marker = lambda x: (repo[x], (urepo[n] for n in > > > > nodes.get(x, ( > > > > > > > > > > > > This isn't a tuple but a generator. Is that by intention? > > > > Yes. Since obsolete.createmarkers only requires an "iterable", I think a > > generator may make the space complexity from O(N) to O(1). Another reason is > > the code fits in one line. > > Well, it works as 'sucs' is consumed only once, but the doc doesn't say Ah, I thought they could be both be generators. > 'sucs' can be an iterable. And it seems to me that each item of > 'relations' is designed as immutable. Seems it will expand sucs: nsucs = tuple(s.node() for s in sucs) And "for rel in relations" is only once. So both "relations" and "sucs" can be generators. > " must be an iterable of (, (, ...)[,{metadata}]) > tuple." I think generators are iterable. Anyway, I think this is fine as is. Or I could send a V2. Or I could fix obsolete.py documentation to make it clear that generators are fine. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4] histedit: add a method to cleanup nodes safely
On Fri, 17 Mar 2017 08:37:14 -0700, Jun Wu wrote: > Excerpts from Yuya Nishihara's message of 2017-03-17 22:32:45 +0900: > > On Mon, 13 Mar 2017 22:36:16 -0700, Jun Wu wrote: > > > # HG changeset patch > > > # User Jun Wu> > > # Date 1489464645 25200 > > > # Mon Mar 13 21:10:45 2017 -0700 > > > # Node ID b4cf155f7a41ebf314407000f6948716ae0a64e2 > > > # Parent 3d3109339b57341b333c1112beb41dd281fa944a > > > # Available At https://bitbucket.org/quark-zju/hg-draft > > > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > > > b4cf155f7a41 > > > histedit: add a method to cleanup nodes safely > > > > The series looks good to me, but one nit. > > > > > diff --git a/hgext/histedit.py b/hgext/histedit.py > > > --- a/hgext/histedit.py > > > +++ b/hgext/histedit.py > > > @@ -1582,4 +1582,29 @@ def cleanupnode(ui, repo, name, nodes): > > > repair.strip(ui, repo, c) > > > > > > +def safecleanupnode(ui, repo, name, nodes): > > > +"""strip or obsolete nodes > > > + > > > +nodes could be either a set or dict which maps to replacements. > > > +nodes could be unknown (outside the repo). > > > +""" > > > +supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt) > > > +if supportsmarkers: > > > +if util.safehasattr(nodes, 'get'): > > > +# nodes is a dict-like mapping > > > +# use unfiltered repo for successors in case they are hidden > > > +urepo = repo.unfiltered() > > > +marker = lambda x: (repo[x], (urepo[n] for n in nodes.get(x, > > > ( > > > > > > > > This isn't a tuple but a generator. Is that by intention? > > Yes. Since obsolete.createmarkers only requires an "iterable", I think a > generator may make the space complexity from O(N) to O(1). Another reason is > the code fits in one line. Well, it works as 'sucs' is consumed only once, but the doc doesn't say 'sucs' can be an iterable. And it seems to me that each item of 'relations' is designed as immutable. " must be an iterable of (, (, ...)[,{metadata}]) tuple." ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, 17 Mar 2017 11:42:03 -0700, Martin von Zweigbergk via Mercurial-devel wrote: > On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan> wrote: > > > The replace() function for py3 wasn't working when `value` was being > > typecasted as str. When I used pycompat.bytestr the error was resolved. > > So I guess it is preserved by such methods. > > > > Do you know how that works? Since it's not pycompat.bytestr, I don't > understand what makes it work. So if you add something like this at the end > of the "if fm.isplain():" block: > > if pycompat.ispy3: >print 'value is bytestr', isinstance(value, pycompat.bytestr) > > it prints "value is bytestr: True"? Or is that actually false and it > somehow doesn't rely on the __iter__ or __getitem__ methods to work > correctly when fm.isplain()? The bytestr-ness isn't important here. We just need to stringify arbitrary objects (e.g. booleans, integers) and we can't use bytes() as it would create an n-length zeroed bytes. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] subrepo: move prompts out of the if (issue5505)
On 17/03/2017 17:28, FUJIWARA Katsunori wrote: At Fri, 17 Mar 2017 13:10:57 -0700, Simon Farnsworth wrote: # HG changeset patch # User Simon Farnsworth# Date 1489781443 25200 # Fri Mar 17 13:10:43 2017 -0700 # Node ID 0ccc212fc0224209864e8c902920a91acd1bc414 # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 subrepo: move prompts out of the if (issue5505) Prompts weren't available in the else clause diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -195,6 +195,7 @@ r = "%s:%s:%s" % r repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r)) +prompts = filemerge.partextras(labels) for s, l in sorted(s1.iteritems()): a = sa.get(s, nullstate) ld = l # local state with possible dirty flag for compares @@ -203,9 +204,8 @@ if wctx == actx: # overwrite a = ld +prompts['s'] = s if s in s2: -prompts = filemerge.partextras(labels) -prompts['s'] = s r = s2[s] if ld == r or r == a: # no change or local is newer sm[s] = l @@ -275,6 +275,7 @@ mctx.sub(s).get(r) sm[s] = r elif r != sa[s]: +prompts['s'] = s if repo.ui.promptchoice( _(' remote%(o)s changed subrepository %(s)s' ' which local%(l)s removed\n' How about copying before modification at each repetitions ? promptssrc = filemerge.partextras(labels) for s, l in sorted(s1.iteritems()): prompts = promptssrc.copy() prompts['s'] = s for s, r in sorted(s2.items()): elif r != sa[s]: prompts = promptssrc.copy() prompts['s'] = s ("del prompts" before s2 loop for safety is over-killing ? :-) ) Sharing result of filemerge.partextras() between each repetitions and modifying it directly might cause wrong information, which is assigned at previous repetition, like below. In this case, shallow copy seems cheap enough. That seems like a good idea - del prompts does seem like overkill, but ending each repetition with prompts = None would ensure that the bug I introduced into the test case is caught. I'll do it in a v2 when I'm back in the UK. diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -349,7 +349,7 @@ local removed, remote changed, keep changed $ hg merge 6 - remote [merge rev] changed subrepository s which local [working copy] removed + remote [merge rev] changed subrepository t which local [working copy] removed use (c)hanged version or (d)elete? c 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) @@ -380,7 +380,7 @@ $ hg merge --config ui.interactive=true 6 < d > EOF - remote [merge rev] changed subrepository s which local [working copy] removed + remote [merge rev] changed subrepository t which local [working copy] removed use (c)hanged version or (d)elete? d 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) According to "hg debugsub" output in test-subrepo.t, merging revision 6 into revision 11 decreases managed subrepos from "s, t" to "s". $ hg ci -m6 # change sub committing subrepository t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 path t source t revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad $ hg ci -m11 created new head $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 Therefore, subrepo removed on "local" side is not "s" but "t" at this merging, and changes (or fixing wrong expectations) above seem reasonable. @@ -404,7 +404,7 @@ $ hg co -C 6 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge 11 - local [working copy] changed subrepository s which remote [merge rev] removed + local [working copy] changed subrepository t which remote [merge rev] removed use (c)hanged version or (d)elete? c 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) @@ -436,7 +436,7 @@ $ hg merge --config ui.interactive=true 11 < d > EOF - local [working copy] changed subrepository s which remote [merge rev] removed + local [working copy] changed subrepository t which remote [merge rev] removed use (c)hanged version or (d)elete? d 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) On the other hand, merging revision 11 into revision 6 increases managed subrepos from "s" to "s, t". Therefore, subrepo removed on "remote" side is not "s" but "t" at this merging, and changes above seem reasonable, too.
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 1:12 PM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 1:09 PM, Rishabh Madan> wrote: > >> >> Oh, so bytestr.replace() does return a bytestr. I guess I just >>> misunderstood Yuya then. Yuya, can you confirm? >> >> >> I was talking about value. I tried isinstance(value.replace('\n', '\\n'), >> pycompat.bytestr) and it returns false. The type of value.replace('\n', >> '\\n') returns ``. >> > > > Yes, so was I. "value" was replaced by "value.replace('\n', '\\n')" in > that "if fm.isplain()" block. I don't follow, how could that replaced value > still be a bytestr, but when you don't assign it to a variable, it does not > remain a bytestr. Python doesn't have assignment operator overloading as > far as I know. Either way, hopefully Yuya can shed some light on this. > Sorry, s/overloading/overriding/ > > >> ᐧ >> >> On Sat, Mar 18, 2017 at 1:32 AM, Martin von Zweigbergk < >> martinv...@google.com> wrote: >> >>> >>> >>> On Fri, Mar 17, 2017 at 12:55 PM, Rishabh Madan < >>> rishabhmada...@gmail.com> wrote: >>> Do you know how that works? Since it's not pycompat.bytestr, I don't > understand what makes it work. So if you add something like this at the > end > of the "if fm.isplain():" block: > if pycompat.ispy3: >print 'value is bytestr', isinstance(value, > pycompat.bytestr) > it prints "value is bytestr: True"? Or is that actually false and it > somehow doesn't rely on the __iter__ or __getitem__ methods to work > correctly when fm.isplain()? It does print true for isinstance(value, pycompat.bytestr). >>> >>> Oh, so bytestr.replace() does return a bytestr. I guess I just >>> misunderstood Yuya then. Yuya, can you confirm? >>> >>> >>> Although, I am not able to know if it relies on __iter__ / __getitem__ method or not. ᐧ On Sat, Mar 18, 2017 at 12:12 AM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan < > rishabhmada...@gmail.com> wrote: > >> The replace() function for py3 wasn't working when `value` was being >> typecasted as str. When I used pycompat.bytestr the error was >> resolved. So I guess it is preserved by such methods. >> > > Do you know how that works? Since it's not pycompat.bytestr, I don't > understand what makes it work. So if you add something like this at the > end > of the "if fm.isplain():" block: > > if pycompat.ispy3: >print 'value is bytestr', isinstance(value, > pycompat.bytestr) > > it prints "value is bytestr: True"? Or is that actually false and it > somehow doesn't rely on the __iter__ or __getitem__ methods to work > correctly when fm.isplain()? > > >> >> ᐧ >> >> On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < >> martinv...@google.com> wrote: >> >>> >>> >>> On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan < >>> rishabhmada...@gmail.com> wrote: >>> Sorry. I didn't know that changing the changeset message for V2 forwards it as a different stream. ᐧ On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan < rishabhmada...@gmail.com> wrote: > # HG changeset patch > # User Rishabh Madan > # Date 1489758142 -19800 > # Fri Mar 17 19:12:22 2017 +0530 > # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 > # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 > py3: change explicit conversion from str to pycompat.bytestr > > diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py > --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 > +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 > @@ -1813,7 +1813,7 @@ > matched = False > for section, name, value in ui.walkconfig(untrusted=untrus > ted): > source = ui.configsource(section, name, untrusted) > -value = str(value) > +value = pycompat.bytestr(value) > if fm.isplain(): > source = source or 'none' > value = value.replace('\n', '\\n') > >>> I thought I read that pycompat.bytestr-ness is not preserved by >>> operations (such as replace() on this line). If that's correct, will the >>> above still work if fm.isplain()? >>> >>> -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 1:09 PM, Rishabh Madanwrote: > > Oh, so bytestr.replace() does return a bytestr. I guess I just >> misunderstood Yuya then. Yuya, can you confirm? > > > I was talking about value. I tried isinstance(value.replace('\n', '\\n'), > pycompat.bytestr) and it returns false. The type of value.replace('\n', > '\\n') returns ``. > Yes, so was I. "value" was replaced by "value.replace('\n', '\\n')" in that "if fm.isplain()" block. I don't follow, how could that replaced value still be a bytestr, but when you don't assign it to a variable, it does not remain a bytestr. Python doesn't have assignment operator overloading as far as I know. Either way, hopefully Yuya can shed some light on this. > ᐧ > > On Sat, Mar 18, 2017 at 1:32 AM, Martin von Zweigbergk < > martinv...@google.com> wrote: > >> >> >> On Fri, Mar 17, 2017 at 12:55 PM, Rishabh Madan > > wrote: >> >>> Do you know how that works? Since it's not pycompat.bytestr, I don't understand what makes it work. So if you add something like this at the end of the "if fm.isplain():" block: if pycompat.ispy3: print 'value is bytestr', isinstance(value, pycompat.bytestr) it prints "value is bytestr: True"? Or is that actually false and it somehow doesn't rely on the __iter__ or __getitem__ methods to work correctly when fm.isplain()? >>> >>> >>> It does print true for isinstance(value, pycompat.bytestr). >>> >> >> Oh, so bytestr.replace() does return a bytestr. I guess I just >> misunderstood Yuya then. Yuya, can you confirm? >> >> >> >>> Although, I am not able to know if it relies on __iter__ / __getitem__ >>> method or not. >>> >>> >>> ᐧ >>> >>> On Sat, Mar 18, 2017 at 12:12 AM, Martin von Zweigbergk < >>> martinv...@google.com> wrote: >>> On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan < rishabhmada...@gmail.com> wrote: > The replace() function for py3 wasn't working when `value` was being > typecasted as str. When I used pycompat.bytestr the error was > resolved. So I guess it is preserved by such methods. > Do you know how that works? Since it's not pycompat.bytestr, I don't understand what makes it work. So if you add something like this at the end of the "if fm.isplain():" block: if pycompat.ispy3: print 'value is bytestr', isinstance(value, pycompat.bytestr) it prints "value is bytestr: True"? Or is that actually false and it somehow doesn't rely on the __iter__ or __getitem__ methods to work correctly when fm.isplain()? > > ᐧ > > On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < > martinv...@google.com> wrote: > >> >> >> On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan < >> rishabhmada...@gmail.com> wrote: >> >>> Sorry. I didn't know that changing the changeset message for V2 >>> forwards it as a different stream. >>> ᐧ >>> >>> On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan < >>> rishabhmada...@gmail.com> wrote: >>> # HG changeset patch # User Rishabh Madan # Date 1489758142 -19800 # Fri Mar 17 19:12:22 2017 +0530 # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 py3: change explicit conversion from str to pycompat.bytestr diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 @@ -1813,7 +1813,7 @@ matched = False for section, name, value in ui.walkconfig(untrusted=untrus ted): source = ui.configsource(section, name, untrusted) -value = str(value) +value = pycompat.bytestr(value) if fm.isplain(): source = source or 'none' value = value.replace('\n', '\\n') >>> >> I thought I read that pycompat.bytestr-ness is not preserved by >> operations (such as replace() on this line). If that's correct, will the >> above still work if fm.isplain()? >> >> >>> >>> >>> >>> -- >>> Rishabh Madan >>> Second Year Undergraduate student >>> Indian Institute of Technology, Kharagpur >>> >>> ___ >>> Mercurial-devel mailing list >>> Mercurial-devel@mercurial-scm.org >>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >>> >>> >> > > > -- > Rishabh Madan > Second Year Undergraduate student > Indian Institute of Technology, Kharagpur > >
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
> Oh, so bytestr.replace() does return a bytestr. I guess I just > misunderstood Yuya then. Yuya, can you confirm? I was talking about value. I tried isinstance(value.replace('\n', '\\n'), pycompat.bytestr) and it returns false. The type of value.replace('\n', '\\n') returns ``. ᐧ On Sat, Mar 18, 2017 at 1:32 AM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 12:55 PM, Rishabh Madan> wrote: > >> Do you know how that works? Since it's not pycompat.bytestr, I don't >>> understand what makes it work. So if you add something like this at the end >>> of the "if fm.isplain():" block: >>> if pycompat.ispy3: >>>print 'value is bytestr', isinstance(value, >>> pycompat.bytestr) >>> it prints "value is bytestr: True"? Or is that actually false and it >>> somehow doesn't rely on the __iter__ or __getitem__ methods to work >>> correctly when fm.isplain()? >> >> >> It does print true for isinstance(value, pycompat.bytestr). >> > > Oh, so bytestr.replace() does return a bytestr. I guess I just > misunderstood Yuya then. Yuya, can you confirm? > > > >> Although, I am not able to know if it relies on __iter__ / __getitem__ >> method or not. >> >> >> ᐧ >> >> On Sat, Mar 18, 2017 at 12:12 AM, Martin von Zweigbergk < >> martinv...@google.com> wrote: >> >>> >>> >>> On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan < >>> rishabhmada...@gmail.com> wrote: >>> The replace() function for py3 wasn't working when `value` was being typecasted as str. When I used pycompat.bytestr the error was resolved. So I guess it is preserved by such methods. >>> >>> Do you know how that works? Since it's not pycompat.bytestr, I don't >>> understand what makes it work. So if you add something like this at the end >>> of the "if fm.isplain():" block: >>> >>> if pycompat.ispy3: >>>print 'value is bytestr', isinstance(value, >>> pycompat.bytestr) >>> >>> it prints "value is bytestr: True"? Or is that actually false and it >>> somehow doesn't rely on the __iter__ or __getitem__ methods to work >>> correctly when fm.isplain()? >>> >>> ᐧ On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan < > rishabhmada...@gmail.com> wrote: > >> Sorry. I didn't know that changing the changeset message for V2 >> forwards it as a different stream. >> ᐧ >> >> On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan < >> rishabhmada...@gmail.com> wrote: >> >>> # HG changeset patch >>> # User Rishabh Madan >>> # Date 1489758142 -19800 >>> # Fri Mar 17 19:12:22 2017 +0530 >>> # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 >>> # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 >>> py3: change explicit conversion from str to pycompat.bytestr >>> >>> diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py >>> --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 >>> +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 >>> @@ -1813,7 +1813,7 @@ >>> matched = False >>> for section, name, value in ui.walkconfig(untrusted=untrusted): >>> source = ui.configsource(section, name, untrusted) >>> -value = str(value) >>> +value = pycompat.bytestr(value) >>> if fm.isplain(): >>> source = source or 'none' >>> value = value.replace('\n', '\\n') >>> >> > I thought I read that pycompat.bytestr-ness is not preserved by > operations (such as replace() on this line). If that's correct, will the > above still work if fm.isplain()? > > >> >> >> >> -- >> Rishabh Madan >> Second Year Undergraduate student >> Indian Institute of Technology, Kharagpur >> >> ___ >> Mercurial-devel mailing list >> Mercurial-devel@mercurial-scm.org >> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >> >> > -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >>> >> >> >> -- >> Rishabh Madan >> Second Year Undergraduate student >> Indian Institute of Technology, Kharagpur >> > > -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 12:55 PM, Rishabh Madanwrote: > Do you know how that works? Since it's not pycompat.bytestr, I don't >> understand what makes it work. So if you add something like this at the end >> of the "if fm.isplain():" block: >> if pycompat.ispy3: >>print 'value is bytestr', isinstance(value, >> pycompat.bytestr) >> it prints "value is bytestr: True"? Or is that actually false and it >> somehow doesn't rely on the __iter__ or __getitem__ methods to work >> correctly when fm.isplain()? > > > It does print true for isinstance(value, pycompat.bytestr). > Oh, so bytestr.replace() does return a bytestr. I guess I just misunderstood Yuya then. Yuya, can you confirm? > Although, I am not able to know if it relies on __iter__ / __getitem__ > method or not. > > > ᐧ > > On Sat, Mar 18, 2017 at 12:12 AM, Martin von Zweigbergk < > martinv...@google.com> wrote: > >> >> >> On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan > > wrote: >> >>> The replace() function for py3 wasn't working when `value` was being >>> typecasted as str. When I used pycompat.bytestr the error was resolved. >>> So I guess it is preserved by such methods. >>> >> >> Do you know how that works? Since it's not pycompat.bytestr, I don't >> understand what makes it work. So if you add something like this at the end >> of the "if fm.isplain():" block: >> >> if pycompat.ispy3: >>print 'value is bytestr', isinstance(value, >> pycompat.bytestr) >> >> it prints "value is bytestr: True"? Or is that actually false and it >> somehow doesn't rely on the __iter__ or __getitem__ methods to work >> correctly when fm.isplain()? >> >> >>> >>> ᐧ >>> >>> On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < >>> martinv...@google.com> wrote: >>> On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan < rishabhmada...@gmail.com> wrote: > Sorry. I didn't know that changing the changeset message for V2 > forwards it as a different stream. > ᐧ > > On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan < > rishabhmada...@gmail.com> wrote: > >> # HG changeset patch >> # User Rishabh Madan >> # Date 1489758142 -19800 >> # Fri Mar 17 19:12:22 2017 +0530 >> # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 >> # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 >> py3: change explicit conversion from str to pycompat.bytestr >> >> diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py >> --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 >> +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 >> @@ -1813,7 +1813,7 @@ >> matched = False >> for section, name, value in ui.walkconfig(untrusted=untrusted): >> source = ui.configsource(section, name, untrusted) >> -value = str(value) >> +value = pycompat.bytestr(value) >> if fm.isplain(): >> source = source or 'none' >> value = value.replace('\n', '\\n') >> > I thought I read that pycompat.bytestr-ness is not preserved by operations (such as replace() on this line). If that's correct, will the above still work if fm.isplain()? > > > > -- > Rishabh Madan > Second Year Undergraduate student > Indian Institute of Technology, Kharagpur > > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > > >>> >>> >>> -- >>> Rishabh Madan >>> Second Year Undergraduate student >>> Indian Institute of Technology, Kharagpur >>> >>> ___ >>> Mercurial-devel mailing list >>> Mercurial-devel@mercurial-scm.org >>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >>> >>> >> > > > -- > Rishabh Madan > Second Year Undergraduate student > Indian Institute of Technology, Kharagpur > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
> > Do you know how that works? Since it's not pycompat.bytestr, I don't > understand what makes it work. So if you add something like this at the end > of the "if fm.isplain():" block: > if pycompat.ispy3: >print 'value is bytestr', isinstance(value, > pycompat.bytestr) > it prints "value is bytestr: True"? Or is that actually false and it > somehow doesn't rely on the __iter__ or __getitem__ methods to work > correctly when fm.isplain()? It does print true for isinstance(value, pycompat.bytestr). Although, I am not able to know if it relies on __iter__ / __getitem__ method or not. ᐧ On Sat, Mar 18, 2017 at 12:12 AM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madan> wrote: > >> The replace() function for py3 wasn't working when `value` was being >> typecasted as str. When I used pycompat.bytestr the error was resolved. >> So I guess it is preserved by such methods. >> > > Do you know how that works? Since it's not pycompat.bytestr, I don't > understand what makes it work. So if you add something like this at the end > of the "if fm.isplain():" block: > > if pycompat.ispy3: >print 'value is bytestr', isinstance(value, > pycompat.bytestr) > > it prints "value is bytestr: True"? Or is that actually false and it > somehow doesn't rely on the __iter__ or __getitem__ methods to work > correctly when fm.isplain()? > > >> >> ᐧ >> >> On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < >> martinv...@google.com> wrote: >> >>> >>> >>> On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan >> > wrote: >>> Sorry. I didn't know that changing the changeset message for V2 forwards it as a different stream. ᐧ On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan < rishabhmada...@gmail.com> wrote: > # HG changeset patch > # User Rishabh Madan > # Date 1489758142 -19800 > # Fri Mar 17 19:12:22 2017 +0530 > # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 > # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 > py3: change explicit conversion from str to pycompat.bytestr > > diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py > --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 > +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 > @@ -1813,7 +1813,7 @@ > matched = False > for section, name, value in ui.walkconfig(untrusted=untrusted): > source = ui.configsource(section, name, untrusted) > -value = str(value) > +value = pycompat.bytestr(value) > if fm.isplain(): > source = source or 'none' > value = value.replace('\n', '\\n') > >>> I thought I read that pycompat.bytestr-ness is not preserved by >>> operations (such as replace() on this line). If that's correct, will the >>> above still work if fm.isplain()? >>> >>> -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >>> >> >> >> -- >> Rishabh Madan >> Second Year Undergraduate student >> Indian Institute of Technology, Kharagpur >> >> ___ >> Mercurial-devel mailing list >> Mercurial-devel@mercurial-scm.org >> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >> >> > -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 11:22 AM, Rishabh Madanwrote: > The replace() function for py3 wasn't working when `value` was being > typecasted as str. When I used pycompat.bytestr the error was resolved. > So I guess it is preserved by such methods. > Do you know how that works? Since it's not pycompat.bytestr, I don't understand what makes it work. So if you add something like this at the end of the "if fm.isplain():" block: if pycompat.ispy3: print 'value is bytestr', isinstance(value, pycompat.bytestr) it prints "value is bytestr: True"? Or is that actually false and it somehow doesn't rely on the __iter__ or __getitem__ methods to work correctly when fm.isplain()? > > ᐧ > > On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < > martinv...@google.com> wrote: > >> >> >> On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan >> wrote: >> >>> Sorry. I didn't know that changing the changeset message for V2 forwards >>> it as a different stream. >>> ᐧ >>> >>> On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan >> > wrote: >>> # HG changeset patch # User Rishabh Madan # Date 1489758142 -19800 # Fri Mar 17 19:12:22 2017 +0530 # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 py3: change explicit conversion from str to pycompat.bytestr diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 @@ -1813,7 +1813,7 @@ matched = False for section, name, value in ui.walkconfig(untrusted=untrusted): source = ui.configsource(section, name, untrusted) -value = str(value) +value = pycompat.bytestr(value) if fm.isplain(): source = source or 'none' value = value.replace('\n', '\\n') >>> >> I thought I read that pycompat.bytestr-ness is not preserved by >> operations (such as replace() on this line). If that's correct, will the >> above still work if fm.isplain()? >> >> >>> >>> >>> >>> -- >>> Rishabh Madan >>> Second Year Undergraduate student >>> Indian Institute of Technology, Kharagpur >>> >>> ___ >>> Mercurial-devel mailing list >>> Mercurial-devel@mercurial-scm.org >>> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >>> >>> >> > > > -- > Rishabh Madan > Second Year Undergraduate student > Indian Institute of Technology, Kharagpur > > ___ > 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 V2] py3: change explicit conversion from str to pycompat.bytestr
The replace() function for py3 wasn't working when `value` was being typecasted as str. When I used pycompat.bytestr the error was resolved. So I guess it is preserved by such methods. ᐧ On Fri, Mar 17, 2017 at 10:45 PM, Martin von Zweigbergk < martinv...@google.com> wrote: > > > On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madan> wrote: > >> Sorry. I didn't know that changing the changeset message for V2 forwards >> it as a different stream. >> ᐧ >> >> On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan >> wrote: >> >>> # HG changeset patch >>> # User Rishabh Madan >>> # Date 1489758142 -19800 >>> # Fri Mar 17 19:12:22 2017 +0530 >>> # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 >>> # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 >>> py3: change explicit conversion from str to pycompat.bytestr >>> >>> diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py >>> --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 >>> +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 >>> @@ -1813,7 +1813,7 @@ >>> matched = False >>> for section, name, value in ui.walkconfig(untrusted=untrusted): >>> source = ui.configsource(section, name, untrusted) >>> -value = str(value) >>> +value = pycompat.bytestr(value) >>> if fm.isplain(): >>> source = source or 'none' >>> value = value.replace('\n', '\\n') >>> >> > I thought I read that pycompat.bytestr-ness is not preserved by operations > (such as replace() on this line). If that's correct, will the above still > work if fm.isplain()? > > >> >> >> >> -- >> Rishabh Madan >> Second Year Undergraduate student >> Indian Institute of Technology, Kharagpur >> >> ___ >> Mercurial-devel mailing list >> Mercurial-devel@mercurial-scm.org >> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >> >> > -- Rishabh Madan Second Year Undergraduate student Indian Institute of Technology, Kharagpur ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, Mar 17, 2017 at 6:49 AM, Rishabh Madanwrote: > Sorry. I didn't know that changing the changeset message for V2 forwards > it as a different stream. > ᐧ > > On Fri, Mar 17, 2017 at 7:14 PM, Rishabh Madan > wrote: > >> # HG changeset patch >> # User Rishabh Madan >> # Date 1489758142 -19800 >> # Fri Mar 17 19:12:22 2017 +0530 >> # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 >> # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 >> py3: change explicit conversion from str to pycompat.bytestr >> >> diff -r a5bad127128d -r 3d6d9294e224 mercurial/commands.py >> --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 >> +++ b/mercurial/commands.py Fri Mar 17 19:12:22 2017 +0530 >> @@ -1813,7 +1813,7 @@ >> matched = False >> for section, name, value in ui.walkconfig(untrusted=untrusted): >> source = ui.configsource(section, name, untrusted) >> -value = str(value) >> +value = pycompat.bytestr(value) >> if fm.isplain(): >> source = source or 'none' >> value = value.replace('\n', '\\n') >> > I thought I read that pycompat.bytestr-ness is not preserved by operations (such as replace() on this line). If that's correct, will the above still work if fm.isplain()? > > > > -- > Rishabh Madan > Second Year Undergraduate student > Indian Institute of Technology, Kharagpur > > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] tests: allow ModuleNotFoundError in addition to ImportError
# HG changeset patch # User Martin von Zweigbergk# Date 1489769929 25200 # Fri Mar 17 09:58:49 2017 -0700 # Node ID 0308a2a076f5e9591c3f4b6da8f42a96eb6ec2d4 # Parent d1ce2124ec83d3eef61aa0e6b7ef89c738a5d8fe tests: allow ModuleNotFoundError in addition to ImportError My environment (Python version? PYTHONPATH? something else?) raises ModuleNotFoundError in test-check-py3-compat.t. This patch allows any "*Error". The error string contains "error importing", so it seems specific enough even after. diff -r d1ce2124ec83 -r 0308a2a076f5 tests/test-check-py3-compat.t --- a/tests/test-check-py3-compat.t Thu Mar 16 14:27:41 2017 -0700 +++ b/tests/test-check-py3-compat.t Fri Mar 17 09:58:49 2017 -0700 @@ -22,15 +22,15 @@ $ hg files 'set:(**.py) - grep(pygments)' -X hgext/fsmonitor/pywatchman \ > | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py \ > | sed 's/[0-9][0-9]*)$/*)/' - hgext/convert/transport.py: error importing: No module named 'svn.client' (error at transport.py:*) + hgext/convert/transport.py: error importing: <*Error> No module named 'svn.client' (error at transport.py:*) (glob) hgext/fsmonitor/state.py: error importing: from __future__ imports must occur at the beginning of the file (__init__.py, line 30) (error at watchmanclient.py:*) hgext/fsmonitor/watchmanclient.py: error importing: from __future__ imports must occur at the beginning of the file (__init__.py, line 30) (error at watchmanclient.py:*) - mercurial/cffi/bdiff.py: error importing: No module named 'mercurial.cffi' (error at check-py3-compat.py:*) - mercurial/cffi/mpatch.py: error importing: No module named 'mercurial.cffi' (error at check-py3-compat.py:*) - mercurial/cffi/osutil.py: error importing: No module named 'mercurial.cffi' (error at check-py3-compat.py:*) - mercurial/scmwindows.py: error importing: No module named 'msvcrt' (error at win32.py:*) - mercurial/win32.py: error importing: No module named 'msvcrt' (error at win32.py:*) - mercurial/windows.py: error importing: No module named 'msvcrt' (error at windows.py:*) + mercurial/cffi/bdiff.py: error importing: <*Error> No module named 'mercurial.cffi' (error at check-py3-compat.py:*) (glob) + mercurial/cffi/mpatch.py: error importing: <*Error> No module named 'mercurial.cffi' (error at check-py3-compat.py:*) (glob) + mercurial/cffi/osutil.py: error importing: <*Error> No module named 'mercurial.cffi' (error at check-py3-compat.py:*) (glob) + mercurial/scmwindows.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob) + mercurial/win32.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob) + mercurial/windows.py: error importing: <*Error> No module named 'msvcrt' (error at windows.py:*) (glob) #endif ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH config easy] ui: move configlist parser to config.py
# HG changeset patch # User Jun Wu# Date 1489767596 25200 # Fri Mar 17 09:19:56 2017 -0700 # Node ID 012156d455f06480e3825edb450fcb37b63e9a1c # Parent 96929bd6e58d29bc3d44e1db7c1283f224bd1dc1 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 012156d455f0 ui: move configlist parser to config.py The list parser is complex and reusable without ui. Let's move it to config.py. This allows us to parse a list from a "pure" config object without going through ui. Like, we can make "_trustusers" calculated from raw configs, instead of making sure it's synchronized by calling "fixconfig"s. diff --git a/mercurial/config.py b/mercurial/config.py --- a/mercurial/config.py +++ b/mercurial/config.py @@ -180,2 +180,85 @@ class config(object): self.parse(path, fp.read(), sections=sections, remap=remap, include=self.read) + +def parselist(value): +"""parse a configuration value as a list of comma/space separated strings + +>>> parselist('this,is "a small" ,test') +['this', 'is', 'a small', 'test'] +""" + +def _parse_plain(parts, s, offset): +whitespace = False +while offset < len(s) and (s[offset:offset + 1].isspace() + or s[offset:offset + 1] == ','): +whitespace = True +offset += 1 +if offset >= len(s): +return None, parts, offset +if whitespace: +parts.append('') +if s[offset:offset + 1] == '"' and not parts[-1]: +return _parse_quote, parts, offset + 1 +elif s[offset:offset + 1] == '"' and parts[-1][-1] == '\\': +parts[-1] = parts[-1][:-1] + s[offset:offset + 1] +return _parse_plain, parts, offset + 1 +parts[-1] += s[offset:offset + 1] +return _parse_plain, parts, offset + 1 + +def _parse_quote(parts, s, offset): +if offset < len(s) and s[offset:offset + 1] == '"': # "" +parts.append('') +offset += 1 +while offset < len(s) and (s[offset:offset + 1].isspace() or +s[offset:offset + 1] == ','): +offset += 1 +return _parse_plain, parts, offset + +while offset < len(s) and s[offset:offset + 1] != '"': +if (s[offset:offset + 1] == '\\' and offset + 1 < len(s) +and s[offset + 1:offset + 2] == '"'): +offset += 1 +parts[-1] += '"' +else: +parts[-1] += s[offset:offset + 1] +offset += 1 + +if offset >= len(s): +real_parts = _configlist(parts[-1]) +if not real_parts: +parts[-1] = '"' +else: +real_parts[0] = '"' + real_parts[0] +parts = parts[:-1] +parts.extend(real_parts) +return None, parts, offset + +offset += 1 +while offset < len(s) and s[offset:offset + 1] in [' ', ',']: +offset += 1 + +if offset < len(s): +if offset + 1 == len(s) and s[offset:offset + 1] == '"': +parts[-1] += '"' +offset += 1 +else: +parts.append('') +else: +return None, parts, offset + +return _parse_plain, parts, offset + +def _configlist(s): +s = s.rstrip(' ,') +if not s: +return [] +parser, parts, offset = _parse_plain, [''], 0 +while parser: +parser, parts, offset = parser(parts, s, offset) +return parts + +if value is not None and isinstance(value, bytes): +result = _configlist(value.lstrip(' ,\n')) +else: +result = value +return result or [] diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -563,83 +563,9 @@ class ui(object): ['this', 'is', 'a small', 'test'] """ - -def _parse_plain(parts, s, offset): -whitespace = False -while offset < len(s) and (s[offset:offset + 1].isspace() - or s[offset:offset + 1] == ','): -whitespace = True -offset += 1 -if offset >= len(s): -return None, parts, offset -if whitespace: -parts.append('') -if s[offset:offset + 1] == '"' and not parts[-1]: -return _parse_quote, parts, offset + 1 -elif s[offset:offset + 1] == '"' and parts[-1][-1] == '\\': -parts[-1] = parts[-1][:-1] + s[offset:offset + 1] -return _parse_plain, parts, offset + 1 -parts[-1] += s[offset:offset + 1] -return _parse_plain, parts, offset + 1 - -def _parse_quote(parts, s, offset): -if offset < len(s) and s[offset:offset + 1] == '"': # "" -
Re: [PATCH 01 of 10 RFC v2] ui: refactoring handling of trusted, user and overlay
Another issue with the "compat" layer outside "ucfg" or "tcfg" is that it cannot handle the case where ucfg or tcfg have different ui.compat setting. I just discovered this when writing the immutable stuff. Hopefully I can send a V1 today. Excerpts from David Soria Parra's message of 2017-03-12 15:40:24 -0700: > # HG changeset patch > # User David Soria Parra> # Date 1489349204 25200 > # Sun Mar 12 13:06:44 2017 -0700 > # Node ID 99514a82d5b23c75bd6da38e522acfd14a618c14 > # Parent 1c3352d7eaf24533ad52d4b8a024211e9189fb0b > ui: refactoring handling of trusted, user and overlay > > We are using obscure names such as _ocfg for overlay-config in the UI. This is > sometimes confusing and not very flexible. We are moving this into a > dictionary > now that has a specific ordering in which we would apply multiple layers of > configuration. At the moment this is not needed as we always pick either > user-config or trusted-config and overlay it, but it gets us a good machinery > to > add a defaults layer for ui.compat. > > diff --git a/mercurial/ui.py b/mercurial/ui.py > --- a/mercurial/ui.py > +++ b/mercurial/ui.py > @@ -146,9 +146,7 @@ > self._bufferapplylabels = None > self.quiet = self.verbose = self.debugflag = self.tracebackflag = > False > self._reportuntrusted = True > -self._ocfg = config.config() # overlay > -self._tcfg = config.config() # trusted > -self._ucfg = config.config() # untrusted > +self._cfg = self.cfg() > self._trustusers = set() > self._trustgroups = set() > self.callhooks = True > @@ -167,10 +165,6 @@ > self.fin = src.fin > self.pageractive = src.pageractive > self._disablepager = src._disablepager > - > -self._tcfg = src._tcfg.copy() > -self._ucfg = src._ucfg.copy() > -self._ocfg = src._ocfg.copy() > self._trustusers = src._trustusers.copy() > self._trustgroups = src._trustgroups.copy() > self.environ = src.environ > @@ -179,6 +173,8 @@ > self._colormode = src._colormode > self._terminfoparams = src._terminfoparams.copy() > self._styles = src._styles.copy() > +for k in self._cfg.keys(): > +self._cfg[k] = src._cfg[k].copy() > > self.fixconfig() > > @@ -296,21 +292,28 @@ > del cfg['templatealias'][k] > > if trusted: > -self._tcfg.update(cfg) > -self._tcfg.update(self._ocfg) > -self._ucfg.update(cfg) > -self._ucfg.update(self._ocfg) > +self._cfg['trusted'].update(cfg) > +self._cfg['trusted'].update(self._cfg['overlay']) > +self._cfg['user'].update(cfg) > +self._cfg['user'].update(self._cfg['overlay']) > > if root is None: > root = os.path.expanduser('~') > self.fixconfig(root=root) > > +def cfg(self): > +# Ordered in ascneding order of preference. > +return util.sortdict( > +[('user', config.config()), > +('trusted', config.config()), > +('overlay', config.config())]) > + > def fixconfig(self, root=None, section=None): > if section in (None, 'paths'): > # expand vars and ~ > # translate paths relative to root (or home) into absolute paths > root = root or pycompat.getcwd() > -for c in self._tcfg, self._ucfg, self._ocfg: > +for c in self._cfg.values(): > for n, p in c.items('paths'): > # Ignore sub-options. > if ':' in n: > @@ -345,21 +348,22 @@ > self._trustgroups.update(self.configlist('trusted', 'groups')) > > def backupconfig(self, section, item): > -return (self._ocfg.backup(section, item), > -self._tcfg.backup(section, item), > -self._ucfg.backup(section, item),) > +return {k: cfg.backup(section, item) for k, cfg in self._cfg.items()} > + > def restoreconfig(self, data): > -self._ocfg.restore(data[0]) > -self._tcfg.restore(data[1]) > -self._ucfg.restore(data[2]) > +for k, d in data.items(): > +self._cfg[k].restore(d) > > def setconfig(self, section, name, value, source=''): > -for cfg in (self._ocfg, self._tcfg, self._ucfg): > +for cfg in self._cfg.values(): > cfg.set(section, name, value, source) > self.fixconfig(section=section) > > def _data(self, untrusted): > -return untrusted and self._ucfg or self._tcfg > +if untrusted: > +return self._cfg['user'] > +else: > +return self._cfg['trusted'] > > def configsource(self, section, name, untrusted=False): > return self._data(untrusted).source(section, name) > @@ -380,7
[PATCH 4 of 4] py3: convert log opts to bytes-key dict
# HG changeset patch # User Yuya Nishihara# Date 1489483439 -32400 # Tue Mar 14 18:23:59 2017 +0900 # Node ID d32b1cfe597ebe2093c42b67e85143190eda0e8b # Parent 9a758c848fe08e97386fca95d2428aa003939b4d py3: convert log opts to bytes-key dict Now simple log command works. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3393,6 +3393,7 @@ def log(ui, repo, *pats, **opts): Returns 0 on success. """ +opts = pycompat.byteskwargs(opts) if opts.get('follow') and opts.get('rev'): opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))] del opts['follow'] diff --git a/tests/test-check-py3-commands.t b/tests/test-check-py3-commands.t --- a/tests/test-check-py3-commands.t +++ b/tests/test-check-py3-commands.t @@ -52,7 +52,7 @@ out some potential warnings that come fr $ $PYTHON3 $HGBIN files | wc -l \s*15 (re) -Test if `hg tip` works: +Test if log-like commands work: $ $PYTHON3 $HGBIN tip changeset: 10:e76ed1e480ef @@ -62,6 +62,13 @@ Test if `hg tip` works: summary: Fix linking of changeset revs when merging + $ $PYTHON3 $HGBIN log -r0 + changeset: 0:9117c6561b0b + user:m...@selenic.com + date:Tue May 03 13:16:10 2005 -0800 + summary: Add back links from file revisions to changeset revisions + + $ cd .. #endif ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 4] py3: call codecs.escape_decode() directly
# HG changeset patch # User Yuya Nishihara# Date 1489762102 -32400 # Fri Mar 17 23:48:22 2017 +0900 # Node ID 49922515f01eae376dcc9af7b04d450d301e4782 # Parent fa032607ed52a0ba605bb4c496426ffb01b09c54 py3: call codecs.escape_decode() directly The same rule as 3b7a6941a6ef applies. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -2138,7 +2138,7 @@ def escapestr(s): return codecs.escape_encode(s)[0] def unescapestr(s): -return s.decode('string_escape') +return codecs.escape_decode(s)[0] def uirepr(s): # Avoid double backslash in Windows path repr() ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4] util: wrap s.decode('string_escape') calls for future py3 compatibility
# HG changeset patch # User Yuya Nishihara# Date 1489761766 -32400 # Fri Mar 17 23:42:46 2017 +0900 # Node ID fa032607ed52a0ba605bb4c496426ffb01b09c54 # Parent 96929bd6e58d29bc3d44e1db7c1283f224bd1dc1 util: wrap s.decode('string_escape') calls for future py3 compatibility diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -32,7 +32,7 @@ def _string_escape(text): >>> s 'ab\\ncdn\\x00ab\\rcd\\n' >>> res = _string_escape(s) ->>> s == res.decode('string_escape') +>>> s == util.unescapestr(res) True """ # subset of the string_escape codec @@ -57,7 +57,7 @@ def decodeextra(text): l = l.replace('', '\n') l = l.replace('\\0', '\0') l = l.replace('\n', '') -k, v = l.decode('string_escape').split(':', 1) +k, v = util.unescapestr(l).split(':', 1) extra[k] = v return extra diff --git a/mercurial/parser.py b/mercurial/parser.py --- a/mercurial/parser.py +++ b/mercurial/parser.py @@ -19,7 +19,10 @@ from __future__ import absolute_import from .i18n import _ -from . import error +from . import ( +error, +util, +) class parser(object): def __init__(self, elements, methods=None): @@ -164,7 +167,7 @@ def buildargsdict(trees, funcname, argsp def unescapestr(s): try: -return s.decode("string_escape") +return util.unescapestr(s) except ValueError as e: # mangle Python's exception into our format raise error.ParseError(str(e).lower()) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -2137,6 +2137,9 @@ def escapestr(s): # Python 3 compatibility return codecs.escape_encode(s)[0] +def unescapestr(s): +return s.decode('string_escape') + def uirepr(s): # Avoid double backslash in Windows path repr() return repr(s).replace('', '\\') ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5507] New: Merge fails with "assert sf not in data['diverge']"
https://bz.mercurial-scm.org/show_bug.cgi?id=5507 Bug ID: 5507 Summary: Merge fails with "assert sf not in data['diverge']" Product: Mercurial Version: 4.1 Hardware: PC OS: Linux Status: UNCONFIRMED Severity: bug Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: abys...@gmail.com CC: mercurial-devel@mercurial-scm.org I try to merge default to my branch with: $ hg merge default And I get the following stacktrace: https://bpaste.net/show/45075be0d7de Can't produce some minimal test-case - the original repo is private. If I disable copy trace via config, the merge is successful. -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] py3: change explicit conversion from str to pycompat.bytestr
On Fri, 17 Mar 2017 19:14:26 +0530, Rishabh Madan wrote: > # HG changeset patch > # User Rishabh Madan> # Date 1489758142 -19800 > # Fri Mar 17 19:12:22 2017 +0530 > # Node ID 3d6d9294e2247316541942c4bec5186cb5772cd6 > # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 > py3: change explicit conversion from str to pycompat.bytestr Queued this, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] pager: skip running the pager if it's set to 'cat'
On Wed, 15 Mar 2017 21:44:26 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler> # Date 1489624466 14400 > # Wed Mar 15 20:34:26 2017 -0400 > # Node ID bc0c38ec3f7be807607d4fdf871f344e7079d992 > # Parent 07d488f16da6e12b225d2827f1020f32c8050a7a > pager: skip running the pager if it's set to 'cat' The series looks good, queued, thanks. I have no strong feeling about 'cat' thing. I hope nobody would install nyancat as cat. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] merge: add `internal:dumpjson` tool to `resolve`, which outputs conflict state
On Tue, 7 Mar 2017 11:40:59 -0800, Phil Cohen wrote: > # HG changeset patch > # User Phil Cohen> # Date 1488915535 28800 > # Tue Mar 07 11:38:55 2017 -0800 > # Node ID bbce62e3790220f19e7b37160a2f8351b7461272 > # Parent 91e86a6c61c0c6a3b554eefeba906311aa29 > merge: add `internal:dumpjson` tool to `resolve`, which outputs conflict state > +if opts.get('tool', '') == "internal:dumpjson": > +fm = ui.formatter('resolve', {'template': 'json'}) > +ms = mergemod.mergestate.read(repo) > +m = scmutil.match(repo[None], pats, opts) > +wctx = repo[None] > + > +paths = [] > +for f in ms: > +if not m(f): > +continue > + > +val = ms.internaldump(f, wctx) > +if val is not None: > +paths.append(val) > + > +fm.startitem() > +fm.write('conflicts', '%s\n', paths) > +fm.end() It doesn't make sense to use the formatter to dump a single object. Perhaps formatter._jsonifyobj() can be a public utility function. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH py3] global: add __bool__ to every class defining __nonzero__
On Mon, 13 Mar 2017 12:40:49 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc> # Date 1489434014 25200 > # Mon Mar 13 12:40:14 2017 -0700 > # Node ID a00f6470c72774efa74b04ed46e5d0918224de0a > # Parent e6b177a3a7662366e8af0ba07ccbd9509a8cc647 > global: add __bool__ to every class defining __nonzero__ > > __nonzero__ was renamed to __bool__ in Python 3. This patch simply > aliases __bool__ to __nonzero__ for every class implementing > __nonzero__. Got check-code error. I've adjusted the rule to not catch __bool__ aliases. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH py3] global: add __bool__ to every class defining __nonzero__
On Mon, 13 Mar 2017 12:40:49 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc> # Date 1489434014 25200 > # Mon Mar 13 12:40:14 2017 -0700 > # Node ID a00f6470c72774efa74b04ed46e5d0918224de0a > # Parent e6b177a3a7662366e8af0ba07ccbd9509a8cc647 > global: add __bool__ to every class defining __nonzero__ > > __nonzero__ was renamed to __bool__ in Python 3. This patch simply > aliases __bool__ to __nonzero__ for every class implementing > __nonzero__. Seems fine. Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 01 of 11] bdiff: use Python memory allocator in fixws
On Thu, 16 Mar 2017 09:27:14 -0700, Gregory Szorc wrote: > On Wed, Mar 15, 2017 at 11:16 PM, Jun Wuwrote: > > > Excerpts from Jun Wu's message of 2017-03-15 23:15:13 -0700: > > > I think it makes sense to migrate Python modules to PyMem_*. > > > > > > However, I'm also a bit conservative about the "calloc" perf issue > > mentioned > > > by Yuya. I think it's safe to take Patch 1, 2, 4, 5 where there is no > > calloc > > > > Sorry, it should be "Patch 1, 2, 4, and 6", not 5. I cannot count. > > > > I agree with not taking the patches that remove calloc(). I'm pretty sure > we don't actually need to zero the memory in some (all?) of those > instances. But I can deal with that in a follow-up series. Queued 1, 2, 4, and 6. Thanks for summing up. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] wfile: fix deprecation warning version
On Thu, 16 Mar 2017 11:24:31 -0700, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David> # Date 1489688275 25200 > # Thu Mar 16 11:17:55 2017 -0700 > # Node ID d26d5987f6ef6a8a260f2aef67838a66b9fe > # Parent b2fb0fd239b88f0f9ec70c43f30d2f1ef0cb1049 > # EXP-Topic fix-depr > # Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ > # hg pull > https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r d26d5987f6ef > wfile: fix deprecation warning version Sure, queued thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] py3: change explicit conversion from str to bytes
# HG changeset patch # User Rishabh Madan# Date 1489746142 -19800 # Fri Mar 17 15:52:22 2017 +0530 # Node ID 2aac5780c5b3c30602ca128cfeb6e38a42f2c0fb # Parent a5bad127128d8f60060be53d161acfa7a32a17d5 py3: change explicit conversion from str to bytes diff -r a5bad127128d -r 2aac5780c5b3 mercurial/commands.py --- a/mercurial/commands.py Wed Mar 15 15:48:57 2017 -0700 +++ b/mercurial/commands.py Fri Mar 17 15:52:22 2017 +0530 @@ -1813,7 +1813,7 @@ matched = False for section, name, value in ui.walkconfig(untrusted=untrusted): source = ui.configsource(section, name, untrusted) -value = str(value) +value = bytes(value) if fm.isplain(): source = source or 'none' value = value.replace('\n', '\\n') ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 STABLE] exchange: reject new compression engines for v1 bundles (issue5506)
At Thu, 16 Mar 2017 12:33:33 -0700, Gregory Szorc wrote: > > # HG changeset patch > # User Gregory Szorc> # Date 1489692236 25200 > # Thu Mar 16 12:23:56 2017 -0700 > # Branch stable > # Node ID 8fed20619acd7a4346408e5819a1c91c52a39ed2 > # Parent 86cd1f2cfff5d5f5ebda227b147ad71a59058323 > exchange: reject new compression engines for v1 bundles (issue5506) LGTM. Thank you for quick fixing ! > Version 1 bundles only support a fixed set of compression engines. > Before this change, we would accept any compression engine for v1 > bundles, even those that may not work on v1. This could lead to > an error. > > We define a fixed set of compression engines known to work with v1 > bundles and we add checking to ensure a newer engine (like zstd) > won't work with v1 bundles. > > I also took the liberty of adding test coverage for unknown compression > names because I noticed we didn't have coverage of it before. > > diff --git a/mercurial/exchange.py b/mercurial/exchange.py > --- a/mercurial/exchange.py > +++ b/mercurial/exchange.py > @@ -44,6 +44,9 @@ urlreq = util.urlreq > 'bundle2': '02', #legacy > } > > +# Compression engines allowed in version 1. THIS SHOULD NEVER CHANGE. > +_bundlespecv1compengines = set(['gzip', 'bzip2', 'none']) > + > def parsebundlespec(repo, spec, strict=True, externalnames=False): > """Parse a bundle string specification into parts. > > @@ -139,6 +142,12 @@ def parsebundlespec(repo, spec, strict=T > raise error.UnsupportedBundleSpecification( > _('%s is not a recognized bundle specification') % spec) > > +# Bundle version 1 only supports a known set of compression engines. > +if version == 'v1' and compression not in _bundlespecv1compengines: > +raise error.UnsupportedBundleSpecification( > +_('compression engine %s is not supported on v1 bundles') % > +compression) > + > # The specification for packed1 can optionally declare the data formats > # required to apply it. If we see this metadata, compare against what the > # repo supports and error if the bundle isn't compatible. > diff --git a/tests/test-bundle-type.t b/tests/test-bundle-type.t > --- a/tests/test-bundle-type.t > +++ b/tests/test-bundle-type.t > @@ -33,6 +33,23 @@ bundle w/o type option >summary: a >$ cd .. > > +Unknown compression type is rejected > + > + $ hg init t3 > + $ cd t3 > + $ hg -q pull ../b1 > + $ hg bundle -a -t unknown out.hg > + abort: unknown is not a recognized bundle specification > + (see 'hg help bundle' for supported values for --type) > + [255] > + > + $ hg bundle -a -t unknown-v2 out.hg > + abort: unknown compression is not supported > + (see 'hg help bundle' for supported values for --type) > + [255] > + > + $ cd .. > + > test bundle types > >$ testbundle() { > @@ -164,6 +181,23 @@ Compression level can be adjusted for bu >c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf >zstd-v2 > > + > +Explicit request for zstd on non-generaldelta repos > + > + $ hg --config format.usegeneraldelta=false init nogd > + $ hg -q -R nogd pull t1 > + $ hg -R nogd bundle -a -t zstd nogd-zstd > + abort: compression engine zstd is not supported on v1 bundles > + (see 'hg help bundle' for supported values for --type) > + [255] > + > +zstd-v1 always fails > + > + $ hg -R tzstd bundle -a -t zstd-v1 zstd-v1 > + abort: compression engine zstd is not supported on v1 bundles > + (see 'hg help bundle' for supported values for --type) > + [255] > + > #else > > zstd is a valid engine but isn't available > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel -- -- [FUJIWARA Katsunori] fo...@lares.dti.ne.jp ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] merge: add `internal:dumpjson` tool to `resolve`, which outputs conflict state
I agree with pretty much all of that. Short standardized names that represent universal concepts in the codebase (like p1) are very useful. To steal Siracusa's description of Perl, it is a bit like Huffman coding: make the common case easy and short, and the more unusual case longer and more descriptive. From: Jun Wu Sent: Thursday, March 16, 2017 8:15 PM To: Jun Wu Cc: Phil Cohen; Ryan McElroy; Durham Goode; mercurial-devel Subject: Re: [PATCH V2] merge: add `internal:dumpjson` tool to `resolve`, which outputs conflict state Fix a cat typing. Excerpts from Jun Wu's message of 2017-03-16 20:12:28 -0700: > Just to add some notes on variable names. There are some very common short > names. Like "p1" representing "parent1". And "p1" should be preferred. An > incomplete list is at [1]. It's okay to use "fname" hetlridvnvrtrtf ^^^ or "fn" instead of > "filename". > > FWIW, Ruby community standard prefers longer names while Golang explicitly > prefers shorter names [2]. I think both are reasonable, as long as the code > is consistent. > > For less-common things like "fca", "fco", etc. Longer names are definitely > better. For common objects like "matcher", "manifest", I think either is > okay. Since we are unlikely to rename "p1" to "parent1", I personally prefer > shorter ones for unambiguous common objects, especially when it can reduce > line wraps. > > [1]: https://www.mercurial-scm.org/wiki/CodingStyle CodingStyle - Mercurial www.mercurial-scm.org 1. Introduction. This page is intended to save new developers a few round-trips when contributing changes. It doesn't cover everything, but it does cover some of the ... > [2]: https://github.com/golang/go/wiki/CodeReviewComments#variable-names https://avatars1.githubusercontent.com/u/4314092?v=3=400 CodeReviewComments · golang/go Wiki · GitHub github.com The former declares a nil slice value, while the latter is non-nil but zero-length. They are functionally equivalent—their len and cap are both zero—but the nil ... > > Excerpts from Phil Cohen's message of 2017-03-16 19:32:44 -0700: > > Thanks a lot for the points re: variable names! I'm actually really > > happy to hear that -- these names were taken from elsewhere in the > > codebase, and they were very confusing. I have forgotten/had to relearn > > the difference between fcd/fca/fco/etc several times. Glad to hear that > > slightly longer/clearer names are encouraged. > > > > On 3/15/17 11:20 PM, Ryan McElroy wrote: > > > More nits inline to consider since you're looking into a v3 anyway... > > > > > > > > > On 3/15/17 10:48 AM, Durham Goode wrote: > > >> > > >> > > >> On 3/7/17 11:40 AM, Phil Cohen wrote: > > >>> # HG changeset patch > > >>> # User Phil Cohen> > >>> # Date 1488915535 28800 > > >>> # Tue Mar 07 11:38:55 2017 -0800 > > >>> # Node ID bbce62e3790220f19e7b37160a2f8351b7461272 > > >>> # Parent 91e86a6c61c0c6a3b554eefeba906311aa29 > > >>> merge: add `internal:dumpjson` tool to `resolve`, which outputs > > >>> conflict state > > >>> > > >>> This supersedes a previous change which added a --prep option. > > >> > > >> Generally we don't reference previous iterations of the patch in the > > >> commit message, since those previous iterations wont' show up in the > > >> repo after this is pushed. > > >> > > >>> Normally, `hg resolve` takes the user on a whistle-stop tour of each > > >>> conflicted > > >>> file, pausing to launch the editor to resolve the conflicts. This is an > > >>> alternative workflow for resolving many conflicts in a random-access > > >>> fashion. It > > >>> doesn't change/replace the default behavior. > > >>> > > >>> This commit adds `--tool=internal:dumpjson`. It prints, for each > > >>> conflict, the > > >>> "base", "other", and "ours" versions (the contents, as well as their > > >>> exec/link > > >>> flags), and where the user/tool should write a resolved version > > >>> (i.e., the > > >>> working copy) as JSON. The user will then resolve the conflicts at > > >>> their leisure > > >>> and run `hg resolve --mark`. > > >> > > >> Overall I think it looks good. Some minor comments inline, but I'd be > > >> ok having this queued (since it's been sitting here a while) and > > >> addressing the nits in a follow up. > > >> > > >>> diff --git a/mercurial/commands.py b/mercurial/commands.py > > >>> --- a/mercurial/commands.py > > >>> +++ b/mercurial/commands.py > > >>> @@ -33,6 +33,7 @@ > > >>> error, > > >>> exchange, > > >>> extensions, > > >>> + formatter, > > >>> graphmod, > > >>> hbisect, > > >>> help, > > >>> @@ -4284,6 +4285,26 @@ > > >>> fm.end() > > >>> return 0 > > >>> > > >>> + if opts.get('tool', '') == "internal:dumpjson": > > >>> + fm = ui.formatter('resolve', {'template': 'json'}) > > >>> + ms =