Re: [PATCH 10 of 13 V3] config: list environment variables in debug output
On Wed, Mar 22, 2017 at 10:23 AM, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1489455351 25200 > # Mon Mar 13 18:35:51 2017 -0700 > # Node ID fa6d527d03e29efc75591e1721ddcbd6b72e4a76 > # Parent 6c04717d3b4958800a39fdf6e2c28e2caf6629bd > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > fa6d527d03e2 > config: list environment variables in debug output > > So we can verify the feature in tests. > > diff --git a/mercurial/commands.py b/mercurial/commands.py > --- a/mercurial/commands.py > +++ b/mercurial/commands.py > @@ -1803,6 +1803,12 @@ def config(ui, repo, *values, **opts): > ui.pager('config') > fm = ui.formatter('config', opts) > -for f in scmutil.rcpath(): > -ui.debug('read config from: %s\n' % f) > +for (t, f) in scmutil.rccomponents(): nit: we usually don't include the parens around tuples (I think this applies to an earlier patch too) > +if t == 'path': > +ui.debug('read config from: %s\n' % f) > +elif t == 'items' and f: > +for item in f: > +source = item[3] > +ui.debug('set config by: %s\n' % source) > + > untrusted = bool(opts.get('untrusted')) > if values: > diff --git a/tests/test-hgrc.t b/tests/test-hgrc.t > --- a/tests/test-hgrc.t > +++ b/tests/test-hgrc.t > @@ -177,4 +177,18 @@ plain hgrc >--quiet: ui.quiet=False > > +with environment variables > + > + $ PAGER=p1 EDITOR=e1 VISUAL=e2 hg showconfig --debug > + set config by: $EDITOR > + set config by: $VISUAL > + set config by: $PAGER > + read config from: $TESTTMP/hgrc > + repo: bundle.mainreporoot=$TESTTMP > + $PAGER: pager.pager=p1 > + $VISUAL: ui.editor=e2 > + --verbose: ui.verbose=False > + --debug: ui.debug=True > + --quiet: ui.quiet=False > + > plain mode with exceptions > > ___ > 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 09 of 13 V3] ui: use scmutil.rccomponents to load configs (BC)
On Wed, Mar 22, 2017 at 10:23 AM, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1489462886 25200 > # Mon Mar 13 20:41:26 2017 -0700 > # Node ID 6c04717d3b4958800a39fdf6e2c28e2caf6629bd > # Parent c537d04829a8dc0b88fe03ec41e95a85638c696b > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 6c04717d3b49 > ui: use scmutil.rccomponents to load configs (BC) > > This is BC because system configs won't be able to override $EDITOR, $PAGER. > The new behavior is arguably more rational. > > The code added is somehow temporary. Once we have immutable config objects, > this area will be cleaner. > > diff --git a/mercurial/ui.py b/mercurial/ui.py > --- a/mercurial/ui.py > +++ b/mercurial/ui.py > @@ -212,6 +212,19 @@ class ui(object): > u = cls() > # we always trust global config files Do you know what this comment refers to? Should it be moved a few lines down now (I'm thinking maybe just before u.readconfig())? > -for f in scmutil.rcpath(): > -u.readconfig(f, trust=True) > +for (t, f) in scmutil.rccomponents(): > +if t == 'path': > +u.readconfig(f, trust=True) > +elif t == 'items': > +sections = set() > +for section, name, value, source in f: > +# do not set ocfg > +# XXX change this once we have immutable config objects > +u._tcfg.set(section, name, value, source) > +u._ucfg.set(section, name, value, source) > +sections.add(section) > +for section in sections: > +u.fixconfig(section=section) > +else: > +raise error.ProgrammingError('unexpected rccomponent: %s' % > t) > return u > > diff --git a/tests/test-config-env.py b/tests/test-config-env.py > new file mode 100644 > --- /dev/null > +++ b/tests/test-config-env.py > @@ -0,0 +1,48 @@ > +# Test the config layer generated by environment variables > + > +from __future__ import absolute_import, print_function > + > +import os > + > +from mercurial import ( > +encoding, > +scmutil, > +ui as uimod, > +) > + > +testtmp = encoding.environ['TESTTMP'] > + > +# prepare hgrc files > +def join(name): > +return os.path.join(testtmp, name) > + > +with open(join('sysrc'), 'w') as f: > +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') > + > +with open(join('userrc'), 'w') as f: > +f.write('[ui]\neditor=e1') > + > +# replace rcpath functions so they point to the files above > +def systemrcpath(): > +return [join('sysrc')] > + > +def userrcpath(): > +return [join('userrc')] > + > +scmutil.systemrcpath = systemrcpath > +scmutil.userrcpath = userrcpath > +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc > + > +# utility to print configs > +def printconfigs(env): > +encoding.environ = env > +scmutil._rccomponents = None # reset cache > +ui = uimod.ui.load() > +for section, name, value in ui.walkconfig(): > +source = ui.configsource(section, name) > +print('%s.%s=%s # %s' % (section, name, value, source)) > +print('') > + > +# environment variable overrides > +printconfigs({}) > +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) > diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out > new file mode 100644 > --- /dev/null > +++ b/tests/test-config-env.py.out > @@ -0,0 +1,6 @@ > +pager.pager=p0 # $TESTTMP/sysrc:4 > +ui.editor=e1 # $TESTTMP/userrc:2 > + > +pager.pager=p2 # $PAGER > +ui.editor=e1 # $TESTTMP/userrc:2 > + > diff --git a/tests/test-config.t b/tests/test-config.t > --- a/tests/test-config.t > +++ b/tests/test-config.t > @@ -165,2 +165,16 @@ edit failure >abort: edit failed: false exited with status 1 >[255] > + > +config affected by environment variables > + > + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' > + $VISUAL: ui.editor=e2 > + > + $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor' > + --config: ui.editor=e3 > + > + $ PAGER=p1 hg config --debug | grep 'pager\.pager' > + $PAGER: pager.pager=p1 > + > + $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep 'pager\.pager' > + --config: pager.pager=p2 > ___ > 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 07 of 13 V3] scmutil: extract rc.d listing function from rccomponents
On Wed, Mar 22, 2017 at 10:23 AM, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1490201429 25200 > # Wed Mar 22 09:50:29 2017 -0700 > # Node ID d604e5baed4ac2f5470860bff89728c282d71e3a > # Parent 44c865487bfd2f081bfb322b1fb1b700d57f7adf > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > d604e5baed4a > scmutil: extract rc.d listing function from rccomponents > > This is suggested by dsop and makes the code cleaner. A side effect is > "normpath" will be called on paths in $HGRCPATH, which seems to be more > correct. Is that last part still true? It looks like pathize() is called on all paths even in the preimage, and I believe pathize() calls normpath(). I'm thinking that maybe the commit message is outdated. > > diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py > --- a/mercurial/scmutil.py > +++ b/mercurial/scmutil.py > @@ -452,4 +452,13 @@ def rcpath(): > _rccomponents = None > > +def _expandrcpath(path): > +'''path could be a file or a directory. return a list of file paths''' > +p = util.expandpath(path) > +join = os.path.join > +if os.path.isdir(p): > +return [join(p, f) for f, k in osutil.listdir(p) if > f.endswith('.rc')] > +else: > +return [p] > + > def rccomponents(): > '''return an ordered [(type, obj)] about where to load configs. > @@ -478,11 +487,5 @@ def rccomponents(): > if not p: > continue > -p = util.expandpath(p) > -if os.path.isdir(p): > -for f, kind in osutil.listdir(p): > -if f.endswith('.rc'): > -_rccomponents.append(pathize(os.path.join(p, f))) > -else: > -_rccomponents.append(pathize(p)) > +_rccomponents.extend(map(pathize, _expandrcpath(p))) > else: > _rccomponents = map(pathize, defaultrcpath() + systemrcpath()) > ___ > 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 01 of 13 V3] scmutil: add a method to convert environment variables to config items
On Wed, Mar 22, 2017 at 10:23 AM, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1489449998 25200 > # Mon Mar 13 17:06:38 2017 -0700 > # Node ID 04259bd73d263306f16e25bd4e6bc53faf80911c > # Parent 55c6788c54e2faf80ec14f2b0844bfe429012bc3 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 04259bd73d26 > scmutil: add a method to convert environment variables to config items First of all, thanks for working on this! I just have a comment on the structure of of this series for now. This is the current structure: [01] scmutil: add a method to convert environment variables to config items [02] scmutil: define a list of configs overriding system rc, but not users [03] scmutil: split osrcpath to return default.d paths (API) [04] scmutil: copy rcpath to rcpath2 [05] scmutil: use _rccomponents in rcpath2 [06] scmutil: implement rccomponents to return multiple config sources [07] scmutil: extract rc.d listing function from rccomponents [08] run-tests: drop environment variables affecting configs [09] ui: use scmutil.rccomponents to load configs (BC) [10] config: list environment variables in debug output [11] scmutil: remove rcpath (API) [12] ui: simplify geteditor [13] pager: do not read from environment variable Patches 1,2,4,5,6,7 all introduce and/or update dead code (AFAICT). The dead code becomes live only in patch 9. This is a common pattern on this list, so I may very well be a minority in disliking it, but I do really dislike it. When reviewing the patches, I end up looking at the description, then I ignore the content and go to the next patch, because I don't yet know how the added code will be used. And since there are no tests exercising it, it doesn't really matter if it's working or not anyway, so it's safe to ignore it. Then, when I get to patch that hooks things up (patch 9 in this case), I have to try to recall the commit messages of all the previous patches to understand what all the things that changed were. Again, the structure you follow is common on this list, so maybe most people don't have the problem I have with it (and also, I don't mean to pick on you; this series was just an example). I would really have preferred something like this (and since I haven't followed all the changes in the patches, it may very well not work as I think it would): [01] scmutil: extract rc.d listing function from rccomponents [02] scmutil: split osrcpath to return default.d paths (API) [03] scmutil: rename rcpath to rccomponents (API) [04] scmutil: implement rccomponents to return multiple config sources [05] run-tests: drop environment variables affecting configs [06] config: let env variables override system hgrc (BC) [07] config: list environment variables in debug output [08] ui: simplify geteditor [09] pager: do not read from environment variable Patch 6 above would be a fold of your patches 1,2, and 9, so it would be a larger patch to review. However, as I tried to explain above, that's effectively what I review at that point anyway, and having it all in one patch makes it much easier for me as a reviewer. I'm sure there there are things I missed that make the above not quite possible, but hopefully it's close enough to possible that you at least get the idea. And then you get to decide what to do with the idea, of course :-) Perhaps you decide that it's a bad idea. Or perhaps you decide it has some value, and you consider it for next time. Again, this is directed not only at Jun. I'm happy to hear what others think as well. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] help: format ``commands`` heading correctly
# HG changeset patch # User Martin von Zweigbergk # Date 1490225813 25200 # Wed Mar 22 16:36:53 2017 -0700 # Node ID cd99f61579194767aaa958a29d8de88e639d1578 # Parent 55c6788c54e2faf80ec14f2b0844bfe429012bc3 help: format ``commands`` heading correctly The number of dashes under it needs to match exactly for it to be rendered as a heading. Without this change, the dashes end up on the same line as "commands", and "hg help config.commands" does not work. diff -r 55c6788c54e2 -r cd99f6157919 mercurial/help/config.txt --- a/mercurial/help/config.txt Tue Mar 21 22:47:49 2017 -0700 +++ b/mercurial/help/config.txt Wed Mar 22 16:36:53 2017 -0700 @@ -415,7 +415,7 @@ extension). ``commands`` --- + ``update.requiredest`` Require that the user pass a destination when running ``hg update``. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@31573: 9 new changesets
9 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/553ad16b274f changeset: 31565:553ad16b274f user:Augie Fackler date:Sun Mar 19 01:03:53 2017 -0400 summary: revsetlang: portably turn int into bytestring https://www.mercurial-scm.org/repo/hg/rev/c6df6a23dfe5 changeset: 31566:c6df6a23dfe5 user:Gregory Szorc date:Tue Mar 21 22:20:11 2017 -0700 summary: pycompat: alias urlreq.unquote to unquote_to_bytes https://www.mercurial-scm.org/repo/hg/rev/4ebecf331d7d changeset: 31567:4ebecf331d7d user:Gregory Szorc date:Tue Mar 21 22:23:11 2017 -0700 summary: util: use urlreq.unquote https://www.mercurial-scm.org/repo/hg/rev/6c9772867344 changeset: 31568:6c9772867344 user:Gregory Szorc date:Tue Mar 21 22:28:16 2017 -0700 summary: pycompat: remove urlunquote alias https://www.mercurial-scm.org/repo/hg/rev/e68932dfbb55 changeset: 31569:e68932dfbb55 user:Gregory Szorc date:Tue Mar 21 22:34:17 2017 -0700 summary: pycompat: define urlreq.urlparse and urlreq.unparse aliases https://www.mercurial-scm.org/repo/hg/rev/29fcfb981324 changeset: 31570:29fcfb981324 user:Gregory Szorc date:Tue Mar 21 22:39:52 2017 -0700 summary: bugzilla: use util.urlreq.urlparse https://www.mercurial-scm.org/repo/hg/rev/b2a41a826d71 changeset: 31571:b2a41a826d71 user:Gregory Szorc date:Tue Mar 21 22:45:02 2017 -0700 summary: tests: use urlreq in tinyproxy.py https://www.mercurial-scm.org/repo/hg/rev/c0c4e14ee597 changeset: 31572:c0c4e14ee597 user:Gregory Szorc date:Tue Mar 21 22:46:17 2017 -0700 summary: check-code: recommend util.urlreq when importing urlparse https://www.mercurial-scm.org/repo/hg/rev/55c6788c54e2 changeset: 31573:55c6788c54e2 bookmark:@ tag: tip user:Gregory Szorc date:Tue Mar 21 22:47:49 2017 -0700 summary: py3: stop exporting urlparse from pycompat and util (API) -- 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 4 of 4 V2] obsolete: allow cycles
Jun Wu writes: > Excerpts from Sean Farley's message of 2017-03-22 13:18:29 -0700: >> Heh, yes, that made me chuckle. I understand that *you* need this. > > I'd argue *most people* wants this. See below. > >> But that's the thing. I'm not taking "inhibit" into consideration >> because inhibit isn't a common workflow. It's completely a facebook >> thing. > > If you could look a bit ahead, commends like "unamend", "unstrip", > "unabsorb" and "undo" in general will basically need the stuff. > > I guess Bitbucket don't have the data about how much demand users want those > commands, since they are power-user only and need complex manual setup. But > we ship commands like "unamend" and friends we have data and feedback that > those commands are great and in high demand. Evolve doesn't even have the terminology finished. What you are basing this on is, in my opinion, a very advanced and Facebook specific workflow. > You may argue it's still Facebook-specific. But I don't see why "unamend" > has any fb-specific bit. The demand of those commands is universal. > >> > this approach not only >> > simplifies things *greatly*, it also handles the case much cleanly and with >> > much more confidence. If we count the removal lines in inhibit and all >> > kinds >> > of code supporting it, I'm sure there will be much more deleted lines than >> > added. That is a decent clean-up. How could you define it as >> > "over-engineering" ? >> >> I think that's a discussion for another time. >> >> > If you had good points indicating that "inhibit" is a reasonable permanent >> > solution and provides a good user experience, then I'd be happy to drop the >> > series. If you do so, be prepared with questions about all kinds of corner >> > cases. >> > >> > By the way, I'm not sure if you have noticed that "inhibit" was recently >> > moved to a directory called "hack/" in mutable-history. >> >> Yes, things in evolve are still baking. I don't see the need to rush obs >> cycles into core based on that, though. > > Shall we have "unamend", "unrebase", "unhistedit" and "undo" ready, please > do not use them as you don't need them. But that's part of the problem: all the edge cases mentioned here will affect normal use of obs markers. Why not put this in an extension for now? I don't see how this is more important than fixing terminology / error messages / UI / UX / etc etc etc. That being said, my questions weren't really for you. I am not a leader here. My questions are for the steering committee and the rest of the community. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4 V2] obsolete: allow cycles
Excerpts from Sean Farley's message of 2017-03-22 13:18:29 -0700: > Heh, yes, that made me chuckle. I understand that *you* need this. I'd argue *most people* wants this. See below. > But that's the thing. I'm not taking "inhibit" into consideration > because inhibit isn't a common workflow. It's completely a facebook > thing. If you could look a bit ahead, commends like "unamend", "unstrip", "unabsorb" and "undo" in general will basically need the stuff. I guess Bitbucket don't have the data about how much demand users want those commands, since they are power-user only and need complex manual setup. But we ship commands like "unamend" and friends we have data and feedback that those commands are great and in high demand. You may argue it's still Facebook-specific. But I don't see why "unamend" has any fb-specific bit. The demand of those commands is universal. > > this approach not only > > simplifies things *greatly*, it also handles the case much cleanly and with > > much more confidence. If we count the removal lines in inhibit and all kinds > > of code supporting it, I'm sure there will be much more deleted lines than > > added. That is a decent clean-up. How could you define it as > > "over-engineering" ? > > I think that's a discussion for another time. > > > If you had good points indicating that "inhibit" is a reasonable permanent > > solution and provides a good user experience, then I'd be happy to drop the > > series. If you do so, be prepared with questions about all kinds of corner > > cases. > > > > By the way, I'm not sure if you have noticed that "inhibit" was recently > > moved to a directory called "hack/" in mutable-history. > > Yes, things in evolve are still baking. I don't see the need to rush obs > cycles into core based on that, though. Shall we have "unamend", "unrebase", "unhistedit" and "undo" ready, please do not use them as you don't need them. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] convert: Fix the handling of empty changlist descriptions in P4
David Soria Parra writes: > # HG changeset patch > # User David Soria Parra > # Date 1490209978 18000 > # Wed Mar 22 14:12:58 2017 -0500 > # Node ID ff24a4168c2f05fd367b0b126e52559ef89af77f > # Parent 102f291807c92864a2231e5e925d6cd64783bb59 > convert: Fix the handling of empty changlist descriptions in P4 Looks like a good patch. Only minor nits in my review. 'F' in "Fix" should be 'f'. > Empty changelist descriptions are valid in Perforce. If we encounter one of > them we are currently running into an IndexError. In case of empty commit > messages set the commit message to **empty changelist description**, which > follows Perforce terminology. > > diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py > --- a/hgext/convert/p4.py > +++ b/hgext/convert/p4.py > @@ -161,7 +161,12 @@ > d = self._fetch_revision(change) > c = self._construct_commit(d, parents) > > -shortdesc = c.desc.splitlines(True)[0].rstrip('\r\n') > +descarr = c.desc.splitlines(True) > +if len(descarr) > 0: > +shortdesc = descarr[0].rstrip('\r\n') > +else: > +shortdesc = '**empty changelist description**' We usually write this as: shortdesc = '**empty changelist description**' descarr = c.desc.splitlines(True) if len(descarr) > 0: shortdesc = descarr[0].rstrip('\r\n') But that's probably not worth sending again. More of an FYI. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4 V2] obsolete: allow cycles
Jun Wu writes: > Excerpts from Sean Farley's message of 2017-03-22 11:58:34 -0700: >> Let's take a step back for a minute. Technical discussions aside (and >> they are, indeed, very technical), is this a feature that we should be >> concentrating on *right now*? > > Yes. Right now. For example, At Facebook we use "inhibit" to implement > "umamend" and has tons of code to support all kinds of corner cases. And it > still is not prefect. Heh, yes, that made me chuckle. I understand that *you* need this. > This tens of lines will allow us to get rid of those hacky code (and > "inhibit" all together). > >> I worry that evolve is already too complicated and we haven't done the >> first tasks of bringing bits of it into core. I've overheard from some >> Bitbucket co-workers (that prefer to not chime in)[1] that it's getting >> a bit out of hand with everyone implementing every single niche feature >> they want and no one seems to be around to herd these cats. > > The fact that the evolve version of "unamend" or "unstrip (touch)" changing > commit hashes is "complicated" to explian to end-users. So although > the code is slightly more complicated, the end-user experience is much > better. I think it's worthy. > > Besides, if you take "inhibit" into consideration, But that's the thing. I'm not taking "inhibit" into consideration because inhibit isn't a common workflow. It's completely a facebook thing. > this approach not only > simplifies things *greatly*, it also handles the case much cleanly and with > much more confidence. If we count the removal lines in inhibit and all kinds > of code supporting it, I'm sure there will be much more deleted lines than > added. That is a decent clean-up. How could you define it as > "over-engineering" ? I think that's a discussion for another time. > If you had good points indicating that "inhibit" is a reasonable permanent > solution and provides a good user experience, then I'd be happy to drop the > series. If you do so, be prepared with questions about all kinds of corner > cases. > > By the way, I'm not sure if you have noticed that "inhibit" was recently > moved to a directory called "hack/" in mutable-history. Yes, things in evolve are still baking. I don't see the need to rush obs cycles into core based on that, though. ___ 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
> It doesn't make sense to use the formatter to dump a single object. Perhaps > formatter._jsonifyobj() can be a public utility function. That's a good idea. If there are no objections I'll send that out, either as the first change in the next version or a isolated change (probably the former so I can depend on it here). On Fri, Mar 17, 2017 at 7:08 AM, Yuya Nishihara wrote: > 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 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4 V2] obsolete: allow cycles
Excerpts from Sean Farley's message of 2017-03-22 11:58:34 -0700: > Let's take a step back for a minute. Technical discussions aside (and > they are, indeed, very technical), is this a feature that we should be > concentrating on *right now*? Yes. Right now. For example, At Facebook we use "inhibit" to implement "umamend" and has tons of code to support all kinds of corner cases. And it still is not prefect. This tens of lines will allow us to get rid of those hacky code (and "inhibit" all together). > I worry that evolve is already too complicated and we haven't done the > first tasks of bringing bits of it into core. I've overheard from some > Bitbucket co-workers (that prefer to not chime in)[1] that it's getting > a bit out of hand with everyone implementing every single niche feature > they want and no one seems to be around to herd these cats. The fact that the evolve version of "unamend" or "unstrip (touch)" changing commit hashes is "complicated" to explian to end-users. So although the code is slightly more complicated, the end-user experience is much better. I think it's worthy. Besides, if you take "inhibit" into consideration, this approach not only simplifies things *greatly*, it also handles the case much cleanly and with much more confidence. If we count the removal lines in inhibit and all kinds of code supporting it, I'm sure there will be much more deleted lines than added. That is a decent clean-up. How could you define it as "over-engineering" ? If you had good points indicating that "inhibit" is a reasonable permanent solution and provides a good user experience, then I'd be happy to drop the series. If you do so, be prepared with questions about all kinds of corner cases. By the way, I'm not sure if you have noticed that "inhibit" was recently moved to a directory called "hack/" in mutable-history. > If this feature is really, really needed, then fine. My only purpose > here is to ask the current leaders: in all honesty, how will we, as a > community, avoid over-engineering Mercurial into JIRA? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] convert: Fix the handling of empty changlist descriptions in P4
# HG changeset patch # User David Soria Parra # Date 1490209978 18000 # Wed Mar 22 14:12:58 2017 -0500 # Node ID ff24a4168c2f05fd367b0b126e52559ef89af77f # Parent 102f291807c92864a2231e5e925d6cd64783bb59 convert: Fix the handling of empty changlist descriptions in P4 Empty changelist descriptions are valid in Perforce. If we encounter one of them we are currently running into an IndexError. In case of empty commit messages set the commit message to **empty changelist description**, which follows Perforce terminology. diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py --- a/hgext/convert/p4.py +++ b/hgext/convert/p4.py @@ -161,7 +161,12 @@ d = self._fetch_revision(change) c = self._construct_commit(d, parents) -shortdesc = c.desc.splitlines(True)[0].rstrip('\r\n') +descarr = c.desc.splitlines(True) +if len(descarr) > 0: +shortdesc = descarr[0].rstrip('\r\n') +else: +shortdesc = '**empty changelist description**' + t = '%s %s' % (c.rev, repr(shortdesc)[1:-1]) ui.status(util.ellipsis(t, 80) + '\n') 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 @@ -141,5 +141,23 @@ rev=1 desc="change a" tags="" files="a" rev=0 desc="initial" tags="" files="a b/c" +empty commit message + $ p4 edit a + //depot/test-mercurial-import/a#3 - opened for edit + $ echo a >> a + $ p4 submit -d "" + Submitting change 6. + Locking 1 files ... + edit //depot/test-mercurial-import/a#4 + Change 6 submitted. + $ hg convert -s p4 $DEPOTPATH dst + scanning source... + reading p4 views + collecting p4 changelists + 6 **empty changelist description** + sorting... + converting... + 0 + exit trap: stopping the p4 server ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 4 V2] obsolete: allow cycles
Jun Wu writes: > Excerpts from Gregory Szorc's message of 2017-03-21 21:25:03 -0700: >> Correct me if I'm wrong, but can't incorrect clocks result in the "wrong" >> version of a changeset being visible? For example, I'm working on different >> machines and pushing changes to a central server. I create divergence then >> correct it later via various obsolescence markers. But, because of clocks, > > Let's look at an example of divergence: > > o C (amended from A) > | > | o B (amended from A) > |/ > x A > > If you see the above divergence in one machine, fix it by "hg prune B -s C", > and verify the fix on that machine, then the fix could be applied globally. > That means, if the related markers are sent to elsewhere, the fix will be > observed elsewhere as expected. > > If the clock was wrong, what you may notice is "hg prune" looks like a > no-op. But it does not unhide things. > > In this case only "A" is hidden, since you are not creating markers > involving "A" to resolve the divergence, nothing gets "unhidden". > > > I'm trying to construct a case that you may be concerned about, to explain > the difference caused by date: > > o C (amended from B) > | (marker 2.2) > o B (amended from A)| x B (amended from A) > | (marker 1.1)|/(marker 2.1) > x A x A > > Machine 1 Machine 2 > > Then if Machine 1 gets markers from Machine 2, if marker 1.1 is newer than > marker 2.1, B stays visible and is a divergence. You may think "B" should be > hidden, but that's also explainable. Think about the following order: > > 1. hg amend # A -> B > 2. hg amend # B -> C > 3. hg update --hidden -r A; ...; hg amend # A -> B > > If "3" is the latest operation, it has the intention to make whatever it > creates visible - that's B. And that creates a divergence. > > The key here is the order of operation 2 and 3. If 2 happens after 3, then B > gets hidden as expected. Currently, this cycle will get both B and C hidden, > which I don't think is a sane behavior. > >> the "wrong" changeset is unhidden and I unknowingly start basing new work >> on it instead of the "correct" changeset. I accidentally land a predecessor >> because I assumed obsolescence "just worked" and introduce a subtle bug in >> the process. >> >> What are the processes in place to prevent this from happening? How will a >> power user even know to use a power command to fix the situation? > > They will notice an hg command looks like a no-op. And we may be able to > print some friendly help about how to fix it, or just write a faked date > automatically with a warning. > >> > >> > Not to mention most systems have sane clocks, >> >> This is dangerous to believe. >> >> Anecdotally, I've experienced the following problems on just the machines I >> use day-to-day: >> >> * An old battery on a motherboard caused the system clock to go haywire, >> drifing so fast that the default ntp configuration failed to readjust the >> clock fast enough, leading to clock skew on the order of several minutes. >> Other times, the system would boot up without any persisted time, thinking >> it was at some epoch. This resulted in mtimes decades in the past. >> >> * Hyper-V attempts to adjust the system clock inside running Linux VMs by >> default. Windows was on California time but the Linux VM was on UTC. The >> timezones conflicts and every few seconds Hyper-V and something in systemd >> would race to fix the system time. The system time bounced around 7 hours >> at a time. >> >> * Virtual machines (in Virtualbox IIRC) resumed after hibernate with the >> system time from when they were powered down. It took several seconds or >> minutes for NTP or some other process to kick in to adjust the VM's clock >> to reality. >> >> And these problems all occurred on machines with internet connectivity. >> Could you imagine what would happen if they weren't able to communicate >> with an NTP server? > > As I said, the worst case is only about visibility - no repo corruption, no > data loss, no broken consistency (ex. two synchronized repos have different > understanding about things). And visibility is possible to fix by simply > adding markers. Let's take a step back for a minute. Technical discussions aside (and they are, indeed, very technical), is this a feature that we should be concentrating on *right now*? I worry that evolve is already too complicated and we haven't done the first tasks of bringing bits of it into core. I've overheard from some Bitbucket co-workers (that prefer to not chime in)[1] that it's getting a bit out of hand with everyone implementing every single niche feature they want and no one seems to be around to herd these cats. If this feature is really, really needed, then fine. My only purpose here is to ask the current leaders: in a
Re: [PATCH] fancyopts: making config defaults actually override defaults
On Wed, Mar 22, 2017 at 10:14 AM, Rodrigo Damazio wrote: > On Wed, Mar 22, 2017 at 3:50 AM, Ryan McElroy wrote: >> >> Rodrigo: for some reason, patchwork thinks you are Martin. Any idea why? >> https://patchwork.mercurial-scm.org/patch/19133/ > > No idea, but I'm using a script he created for mailing patches directly to > gmail's backend servers (to avoid reformatting) - Martin, any chance you > hardcoded your own address there? :) Nope. IIUC, patchwork has decided to associate any email from mercurial-devel@mercurial-scm.org with me, because it probably first received one from there from me. And the reason it is from mercurial-devel@mercurial-scm.org in the first place is because we (Google) set the DMARC/SPF/whatever headers to prevent spoofing of @google.com addresses, so the mailing list has no choice but to rewrite it as coming from the mailing list itself. I may very well have misunderstood how that works, but hopefully you get the idea anyway. > >> On 3/14/17 10:16 PM, Rodrigo Damazio via Mercurial-devel wrote: >> >> On Tue, Mar 14, 2017 at 12:50 PM, David Soria Parra >> wrote: >>> >>> On Sat, Mar 11, 2017 at 06:03:30PM -0800, Rodrigo Damazio Bovendorp via >>> Mercurial-devel wrote: >>> > # HG changeset patch >>> > # User Rodrigo Damazio >>> > # Date 1489274373 28800 >>> > # Sat Mar 11 15:19:33 2017 -0800 >>> > # Node ID 8c833b81a994e2d3304c3b06793f536355528aab >>> > # Parent 62939e0148f170b67ca8c7374f36c413b67fd387 >>> > fancyopts: making config defaults actually override defaults >>> > >>> >>> Overall this LGTM, and clearly makes defaults much better :). My concern >>> is that we are encouraging the use of defaults again, while they are >>> deprecated. Defaults have inherent problems that they overwrite arguments >>> which might be mutable exclusive with others (e.g. --graph in incoming >>> and outgoing), or lead to undesired behavior if it's set by an admin. an >>> exmaple >>> is if you would specifiy defaults.update.check=True, the user will not >>> find an >>> --no-check option in the help message or anywhere else. This is not a >>> problem if >>> we assume defaults are alway set by the user and he knows about them. >> >> >> Thanks for the review. >> >> Yes, we discussed the update --check case specifically during Sprint: >> https://public.etherpad-mozilla.org/p/sprint-hg4.2 >> (search for "Flags and defaults breakout") >> >> >> Note that I copied the notes over the the wiki for posterity: >> https://www.mercurial-scm.org/wiki/4.2sprint/Notes >> >> If people do some cleanup passes and categorization, that would be useful. >> I may contribute here at some point as well. >> >> >> The conclusion was that this gains us the ability to do proper single-flag >> overrides, which is good, but doesn't solve all the issues. There are other >> changes we also want to make flags and defaults useful again: >> - make the passed-in flag values not be simple primitive types, but rather >> enhance them with addition information about where the value is coming from, >> so commands like update can decide that an explicit --clean overrides a >> system default of --check, and should only fail if both come from the same >> level >> - we want to add a --no- counterflag for every flag, not just booleans, as >> a way to unset it (useful for revision-specifying flags for instance) >> - we want to add environment variables to the stack of overrides along >> with the different levels of config files and command-line arguments >> - we want to try making all positional arguments map to flags (e.g. "hg >> update 123" would be equivalent to "hg update -r 123" by making 123 be >> passed to the command as the -r flag, also allowing config overrides for >> those) >> - we want to investigate why we support callables in flag defaults, and >> remove support if that's not useful to anyone >> >> >> >> While I like this initial direction, I think this needs to be turned into >> a series of smaller steps, and we need more discussion around whether we >> will revive the defaults section or keep it deprecated. I'll drop this from >> patchwork for now while we discuss. > > > No problem. How/where/when/what would you like to discuss? > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 12 of 13 V3] ui: simplify geteditor
# HG changeset patch # User Jun Wu # Date 1489456194 25200 # Mon Mar 13 18:49:54 2017 -0700 # Node ID cc9d6ca646db2ee51920abdfd2f235b55e0f28d4 # Parent 486b23fa9d4e82b3d01aad8663895b5448f54d88 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r cc9d6ca646db ui: simplify geteditor Now $EDITOR and $VISUAL will affect ui.editor directly. The logic can be simplified. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1309,7 +1309,5 @@ class ui(object): editor = 'vi' return (encoding.environ.get("HGEDITOR") or -self.config("ui", "editor") or -encoding.environ.get("VISUAL") or -encoding.environ.get("EDITOR", editor)) +self.config("ui", "editor", editor)) @util.propertycache ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 13 of 13 V3] pager: do not read from environment variable
# HG changeset patch # User Jun Wu # Date 1489456112 25200 # Mon Mar 13 18:48:32 2017 -0700 # Node ID 0c20ac74b2405ab01d253e884bf64c9128307047 # Parent cc9d6ca646db2ee51920abdfd2f235b55e0f28d4 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 0c20ac74b240 pager: do not read from environment variable We have converted $PAGER to config, ui.pager() now can just read the config, without looking at environment variables. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -847,12 +847,6 @@ class ui(object): return -# TODO: add a "system defaults" config section so this default -# of more(1) can be easily replaced with a global -# configuration file. For example, on OS X the sane default is -# less(1), not more(1), and on debian it's -# sensible-pager(1). We should probably also give the system -# default editor command similar treatment. -envpager = encoding.environ.get('PAGER', 'more') -pagercmd = self.config('pager', 'pager', envpager) +fallbackpager = 'more' +pagercmd = self.config('pager', 'pager', fallbackpager) if not pagercmd: return ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 10 of 13 V3] config: list environment variables in debug output
# HG changeset patch # User Jun Wu # Date 1489455351 25200 # Mon Mar 13 18:35:51 2017 -0700 # Node ID fa6d527d03e29efc75591e1721ddcbd6b72e4a76 # Parent 6c04717d3b4958800a39fdf6e2c28e2caf6629bd # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r fa6d527d03e2 config: list environment variables in debug output So we can verify the feature in tests. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1803,6 +1803,12 @@ def config(ui, repo, *values, **opts): ui.pager('config') fm = ui.formatter('config', opts) -for f in scmutil.rcpath(): -ui.debug('read config from: %s\n' % f) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +ui.debug('read config from: %s\n' % f) +elif t == 'items' and f: +for item in f: +source = item[3] +ui.debug('set config by: %s\n' % source) + untrusted = bool(opts.get('untrusted')) if values: diff --git a/tests/test-hgrc.t b/tests/test-hgrc.t --- a/tests/test-hgrc.t +++ b/tests/test-hgrc.t @@ -177,4 +177,18 @@ plain hgrc --quiet: ui.quiet=False +with environment variables + + $ PAGER=p1 EDITOR=e1 VISUAL=e2 hg showconfig --debug + set config by: $EDITOR + set config by: $VISUAL + set config by: $PAGER + read config from: $TESTTMP/hgrc + repo: bundle.mainreporoot=$TESTTMP + $PAGER: pager.pager=p1 + $VISUAL: ui.editor=e2 + --verbose: ui.verbose=False + --debug: ui.debug=True + --quiet: ui.quiet=False + plain mode with exceptions ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 11 of 13 V3] scmutil: remove rcpath (API)
# HG changeset patch # User Jun Wu # Date 1489455385 25200 # Mon Mar 13 18:36:25 2017 -0700 # Node ID 486b23fa9d4e82b3d01aad8663895b5448f54d88 # Parent fa6d527d03e29efc75591e1721ddcbd6b72e4a76 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 486b23fa9d4e scmutil: remove rcpath (API) It's no longer used. Third-party code using it should consider using "rccomponents" instead. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -423,31 +423,4 @@ def envconfig(envlist, env=None): return result -_rcpath = None - -def rcpath(): -'''return hgrc search path. if env var HGRCPATH is set, use it. -for each item in path, if directory, use files ending in .rc, -else use item. -make HGRCPATH empty to only look in .hg/hgrc of current repo. -if no HGRCPATH, use default os-specific path.''' -global _rcpath -if _rcpath is None: -if 'HGRCPATH' in encoding.environ: -_rcpath = [] -for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): -if not p: -continue -p = util.expandpath(p) -if os.path.isdir(p): -for f, kind in osutil.listdir(p): -if f.endswith('.rc'): -_rcpath.append(os.path.join(p, f)) -else: -_rcpath.append(p) -else: -paths = defaultrcpath() + systemrcpath() + userrcpath() -_rcpath = map(os.path.normpath, paths) -return _rcpath - _rccomponents = None ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 09 of 13 V3] ui: use scmutil.rccomponents to load configs (BC)
# HG changeset patch # User Jun Wu # Date 1489462886 25200 # Mon Mar 13 20:41:26 2017 -0700 # Node ID 6c04717d3b4958800a39fdf6e2c28e2caf6629bd # Parent c537d04829a8dc0b88fe03ec41e95a85638c696b # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 6c04717d3b49 ui: use scmutil.rccomponents to load configs (BC) This is BC because system configs won't be able to override $EDITOR, $PAGER. The new behavior is arguably more rational. The code added is somehow temporary. Once we have immutable config objects, this area will be cleaner. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -212,6 +212,19 @@ class ui(object): u = cls() # we always trust global config files -for f in scmutil.rcpath(): -u.readconfig(f, trust=True) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +u.readconfig(f, trust=True) +elif t == 'items': +sections = set() +for section, name, value, source in f: +# do not set ocfg +# XXX change this once we have immutable config objects +u._tcfg.set(section, name, value, source) +u._ucfg.set(section, name, value, source) +sections.add(section) +for section in sections: +u.fixconfig(section=section) +else: +raise error.ProgrammingError('unexpected rccomponent: %s' % t) return u diff --git a/tests/test-config-env.py b/tests/test-config-env.py new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py @@ -0,0 +1,48 @@ +# Test the config layer generated by environment variables + +from __future__ import absolute_import, print_function + +import os + +from mercurial import ( +encoding, +scmutil, +ui as uimod, +) + +testtmp = encoding.environ['TESTTMP'] + +# prepare hgrc files +def join(name): +return os.path.join(testtmp, name) + +with open(join('sysrc'), 'w') as f: +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') + +with open(join('userrc'), 'w') as f: +f.write('[ui]\neditor=e1') + +# replace rcpath functions so they point to the files above +def systemrcpath(): +return [join('sysrc')] + +def userrcpath(): +return [join('userrc')] + +scmutil.systemrcpath = systemrcpath +scmutil.userrcpath = userrcpath +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc + +# utility to print configs +def printconfigs(env): +encoding.environ = env +scmutil._rccomponents = None # reset cache +ui = uimod.ui.load() +for section, name, value in ui.walkconfig(): +source = ui.configsource(section, name) +print('%s.%s=%s # %s' % (section, name, value, source)) +print('') + +# environment variable overrides +printconfigs({}) +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py.out @@ -0,0 +1,6 @@ +pager.pager=p0 # $TESTTMP/sysrc:4 +ui.editor=e1 # $TESTTMP/userrc:2 + +pager.pager=p2 # $PAGER +ui.editor=e1 # $TESTTMP/userrc:2 + diff --git a/tests/test-config.t b/tests/test-config.t --- a/tests/test-config.t +++ b/tests/test-config.t @@ -165,2 +165,16 @@ edit failure abort: edit failed: false exited with status 1 [255] + +config affected by environment variables + + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' + $VISUAL: ui.editor=e2 + + $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor' + --config: ui.editor=e3 + + $ PAGER=p1 hg config --debug | grep 'pager\.pager' + $PAGER: pager.pager=p1 + + $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep 'pager\.pager' + --config: pager.pager=p2 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 02 of 13 V3] scmutil: define a list of configs overriding system rc, but not users
# HG changeset patch # User Jun Wu # Date 1489450537 25200 # Mon Mar 13 17:15:37 2017 -0700 # Node ID 61757ff29df4a35351fd31568a14e0880dd5c2d4 # Parent 04259bd73d263306f16e25bd4e6bc53faf80911c # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 61757ff29df4 scmutil: define a list of configs overriding system rc, but not users It's mainly about pager and editor for now. That's the problem the series is trying to solve. We may move other things here later. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -405,4 +405,11 @@ def osrcpath(): return path +# environments overriding system configs but not user configs +_sysenvlist = [ +('EDITOR', 'ui', 'editor'), +('VISUAL', 'ui', 'editor'), +('PAGER', 'pager', 'pager'), +] + def envconfig(envlist, env=None): '''[(section, name, value, source)] extracted from environment variables ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 06 of 13 V3] scmutil: implement rccomponents to return multiple config sources
# HG changeset patch # User Jun Wu # Date 1490201209 25200 # Wed Mar 22 09:46:49 2017 -0700 # Node ID 44c865487bfd2f081bfb322b1fb1b700d57f7adf # Parent 0e0f8914507fc0030d66844bde77854266259603 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 44c865487bfd scmutil: implement rccomponents to return multiple config sources rcpath has the limitation that it only returns paths. Now we also have raw configs generated from environ. So rccomponents was added. It is similar to rcpath, but it can return mixed path and raw configs (currently calculated from environment variables). The code was basically copy-pasted from rcpath, and will be cleaned up a bit by the next patch. Python does not have union types or pattern matching. So we use a tuple (type, obj) to denote things of different types. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -452,14 +452,27 @@ def rcpath(): _rccomponents = None -def rcpath2(): -'''return hgrc search path. if env var HGRCPATH is set, use it. -for each item in path, if directory, use files ending in .rc, -else use item. -make HGRCPATH empty to only look in .hg/hgrc of current repo. -if no HGRCPATH, use default os-specific path.''' +def rccomponents(): +'''return an ordered [(type, obj)] about where to load configs. + +respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is +used. if $HGRCPATH is not set, the platform default will be used. + +if a directory is provided, *.rc files under it will be used. + +type could be either 'path' or 'items', if type is 'path', obj is a string, +and is the config file path. if type is 'items', obj is a list of (section, +name, value, source) that should fill the config directly. +''' +def pathize(path): +return ('path', os.path.normpath(path)) + +envrc = ('items', envconfig(_sysenvlist)) + global _rccomponents if _rccomponents is None: if 'HGRCPATH' in encoding.environ: -_rccomponents = [] +# assume HGRCPATH is all about user configs so environments can be +# overridden. +_rccomponents = [envrc] for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): if not p: @@ -469,10 +482,11 @@ def rcpath2(): for f, kind in osutil.listdir(p): if f.endswith('.rc'): -_rccomponents.append(os.path.join(p, f)) +_rccomponents.append(pathize(os.path.join(p, f))) else: -_rccomponents.append(p) +_rccomponents.append(pathize(p)) else: -paths = defaultrcpath() + systemrcpath() + userrcpath() -_rccomponents = map(os.path.normpath, paths) +_rccomponents = map(pathize, defaultrcpath() + systemrcpath()) +_rccomponents.append(envrc) +_rccomponents.extend(map(pathize, userrcpath())) return _rccomponents ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 08 of 13 V3] run-tests: drop environment variables affecting configs
# HG changeset patch # User Jun Wu # Date 1489455061 25200 # Mon Mar 13 18:31:01 2017 -0700 # Node ID c537d04829a8dc0b88fe03ec41e95a85638c696b # Parent d604e5baed4ac2f5470860bff89728c282d71e3a # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r c537d04829a8 run-tests: drop environment variables affecting configs Those environment variables can affect future tests. Drop them so tests run reliably. diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -908,4 +908,5 @@ class Test(unittest.TestCase): for k in ('HG HGPROF CDPATH GREP_OPTIONS http_proxy no_proxy ' + 'HGPLAIN HGPLAINEXCEPT ' + + 'EDITOR VISUAL PAGER ' + 'NO_PROXY CHGDEBUG').split(): if k in env: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 07 of 13 V3] scmutil: extract rc.d listing function from rccomponents
# HG changeset patch # User Jun Wu # Date 1490201429 25200 # Wed Mar 22 09:50:29 2017 -0700 # Node ID d604e5baed4ac2f5470860bff89728c282d71e3a # Parent 44c865487bfd2f081bfb322b1fb1b700d57f7adf # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r d604e5baed4a scmutil: extract rc.d listing function from rccomponents This is suggested by dsop and makes the code cleaner. A side effect is "normpath" will be called on paths in $HGRCPATH, which seems to be more correct. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -452,4 +452,13 @@ def rcpath(): _rccomponents = None +def _expandrcpath(path): +'''path could be a file or a directory. return a list of file paths''' +p = util.expandpath(path) +join = os.path.join +if os.path.isdir(p): +return [join(p, f) for f, k in osutil.listdir(p) if f.endswith('.rc')] +else: +return [p] + def rccomponents(): '''return an ordered [(type, obj)] about where to load configs. @@ -478,11 +487,5 @@ def rccomponents(): if not p: continue -p = util.expandpath(p) -if os.path.isdir(p): -for f, kind in osutil.listdir(p): -if f.endswith('.rc'): -_rccomponents.append(pathize(os.path.join(p, f))) -else: -_rccomponents.append(pathize(p)) +_rccomponents.extend(map(pathize, _expandrcpath(p))) else: _rccomponents = map(pathize, defaultrcpath() + systemrcpath()) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 05 of 13 V3] scmutil: use _rccomponents in rcpath2
# HG changeset patch # User Jun Wu # Date 1490200924 25200 # Wed Mar 22 09:42:04 2017 -0700 # Node ID 0e0f8914507fc0030d66844bde77854266259603 # Parent 8d3521684a9a290d547a90c5ecf6ebdccb72de57 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 0e0f8914507f scmutil: use _rccomponents in rcpath2 This is a rename to make the next patch easier to review. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -450,4 +450,6 @@ def rcpath(): return _rcpath +_rccomponents = None + def rcpath2(): '''return hgrc search path. if env var HGRCPATH is set, use it. @@ -456,8 +458,8 @@ def rcpath2(): make HGRCPATH empty to only look in .hg/hgrc of current repo. if no HGRCPATH, use default os-specific path.''' -global _rcpath -if _rcpath is None: +global _rccomponents +if _rccomponents is None: if 'HGRCPATH' in encoding.environ: -_rcpath = [] +_rccomponents = [] for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): if not p: @@ -467,11 +469,11 @@ def rcpath2(): for f, kind in osutil.listdir(p): if f.endswith('.rc'): -_rcpath.append(os.path.join(p, f)) +_rccomponents.append(os.path.join(p, f)) else: -_rcpath.append(p) +_rccomponents.append(p) else: paths = defaultrcpath() + systemrcpath() + userrcpath() -_rcpath = map(os.path.normpath, paths) -return _rcpath +_rccomponents = map(os.path.normpath, paths) +return _rccomponents def intrev(rev): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 04 of 13 V3] scmutil: copy rcpath to rcpath2
# HG changeset patch # User Jun Wu # Date 1490200924 25200 # Wed Mar 22 09:42:04 2017 -0700 # Node ID 8d3521684a9a290d547a90c5ecf6ebdccb72de57 # Parent ca711190cb22ea50baac89c75f1a621c67d5754f # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 8d3521684a9a scmutil: copy rcpath to rcpath2 This is temporary and makes the next patch easier to review. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -450,4 +450,29 @@ def rcpath(): return _rcpath +def rcpath2(): +'''return hgrc search path. if env var HGRCPATH is set, use it. +for each item in path, if directory, use files ending in .rc, +else use item. +make HGRCPATH empty to only look in .hg/hgrc of current repo. +if no HGRCPATH, use default os-specific path.''' +global _rcpath +if _rcpath is None: +if 'HGRCPATH' in encoding.environ: +_rcpath = [] +for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): +if not p: +continue +p = util.expandpath(p) +if os.path.isdir(p): +for f, kind in osutil.listdir(p): +if f.endswith('.rc'): +_rcpath.append(os.path.join(p, f)) +else: +_rcpath.append(p) +else: +paths = defaultrcpath() + systemrcpath() + userrcpath() +_rcpath = map(os.path.normpath, paths) +return _rcpath + def intrev(rev): """Return integer for a given revision that can be used in comparison or ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 01 of 13 V3] scmutil: add a method to convert environment variables to config items
# HG changeset patch # User Jun Wu # Date 1489449998 25200 # Mon Mar 13 17:06:38 2017 -0700 # Node ID 04259bd73d263306f16e25bd4e6bc53faf80911c # Parent 55c6788c54e2faf80ec14f2b0844bfe429012bc3 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 04259bd73d26 scmutil: add a method to convert environment variables to config items We will put this "config generated by environment variables" thing in a desired layer - ex. above system configs, below user configs. The method was designed to be reusable if we want more complex layers - like multiple environment-generated configs; or test environment configs using a different environ dict. The method seems to be more appropriate fitting here than "config.py" because "config.py" only has data structure and is unware of special actual config or environments. I think it's cleaner to keep config.py pure and free from environment or config names. The same applies to ui.fixconfig, trusted or untrusted handling, and likely "ui.compat" in the future. We may want to a new file like "uiconfig.py" if we want to make "ui.config" a thing and move logic aware of specific config items there. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -405,4 +405,18 @@ def osrcpath(): return path +def envconfig(envlist, env=None): +'''[(section, name, value, source)] extracted from environment variables + +envlist is a list of (envname, section, configname) +''' +if env is None: +env = encoding.environ +result = [] +for envname, section, configname in envlist: +if envname not in env: +continue +result.append((section, configname, env[envname], '$%s' % envname)) +return result + _rcpath = None ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 03 of 13 V3] scmutil: split osrcpath to return default.d paths (API)
# HG changeset patch # User Jun Wu # Date 1490165660 25200 # Tue Mar 21 23:54:20 2017 -0700 # Node ID ca711190cb22ea50baac89c75f1a621c67d5754f # Parent 61757ff29df4a35351fd31568a14e0880dd5c2d4 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r ca711190cb22 scmutil: split osrcpath to return default.d paths (API) After this change, there are 3 rcpath functions: - defaultrcpath - systemrcpath - userrcpath This will allow us to insert another config layer in the middle. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -392,6 +392,6 @@ def walkrepos(path, followsym=False, see dirs[:] = newdirs -def osrcpath(): -'''return default os-specific hgrc search path''' +def defaultrcpath(): +'''return rc paths in default.d''' path = [] defaultpath = os.path.join(util.datapath, 'default.d') @@ -400,7 +400,4 @@ def osrcpath(): if f.endswith('.rc'): path.append(os.path.join(defaultpath, f)) -path.extend(systemrcpath()) -path.extend(userrcpath()) -path = [os.path.normpath(f) for f in path] return path @@ -449,5 +446,6 @@ def rcpath(): _rcpath.append(p) else: -_rcpath = osrcpath() +paths = defaultrcpath() + systemrcpath() + userrcpath() +_rcpath = map(os.path.normpath, paths) return _rcpath ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] fancyopts: making config defaults actually override defaults
On Wed, Mar 22, 2017 at 3:50 AM, Ryan McElroy wrote: > Rodrigo: for some reason, patchwork thinks you are Martin. Any idea why? > https://patchwork.mercurial-scm.org/patch/19133/ > No idea, but I'm using a script he created for mailing patches directly to gmail's backend servers (to avoid reformatting) - Martin, any chance you hardcoded your own address there? :) On 3/14/17 10:16 PM, Rodrigo Damazio via Mercurial-devel wrote: > > On Tue, Mar 14, 2017 at 12:50 PM, David Soria Parra < > d...@experimentalworks.net> wrote: > >> On Sat, Mar 11, 2017 at 06:03:30PM -0800, Rodrigo Damazio Bovendorp via >> Mercurial-devel wrote: >> > # HG changeset patch >> > # User Rodrigo Damazio >> > # Date 1489274373 28800 >> > # Sat Mar 11 15:19:33 2017 -0800 >> > # Node ID 8c833b81a994e2d3304c3b06793f536355528aab >> > # Parent 62939e0148f170b67ca8c7374f36c413b67fd387 >> > fancyopts: making config defaults actually override defaults >> > >> >> Overall this LGTM, and clearly makes defaults much better :). My concern >> is that we are encouraging the use of defaults again, while they are >> deprecated. Defaults have inherent problems that they overwrite arguments >> which might be mutable exclusive with others (e.g. --graph in incoming >> and outgoing), or lead to undesired behavior if it's set by an admin. an >> exmaple >> is if you would specifiy defaults.update.check=True, the user will not >> find an >> --no-check option in the help message or anywhere else. This is not a >> problem if >> we assume defaults are alway set by the user and he knows about them. >> > > Thanks for the review. > > Yes, we discussed the update --check case specifically during Sprint: > https://public.etherpad-mozilla.org/p/sprint-hg4.2 > (search for "Flags and defaults breakout") > > > Note that I copied the notes over the the wiki for posterity: > https://www.mercurial-scm.org/wiki/4.2sprint/Notes > > If people do some cleanup passes and categorization, that would be useful. > I may contribute here at some point as well. > > > The conclusion was that this gains us the ability to do proper single-flag > overrides, which is good, but doesn't solve all the issues. There are other > changes we also want to make flags and defaults useful again: > - make the passed-in flag values not be simple primitive types, but rather > enhance them with addition information about where the value is coming > from, so commands like update can decide that an explicit --clean overrides > a system default of --check, and should only fail if both come from the > same level > - we want to add a --no- counterflag for every flag, not just booleans, as > a way to unset it (useful for revision-specifying flags for instance) > - we want to add environment variables to the stack of overrides along > with the different levels of config files and command-line arguments > - we want to try making all positional arguments map to flags (e.g. "hg > update 123" would be equivalent to "hg update -r 123" by making 123 be > passed to the command as the -r flag, also allowing config overrides for > those) > - we want to investigate why we support callables in flag defaults, and > remove support if that's not useful to anyone > > > > While I like this initial direction, I think this needs to be turned into > a series of smaller steps, and we need more discussion around whether we > will revive the defaults section or keep it deprecated. I'll drop this from > patchwork for now while we discuss. > No problem. How/where/when/what would you like to discuss? smime.p7s Description: S/MIME Cryptographic Signature ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 03 of 11 V2] scmutil: split osrcpath to return default.d paths
Excerpts from Martin von Zweigbergk's message of 2017-03-22 09:53:48 -0700: > Two related questions: > > 1) Should this patch be annotated with (API)? Good point. I'll add "(API)". > 2) Should this method be "private" (underscore-prefixed)? Since systemrcpath and userrcpath are public, I think it's more consistent if defaultrcpath is public. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 03 of 11 V2] scmutil: split osrcpath to return default.d paths
On Wed, Mar 22, 2017 at 12:50 AM, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1490165660 25200 > # Tue Mar 21 23:54:20 2017 -0700 > # Node ID 7775943a59cfaaae77e2143cbfa0bf0d8d95a447 > # Parent 5de0f85888f87c705bcbc38d3e92e97b7e23d1d9 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 7775943a59cf > scmutil: split osrcpath to return default.d paths > > After this change, there are 3 rcpath functions: > > - defaultrcpath > - systemrcpath > - userrcpath > > This will allow us to insert another config layer in the middle. > > diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py > --- a/mercurial/scmutil.py > +++ b/mercurial/scmutil.py > @@ -392,6 +392,6 @@ def walkrepos(path, followsym=False, see > dirs[:] = newdirs > > -def osrcpath(): > -'''return default os-specific hgrc search path''' > +def defaultrcpath(): Two related questions: 1) Should this patch be annotated with (API)? 2) Should this method be "private" (underscore-prefixed)? > +'''return rc paths in default.d''' > path = [] > defaultpath = os.path.join(util.datapath, 'default.d') > @@ -400,7 +400,4 @@ def osrcpath(): > if f.endswith('.rc'): > path.append(os.path.join(defaultpath, f)) > -path.extend(systemrcpath()) > -path.extend(userrcpath()) > -path = [os.path.normpath(f) for f in path] > return path > > @@ -449,5 +446,6 @@ def rcpath(): > _rcpath.append(p) > else: > -_rcpath = osrcpath() > +paths = defaultrcpath() + systemrcpath() + userrcpath() > +_rcpath = map(os.path.normpath, paths) > return _rcpath > > ___ > 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 05 of 11 V2] scmutil: extract path reading function from rccomponents
Excerpts from Ryan McElroy's message of 2017-03-22 11:30:37 +: > > + > > +def pathize(path): > > +return ('path', os.path.normpath(path)) > > + > > It seems that this patch and the last patch could be re-done to reduce > the number of churning lines, making both easier to review. For example, > why not introduce _readrcpath in it's own patch, then use it when you > create rccomponents? That would make each patch smaller and the overall > arc of this series more clear to me. "scmutil: extract path reading function from rccomponents" was suggested by dsop. The nice thing about the current arrangement is that if we drop "scmutil: extract path reading function from rccomponents", the code works and is not worse than it was before. I'm not sure reordering will make it easier to review because the function was copy-pasted from osrcpath. I can insert more patches to make the copy-paste explicit. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V2] checkheads: extract obsolete post processing in its own function
# HG changeset patch # User Pierre-Yves David # Date 1490135413 -3600 # Tue Mar 21 23:30:13 2017 +0100 # Node ID 72c820f77671d4495d96e7aeeba9237573dbce85 # Parent 66c3ae6d886cae0e3a3cff6a0058e2d2a866fd9d # EXP-Topic checkheads # Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ # hg pull https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r 72c820f77671 checkheads: extract obsolete post processing in its own function The checkheads function is long and complex, extract that logic in a subfunction is win in itself. As the comment in the code says, this postprocessing is currently very basic and either misbehave or fails to detect valid push in many cases. My deeper motive for this extraction is to be make it easier to provide extensive testing of this case and strategy to cover them. Final test and logic will makes it to core once done. diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -343,38 +343,13 @@ def checkheads(pushop): oldhs.update(unsyncedheads) candidate_newhs.update(unsyncedheads) dhs = None # delta heads, the new heads on branch -discardedheads = set() if not repo.obsstore: +discardedheads = set() newhs = candidate_newhs else: -# remove future heads which are actually obsoleted by another -# pushed element: -# -# XXX as above, There are several cases this code does not handle -# XXX properly -# -# (1) if is public, it won't be affected by obsolete marker -# and a new is created -# -# (2) if the new heads have ancestors which are not obsolete and -# not ancestors of any other heads we will have a new head too. -# -# These two cases will be easy to handle for known changeset but -# much more tricky for unsynced changes. -# -# In addition, this code is confused by prune as it only looks for -# successors of the heads (none if pruned) leading to issue4354 -newhs = set() -for nh in candidate_newhs: -if nh in repo and repo[nh].phase() <= phases.public: -newhs.add(nh) -else: -for suc in obsolete.allsuccessors(repo.obsstore, [nh]): -if suc != nh and suc in allfuturecommon: -discardedheads.add(nh) -break -else: -newhs.add(nh) +newhs, discardedheads = _postprocessobsolete(pushop, + allfuturecommon, + candidate_newhs) unsynced = sorted(h for h in unsyncedheads if h not in discardedheads) if unsynced: if None in unsynced: @@ -434,3 +409,42 @@ def checkheads(pushop): repo.ui.note((" %s\n") % short(h)) if errormsg: raise error.Abort(errormsg, hint=hint) + +def _postprocessobsolete(pushop, futurecommon, candidate_newhs): +"""post process the list of new heads with obsolescence information + +Exist as a subfunction to contains the complexity and allow extensions to +experiment with smarter logic. +Returns (newheads, discarded_heads) tuple +""" +# remove future heads which are actually obsoleted by another +# pushed element: +# +# XXX as above, There are several cases this code does not handle +# XXX properly +# +# (1) if is public, it won't be affected by obsolete marker +# and a new is created +# +# (2) if the new heads have ancestors which are not obsolete and +# not ancestors of any other heads we will have a new head too. +# +# These two cases will be easy to handle for known changeset but +# much more tricky for unsynced changes. +# +# In addition, this code is confused by prune as it only looks for +# successors of the heads (none if pruned) leading to issue4354 +repo = pushop.repo +newhs = set() +discarded = set() +for nh in candidate_newhs: +if nh in repo and repo[nh].phase() <= phases.public: +newhs.add(nh) +else: +for suc in obsolete.allsuccessors(repo.obsstore, [nh]): +if suc != nh and suc in futurecommon: +discarded.add(nh) +break +else: +newhs.add(nh) +return newhs, discarded ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 07 of 11 V2] ui: use scmutil.rccomponents to load configs (BC)
On 3/22/17 4:01 PM, Jun Wu wrote: Excerpts from Ryan McElroy's message of 2017-03-22 11:37:00 +: On 3/22/17 7:50 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1489462886 25200 # Mon Mar 13 20:41:26 2017 -0700 # Node ID add83f47bf3a51edbd58aa0fb6e571d186bdae6e # Parent df768455486ff51b4047fd3a8dfbef158516d2aa ui: use scmutil.rccomponents to load configs (BC) This is BC because system configs won't be able to override $EDITOR, $PAGER. The new behavior is arguably more rational. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -212,6 +212,18 @@ class ui(object): u = cls() # we always trust global config files -for f in scmutil.rcpath(): -u.readconfig(f, trust=True) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +u.readconfig(f, trust=True) +elif t == 'items': +sections = set() +for section, name, value, source in f: +# do not set ocfg +u._tcfg.set(section, name, value, source) +u._ucfg.set(section, name, value, source) +sections.add(section) +for section in sections: +u.fixconfig(section=section) +else: +raise error.ProgrammingError('unexpected rccomponent: %s' % t) return u Seeing this makes me not like this "union type" (rccomponents) that you've created. Can we do this differently for more cleanliness? The code here is temporary and will be rewritten once the immutable config becomes a thing. I will add a comment but not rewrite the temporary code. Consider instead of having rccomponents be a parsed config "source" (either a file or environment for now). Then this patch simply combines them in order. This gives us the nice property of reading each config file only once, which was a patch series that dsop sent but had BC issues, but doing it this way means there are no BC issues. Of course, it also cleans up this code so we don't have the type check in there. If I understand what you suggest, I think it could have issues with "%unset". Although that may be solved, but the immutable config will be a thing, so I'm not interested in improving to-be-deprecated code. I think unset could be accomplished with a "sentinel object" that we compare against to know if we should unset a value while applying partial configs. However, since you have a plan to improve config overall and you have a good track record of follow-through, I'll officially drop my objections to this approach. Essentially, envconfig() can be generalized into a "parsedconfig" container, and then it's just about ordering for the final config from there. I think this would make the code cleaner -- thoughts? diff --git a/tests/test-config-env.py b/tests/test-config-env.py new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py @@ -0,0 +1,48 @@ +# Test the config layer generated by environment variables + +from __future__ import absolute_import, print_function + +import os + +from mercurial import ( +encoding, +scmutil, +ui as uimod, +) + +testtmp = encoding.environ['TESTTMP'] + +# prepare hgrc files +def join(name): +return os.path.join(testtmp, name) + +with open(join('sysrc'), 'w') as f: +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') + +with open(join('userrc'), 'w') as f: +f.write('[ui]\neditor=e1') + +# replace rcpath functions so they point to the files above +def systemrcpath(): +return [join('sysrc')] + +def userrcpath(): +return [join('userrc')] + +scmutil.systemrcpath = systemrcpath +scmutil.userrcpath = userrcpath +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc + +# utility to print configs +def printconfigs(env): +encoding.environ = env +scmutil._rccomponents = None # reset cache +ui = uimod.ui.load() +for section, name, value in ui.walkconfig(): +source = ui.configsource(section, name) +print('%s.%s=%s # %s' % (section, name, value, source)) +print('') + +# environment variable overrides +printconfigs({}) +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py.out @@ -0,0 +1,6 @@ +pager.pager=p0 # $TESTTMP/sysrc:4 +ui.editor=e1 # $TESTTMP/userrc:2 + +pager.pager=p2 # $PAGER +ui.editor=e1 # $TESTTMP/userrc:2 + diff --git a/tests/test-config.t b/tests/test-config.t --- a/tests/test-config.t +++ b/tests/test-config.t @@ -165,2 +165,16 @@ edit failure abort: edit failed: false exited with status 1 [255] + +config affected by environment variables + + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' + $VISUAL: ui.editor=e2 + + $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor' + --config: ui.ed
Re: [PATCH] doc: fix short underline which causes make -C doc to fail
On 3/22/17 3:59 PM, Kostia Balytskyi wrote: # HG changeset patch # User Kostia Balytskyi # Date 1490198110 25200 # Wed Mar 22 08:55:10 2017 -0700 # Node ID 86383b66465bd7122bb5380047c6e87c888d8227 # Parent f808c796dfd2c6e4e6990c73a838320512aafeca doc: fix short underline which causes make -C doc to fail https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_hg-2Dcommitted_rev_79d98e1b21a7&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=XwlnUJ7Dm-i0fD3GxgWTBsbB8Z7wrRzm28VTv3swSy8&s=ICe_Z0HfgsVXfef1aAZy7kC_51u1Iimt8HqYWdV5Jzg&e= Generally we just use the commit hash, right? Can probably be updated in-flight. broke 'make -C doc' by not adding enough underline. This fixes it. My bad! Should this be checked in check-code? I broke it when I changed the name from 'behavior' to 'commands' I believe. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -415,7 +415,7 @@ effect and style see :hg:`help color`. extension). ``commands`` --- + ``update.requiredest`` Require that the user pass a destination when running ``hg update``. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2 V2] status: support commands.status.relative config
# HG changeset patch # User Martin von Zweigbergk # Date 1490143844 25200 # Tue Mar 21 17:50:44 2017 -0700 # Node ID 32fb4dfa78cb43ac9d6b42dcd9e8735bf02cefe4 # Parent 1ed5ec882c49934a16428fc72e7a366f39747cc5 status: support commands.status.relative config When the config is set to true, status output becomes relative to the working directory. This has bugged me since I started using hg and it turns it is sillily simple to support it (unless I missed something, of course). We could also add a --relative flag, but I would personally always want that on, and I haven't heard any use for having it sometimes on, so this patch only lets you enable it via config. diff -r 1ed5ec882c49 -r 32fb4dfa78cb mercurial/commands.py --- a/mercurial/commands.py Tue Mar 21 21:26:52 2017 -0700 +++ b/mercurial/commands.py Tue Mar 21 17:50:44 2017 -0700 @@ -4734,7 +4734,7 @@ else: node1, node2 = scmutil.revpair(repo, revs) -if pats: +if pats or ui.configbool('commands', 'status.relative'): cwd = repo.getcwd() else: cwd = '' diff -r 1ed5ec882c49 -r 32fb4dfa78cb mercurial/help/config.txt --- a/mercurial/help/config.txt Tue Mar 21 21:26:52 2017 -0700 +++ b/mercurial/help/config.txt Tue Mar 21 17:50:44 2017 -0700 @@ -417,6 +417,10 @@ ``commands`` -- +``status.relative`` +Make paths in ``hg status`` output relative to the current directory. +(default: False) + ``update.requiredest`` Require that the user pass a destination when running ``hg update``. For example, ``hg update .::`` will be allowed, but a plain ``hg update`` diff -r 1ed5ec882c49 -r 32fb4dfa78cb tests/test-status.t --- a/tests/test-status.t Tue Mar 21 21:26:52 2017 -0700 +++ b/tests/test-status.t Tue Mar 21 17:50:44 2017 -0700 @@ -107,6 +107,27 @@ ? a/in_a ? b/in_b +relative paths can be requested + + $ cat >> $HGRCPATH < [commands] + > status.relative = True + > EOF + $ hg status --cwd a + ? 1/in_a_1 + ? in_a + ? ../b/1/in_b_1 + ? ../b/2/in_b_2 + ? ../b/in_b + ? ../in_root + $ HGPLAIN=1 hg status --cwd a + ? a/1/in_a_1 + ? a/in_a + ? b/1/in_b_1 + ? b/2/in_b_2 + ? b/in_b + ? in_root + $ cd .. $ hg init repo2 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2 V2] plain: ignore [commands] config
# HG changeset patch # User Martin von Zweigbergk # Date 1490156812 25200 # Tue Mar 21 21:26:52 2017 -0700 # Node ID 1ed5ec882c49934a16428fc72e7a366f39747cc5 # Parent 55c6788c54e2faf80ec14f2b0844bfe429012bc3 plain: ignore [commands] config We only have commands.{update,rebase}.requiredest so far. We should clearly ignore those two if HGPLAIN is in effect, and it seems like we should ignore any future config that will be added in [commands] since that is about changing the behavior of commands. Thanks to Yuya for suggesting to centralize the code in ui.py. While at it, remove the unnecessary False values passed to ui.configbool() for the aforementioned config options. diff -r 55c6788c54e2 -r 1ed5ec882c49 hgext/rebase.py --- a/hgext/rebase.py Tue Mar 21 22:47:49 2017 -0700 +++ b/hgext/rebase.py Tue Mar 21 21:26:52 2017 -0700 @@ -686,7 +686,7 @@ # Validate input and define rebasing points destf = opts.get('dest', None) -if ui.config('commands', 'rebase.requiredest', False): +if ui.config('commands', 'rebase.requiredest'): if not destf: raise error.Abort(_('you must specify a destination'), hint=_('use: hg rebase -d REV')) diff -r 55c6788c54e2 -r 1ed5ec882c49 mercurial/commands.py --- a/mercurial/commands.py Tue Mar 21 22:47:49 2017 -0700 +++ b/mercurial/commands.py Tue Mar 21 21:26:52 2017 -0700 @@ -5349,7 +5349,7 @@ if rev and node: raise error.Abort(_("please specify just one revision")) -if ui.configbool('commands', 'update.requiredest', False): +if ui.configbool('commands', 'update.requiredest'): if not node and not rev and not date: raise error.Abort(_('you must specify a destination'), hint=_('for example: hg update ".::"')) diff -r 55c6788c54e2 -r 1ed5ec882c49 mercurial/ui.py --- a/mercurial/ui.py Tue Mar 21 22:47:49 2017 -0700 +++ b/mercurial/ui.py Tue Mar 21 21:26:52 2017 -0700 @@ -284,6 +284,8 @@ del cfg['ui'][k] for k, v in cfg.items('defaults'): del cfg['defaults'][k] +for k, v in cfg.items('commands'): +del cfg['commands'][k] # Don't remove aliases from the configuration if in the exceptionlist if self.plain('alias'): for k, v in cfg.items('alias'): diff -r 55c6788c54e2 -r 1ed5ec882c49 tests/test-rebase-base.t --- a/tests/test-rebase-base.t Tue Mar 21 22:47:49 2017 -0700 +++ b/tests/test-rebase-base.t Tue Mar 21 21:26:52 2017 -0700 @@ -413,3 +413,7 @@ $ hg rebase -d 1 rebasing 2:5db65b93a12b "cc" (tip) saved backup bundle to $TESTTMP/repo/.hg/strip-backup/5db65b93a12b-4fb789ec-backup.hg (glob) + $ hg rebase -d 0 -r . -q + $ HGPLAIN=1 hg rebase + rebasing 2:889b0bc6a730 "cc" (tip) + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/889b0bc6a730-41ec4f81-backup.hg (glob) diff -r 55c6788c54e2 -r 1ed5ec882c49 tests/test-update-names.t --- a/tests/test-update-names.t Tue Mar 21 22:47:49 2017 -0700 +++ b/tests/test-update-names.t Tue Mar 21 21:26:52 2017 -0700 @@ -104,3 +104,5 @@ [255] $ hg up . 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ HGPLAIN=1 hg up + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] status: support commands.status.relative config
On Wed, Mar 22, 2017 at 8:42 AM, Martin von Zweigbergk wrote: > On Wed, Mar 22, 2017 at 3:12 AM, Ryan McElroy wrote: >> I'm +100 on this patch. We've been doing this in tweakdefaults for ages. >> Everyone loves it. >> >> On 3/22/17 4:35 AM, Martin von Zweigbergk via Mercurial-devel wrote: >>> >>> # HG changeset patch >>> # User Martin von Zweigbergk >>> # Date 1490143844 25200 >>> # Tue Mar 21 17:50:44 2017 -0700 >>> # Node ID e0e123324f205071c80657079ff83a4e58db862c >>> # Parent 102f291807c92864a2231e5e925d6cd64783bb59 >>> status: support commands.status.relative config >>> >>> When the config is set to true, status output becomes relative to the >>> working directory. This has bugged me since I started using hg and it >>> turns it is sillily simple to support it (unless I missed something, >>> of course). >>> >>> We could also add a --relative flag, but I would personally always >>> want that on, and I haven't heard any use for having it sometimes on, >>> so this patch only lets you enable it via config. >>> >>> diff -r 102f291807c9 -r e0e123324f20 mercurial/commands.py >>> --- a/mercurial/commands.py Mon Mar 20 16:34:12 2017 -0700 >>> +++ b/mercurial/commands.py Tue Mar 21 17:50:44 2017 -0700 >>> @@ -4734,7 +4734,8 @@ >>> else: >>> node1, node2 = scmutil.revpair(repo, revs) >>> -if pats: >>> +if pats or (not ui.plain() and >>> +ui.configbool('commands', 'status.relative', False)): >> >> >> Style-nits: >> * The "false" isn't necessary -- that's the default, isn't it? > > Ah, thanks. (Guess where I inherited that from :-)) > >> * Also, I think it would be clearer to divide this into two lines: >> >> relative = not ui.plain and ui.configbool('commands', 'status.relative') >> if pats or relative: > > As Yuya pointed out, the ui.plain() should probably be done in one > place (in ui.py) for all [commands] config, which will make this a > little simpler. I still think your proposal is good, so I'll address > that in V2. Actually, after the "not ui.plain() and" and the unnecessary False were removed, it got pretty simple, so I'm leaving on one line. > >> >> >> >>> cwd = repo.getcwd() >>> else: >>> cwd = '' >>> diff -r 102f291807c9 -r e0e123324f20 mercurial/help/config.txt >>> --- a/mercurial/help/config.txt Mon Mar 20 16:34:12 2017 -0700 >>> +++ b/mercurial/help/config.txt Tue Mar 21 17:50:44 2017 -0700 >>> @@ -417,6 +417,10 @@ >>> ``commands`` >>> -- >>> +``status.relative`` >>> +Make paths in ``hg status`` output relative to the current directory. >>> +(default: False) >>> + >>> ``update.requiredest`` >>> Require that the user pass a destination when running ``hg update``. >>> For example, ``hg update .::`` will be allowed, but a plain ``hg >>> update`` >>> diff -r 102f291807c9 -r e0e123324f20 tests/test-status.t >>> --- a/tests/test-status.t Mon Mar 20 16:34:12 2017 -0700 >>> +++ b/tests/test-status.t Tue Mar 21 17:50:44 2017 -0700 >>> @@ -40,6 +40,20 @@ >>> ? ../b/2/in_b_2 >>> ? ../b/in_b >>> ? ../in_root >>> + $ hg --config commands.status.relative=True status --cwd a >>> + ? 1/in_a_1 >>> + ? in_a >>> + ? ../b/1/in_b_1 >>> + ? ../b/2/in_b_2 >>> + ? ../b/in_b >>> + ? ../in_root >>> + $ HGPLAIN=1 hg --config commands.status.relative=True status --cwd a >>> + ? a/1/in_a_1 >>> + ? a/in_a >>> + ? b/1/in_b_1 >>> + ? b/2/in_b_2 >>> + ? b/in_b >>> + ? in_root >>> $ hg status --cwd b >>> ? a/1/in_a_1 >>> >> ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 V2] formatter: reserve _ prefixed keys as internal and don't render
On 3/22/17 2:55 PM, Yuya Nishihara wrote: On Tue, 21 Mar 2017 23:49:25 -0700, Gregory Szorc wrote: # HG changeset patch # User Gregory Szorc # Date 1490164306 25200 # Tue Mar 21 23:31:46 2017 -0700 # Node ID ae796e23fd42b036352b298f570af8949c2db2d9 # Parent 102f291807c92864a2231e5e925d6cd64783bb59 formatter: reserve _ prefixed keys as internal and don't render As part of implementing `hg show`, Yuya noticed that JSON formatting was rendering an internal-only key, which was unfortunate. In this patch, I document new behavior on fm.data() that all keys beginning with underscores are reserved. I change the behavior of the JSON formatter to not render keys beginning with underscores. I ran the test suite with fm.data() raising if any key with a leading underscore was passed in and there were no test failures. So I think it is safe to adopt this convention. diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -176,7 +176,11 @@ class baseformatter(object): '''insert context objects to be used to render template keywords''' pass def data(self, **data): -'''insert data into item that's not shown in default output''' +'''insert data into item that's not shown in default output + +Keys beginning with '_' are designated as internal and may not be +rendered by all formatters. +''' self._item.update(data) def write(self, fields, deftext, *fielddata, **opts): '''do default text output while assigning data to item''' @@ -315,6 +319,9 @@ class jsonformatter(baseformatter): self._out.write("\n {\n") first = True for k, v in sorted(self._item.items()): +# Don't format hidden elements. +if k.startswith('_'): +continue The idea of using _ prefix seems okay, but I don't think internal keys should be usable in template. If "longestlen" should be available for user templates, it shouldn't be _-prefixed. This seems like a good time to bring up by long-held desire for a JSON template that allows specifying what keys you're interested in. This would solve this problem more suitably than internal name-munging. To expand, -T json is insufficient for some things, like requesting file adds from hg log, which might be slow to ask for in large repos. I'd like a syntax like: -T json(desc,fileadds) Of course, there could be a default set of fields the a bare -T json would expose, but you could override it with the passed set. Then, we simply take the _longest out of the default set, but it's still available if explicitly asked for -- which is good! Because then other tools can use these values as needed. So, overall I'm -0 on this approach, but I understand that perfection is the enemy of better, so I'd be okay getting this in until "someone" has time to add the custom keys functionality to json. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 5 of 6] osutil: add a C function getting filesystem type
Excerpts from Yuya Nishihara's message of 2017-03-22 23:38:17 +0900: > On Mon, 20 Mar 2017 17:04:38 -0700, Jun Wu wrote: > > # HG changeset patch > > # User Jun Wu > > # Date 1490052299 25200 > > # Mon Mar 20 16:24:59 2017 -0700 > > # Node ID f710d54d1985975d7d37aa58e9d5740ebdcf5b7b > > # Parent 8a3c7ac9923732e980a3660f0555c2e109ee93e0 > > # Available At https://bitbucket.org/quark-zju/hg-draft > > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > > f710d54d1985 > > osutil: add a C function getting filesystem type > > > +#ifdef EXT2_SUPER_MAGIC > > +if (buf.f_type == EXT2_SUPER_MAGIC) > > +return "ext2"; > > +#endif > > +#ifdef EXT3_SUPER_MAGIC > > +if (buf.f_type == EXT3_SUPER_MAGIC) > > +return "ext3"; > > +#endif > > +#ifdef EXT4_SUPER_MAGIC > > +if (buf.f_type == EXT4_SUPER_MAGIC) > > +return "ext4"; > > +#endif > > Just FYI, my /home drive was reported as ext2 since ext[234] magics are > identical. > > EXT2_SUPER_MAGIC 0xef53 > EXT3_SUPER_MAGIC 0xef53 > EXT4_SUPER_MAGIC 0xef53 > > Anyway, this series looks promising, thanks. Yeah, I noticed that when I was using "switch" and the compiler reported there are duplicated values. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] checkheads: extract obsolete post processing in its own function
On 03/22/2017 11:04 AM, Ryan McElroy wrote: On 3/21/17 10:42 PM, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David # Date 1490135413 -3600 # Tue Mar 21 23:30:13 2017 +0100 # Node ID 787354f0d60eccda66ba0de4db8e6e47897acc7c # Parent 66c3ae6d886cae0e3a3cff6a0058e2d2a866fd9d # EXP-Topic checkheads # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk&s=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk&s=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI&e= -r 787354f0d60e checkheads: extract obsolete post processing in its own function The checkheads function is long and complex, extract that logic in a subfunction is win in itself. I agree, this looks good to me. Actually, we should probably pass a the pushoperation instead of the repository. That logic will needs to poke at the remote repository (eg: Sean told me about a bug reported to bitbucket were this logic kicks in even if obsolescence markers are not going to be exchanged. V2 incoming. Cheers, -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] findrenames: sort files not by object id but by path for stable result
On 3/22/17 1:48 PM, Yuya Nishihara wrote: # HG changeset patch # User Yuya Nishihara # Date 1426413536 -32400 # Sun Mar 15 18:58:56 2015 +0900 # Node ID 425379e72e817b6c79e955173b015b9a0fe090e9 # Parent 102f291807c92864a2231e5e925d6cd64783bb59 findrenames: sort files not by object id but by path for stable result It seems the original implementation tried to sort added/removed files alphabetically, but actually it did sort fctx objects by address. This patch removes the use of set()s in order to preserve the order of added/removed files. addedfiles.remove() could be slightly slower than before, but it doesn't make much difference. ...except perhaps on a large number of files added/removed, right? Why not re-sort and move the possible O(n^2) to at worst O(n log n)? It doesn't seem like it would be too much more work to me. benchmark (on tmpfs): $ hg up -C 15afda349b11; hg purge --all; mv tests tests.new $ LANG=C hg --time addremove -n > /dev/null original: real 0.420 secs (user 0.390+0.000 sys 0.030+0.000) this patch: real 0.430 secs (user 0.390+0.000 sys 0.040+0.000) I think the algorithm scales O(n^2), so I'd be much more interested in a move of, say, 100k files than a move of 1 file that is dominated by startup time. diff --git a/mercurial/similar.py b/mercurial/similar.py --- a/mercurial/similar.py +++ b/mercurial/similar.py @@ -101,19 +101,18 @@ def findrenames(repo, added, removed, th # Zero length files will be frequently unrelated to each other, and # tracking the deletion/addition of such a file will probably cause more # harm than good. We strip them out here to avoid matching them later on. -addedfiles = set([workingctx[fp] for fp in added -if workingctx[fp].size() > 0]) -removedfiles = set([parentctx[fp] for fp in removed -if fp in parentctx and parentctx[fp].size() > 0]) +addedfiles = [workingctx[fp] for fp in sorted(added) + if workingctx[fp].size() > 0] +removedfiles = [parentctx[fp] for fp in sorted(removed) +if fp in parentctx and parentctx[fp].size() > 0] # Find exact matches. -for (a, b) in _findexactmatches(repo, -sorted(addedfiles), sorted(removedfiles)): +for (a, b) in _findexactmatches(repo, addedfiles[:], removedfiles): Since you're making a copy here anyway, why not do the removes from a set and then re-sort the set to a list afterwards? Should give us the "best of both worlds", right? I'll drop this change request if 100k moves isn't noticeably different in speed though. addedfiles.remove(b) yield (a.path(), b.path(), 1.0) # If the user requested similar files to be matched, search for them also. if threshold < 1.0: -for (a, b, score) in _findsimilarmatches(repo, -sorted(addedfiles), sorted(removedfiles), threshold): +for (a, b, score) in _findsimilarmatches(repo, addedfiles, + removedfiles, threshold): yield (a.path(), b.path(), score) diff --git a/tests/test-addremove-similar.t b/tests/test-addremove-similar.t --- a/tests/test-addremove-similar.t +++ b/tests/test-addremove-similar.t @@ -55,6 +55,57 @@ comparing two empty files caused ZeroDiv $ hg commit -m B +should be sorted by path for stable result + + $ for i in `python $TESTDIR/seq.py 0 9`; do + > cp small-file $i + > done + $ rm small-file + $ hg addremove + adding 0 + adding 1 + adding 2 + adding 3 + adding 4 + adding 5 + adding 6 + adding 7 + adding 8 + adding 9 + removing small-file + recording removal of small-file as rename to 0 (100% similar) + recording removal of small-file as rename to 1 (100% similar) + recording removal of small-file as rename to 2 (100% similar) + recording removal of small-file as rename to 3 (100% similar) + recording removal of small-file as rename to 4 (100% similar) + recording removal of small-file as rename to 5 (100% similar) + recording removal of small-file as rename to 6 (100% similar) + recording removal of small-file as rename to 7 (100% similar) + recording removal of small-file as rename to 8 (100% similar) + recording removal of small-file as rename to 9 (100% similar) + $ hg commit -m '10 same files' + + $ cp 0 a + $ for i in `python $TESTDIR/seq.py 0 9`; do + > echo $i >> $i + > done + $ hg commit -m 'make them slightly different' + $ rm `python $TESTDIR/seq.py 0 9` + $ hg addremove -s50 + removing 0 + removing 1 + removing 2 + removing 3 + removing 4 + removing 5 + removing 6 + removing 7 + removing 8 + removing 9 + adding a + recording removal of 9 as rename to a (99% similar) + $ hg commit -m 'always the same file should be selected' + should all fail $ hg addremove -s foo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-sc
Re: [PATCH 07 of 11 V2] ui: use scmutil.rccomponents to load configs (BC)
Excerpts from Ryan McElroy's message of 2017-03-22 11:37:00 +: > On 3/22/17 7:50 AM, Jun Wu wrote: > > # HG changeset patch > > # User Jun Wu > > # Date 1489462886 25200 > > # Mon Mar 13 20:41:26 2017 -0700 > > # Node ID add83f47bf3a51edbd58aa0fb6e571d186bdae6e > > # Parent df768455486ff51b4047fd3a8dfbef158516d2aa > > ui: use scmutil.rccomponents to load configs (BC) > > > > This is BC because system configs won't be able to override $EDITOR, $PAGER. > > The new behavior is arguably more rational. > > > > diff --git a/mercurial/ui.py b/mercurial/ui.py > > --- a/mercurial/ui.py > > +++ b/mercurial/ui.py > > @@ -212,6 +212,18 @@ class ui(object): > > u = cls() > > # we always trust global config files > > -for f in scmutil.rcpath(): > > -u.readconfig(f, trust=True) > > +for (t, f) in scmutil.rccomponents(): > > +if t == 'path': > > +u.readconfig(f, trust=True) > > +elif t == 'items': > > +sections = set() > > +for section, name, value, source in f: > > +# do not set ocfg > > +u._tcfg.set(section, name, value, source) > > +u._ucfg.set(section, name, value, source) > > +sections.add(section) > > +for section in sections: > > +u.fixconfig(section=section) > > +else: > > +raise error.ProgrammingError('unexpected rccomponent: %s' > > % t) > > return u > > Seeing this makes me not like this "union type" (rccomponents) that > you've created. Can we do this differently for more cleanliness? The code here is temporary and will be rewritten once the immutable config becomes a thing. I will add a comment but not rewrite the temporary code. > Consider instead of having rccomponents be a parsed config "source" > (either a file or environment for now). Then this patch simply combines > them in order. This gives us the nice property of reading each config > file only once, which was a patch series that dsop sent but had BC > issues, but doing it this way means there are no BC issues. Of course, > it also cleans up this code so we don't have the type check in there. If I understand what you suggest, I think it could have issues with "%unset". Although that may be solved, but the immutable config will be a thing, so I'm not interested in improving to-be-deprecated code. > Essentially, envconfig() can be generalized into a "parsedconfig" > container, and then it's just about ordering for the final config from > there. > > I think this would make the code cleaner -- thoughts? > > > > > diff --git a/tests/test-config-env.py b/tests/test-config-env.py > > new file mode 100644 > > --- /dev/null > > +++ b/tests/test-config-env.py > > @@ -0,0 +1,48 @@ > > +# Test the config layer generated by environment variables > > + > > +from __future__ import absolute_import, print_function > > + > > +import os > > + > > +from mercurial import ( > > +encoding, > > +scmutil, > > +ui as uimod, > > +) > > + > > +testtmp = encoding.environ['TESTTMP'] > > + > > +# prepare hgrc files > > +def join(name): > > +return os.path.join(testtmp, name) > > + > > +with open(join('sysrc'), 'w') as f: > > +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') > > + > > +with open(join('userrc'), 'w') as f: > > +f.write('[ui]\neditor=e1') > > + > > +# replace rcpath functions so they point to the files above > > +def systemrcpath(): > > +return [join('sysrc')] > > + > > +def userrcpath(): > > +return [join('userrc')] > > + > > +scmutil.systemrcpath = systemrcpath > > +scmutil.userrcpath = userrcpath > > +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc > > + > > +# utility to print configs > > +def printconfigs(env): > > +encoding.environ = env > > +scmutil._rccomponents = None # reset cache > > +ui = uimod.ui.load() > > +for section, name, value in ui.walkconfig(): > > +source = ui.configsource(section, name) > > +print('%s.%s=%s # %s' % (section, name, value, source)) > > +print('') > > + > > +# environment variable overrides > > +printconfigs({}) > > +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) > > diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out > > new file mode 100644 > > --- /dev/null > > +++ b/tests/test-config-env.py.out > > @@ -0,0 +1,6 @@ > > +pager.pager=p0 # $TESTTMP/sysrc:4 > > +ui.editor=e1 # $TESTTMP/userrc:2 > > + > > +pager.pager=p2 # $PAGER > > +ui.editor=e1 # $TESTTMP/userrc:2 > > + > > diff --git a/tests/test-config.t b/tests/test-config.t > > --- a/tests/test-config.t > > +++ b/tests/test-config.t > > @@ -165,2 +165,16 @@ edit failure > > abort: edit failed: false exited with status 1 > > [255] > > + > > +config affected by environment variables > > + > > + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' > > + $VIS
[PATCH] doc: fix short underline which causes make -C doc to fail
# HG changeset patch # User Kostia Balytskyi # Date 1490198110 25200 # Wed Mar 22 08:55:10 2017 -0700 # Node ID 86383b66465bd7122bb5380047c6e87c888d8227 # Parent f808c796dfd2c6e4e6990c73a838320512aafeca doc: fix short underline which causes make -C doc to fail https://www.mercurial-scm.org/repo/hg-committed/rev/79d98e1b21a7 broke 'make -C doc' by not adding enough underline. This fixes it. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -415,7 +415,7 @@ effect and style see :hg:`help color`. extension). ``commands`` --- + ``update.requiredest`` Require that the user pass a destination when running ``hg update``. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 01 of 11 V2] scmutil: add a method to convert environment variables to config items
Excerpts from Ryan McElroy's message of 2017-03-22 11:16:40 +: > This function is fine, but scmutil feels like the wrong place for it. > Why is it not in config.py? > > This same question applies to patches 2-5 as well. I seems like most of > this should be living in config.py. > > We can move it over in a future series, I suppose? Two reasons: 1. The existing *path() functions are in scmposix, scmwindows and scmutil 2. If you look at config.py, it has zero special-case logic. i.e. it does not know config sections, it does not know config paths, etc. It only knows how to load configs and provides a class to access configs. I think config.py is better keeping "pure" by providing just the data strucutre without any knowledge about actual config sections etc. In the upcoming immutable config series, the config.py will have immutable structures. But things like ui.fixconfig, ui.readconfig, trust vs untrust etc will stay away from config.py ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2] update: ignore commands.update.requiredest if HGPLAIN=1
On Wed, Mar 22, 2017 at 8:33 AM, Martin von Zweigbergk wrote: > On Wed, Mar 22, 2017 at 6:09 AM, Yuya Nishihara wrote: >> On Tue, 21 Mar 2017 21:27:20 -0700, Martin von Zweigbergk via >> Mercurial-devel wrote: >>> # HG changeset patch >>> # User Martin von Zweigbergk >>> # Date 1490156520 25200 >>> # Tue Mar 21 21:22:00 2017 -0700 >>> # Node ID 2558f3d814f50681641fff9815d30129de2ab5ad >>> # Parent 13dc00c233b7e374a6fa0b9846510a94c2615671 >>> update: ignore commands.update.requiredest if HGPLAIN=1 >>> >>> diff -r 13dc00c233b7 -r 2558f3d814f5 mercurial/commands.py >>> --- a/mercurial/commands.py Tue Mar 14 17:43:44 2017 -0700 >>> +++ b/mercurial/commands.py Tue Mar 21 21:22:00 2017 -0700 >>> @@ -5349,7 +5349,8 @@ >>> if rev and node: >>> raise error.Abort(_("please specify just one revision")) >>> >>> -if ui.configbool('commands', 'update.requiredest', False): >>> +if (not ui.plain() and >>> +ui.configbool('commands', 'update.requiredest', False)): >>> if not node and not rev and not date: >>> raise error.Abort(_('you must specify a destination'), >>>hint=_('for example: hg update ".::"')) >> >> Perhaps it will be better to handle this kind of HGPLAIN stuff in ui.py >> like how 'defaults' section is ignored. > > Makes sense. I'll just check that "HGPLAIN=1 hg --config > commands.update.requiredest=1 up" does not fail (I assume HGPLAIN > should also make it ignore commands.* configs provided via --config). Looks like my assumption was wrong, in the sense that that's not how it currently works for the other flags. For example: $ hg id facd5b0862f1 tip $ HGPLAIN=1 hg --config ui.quiet=1 id facd5b0862f1 So I guess we should stick to that pattern for [commands]. That also makes sense because it is similar to how HGRCPATH=/dev/null works; config options can be added onto the otherwise empty config. I'll just need to update the test case I included in this patch to actually write the config to file. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] status: support commands.status.relative config
On Wed, Mar 22, 2017 at 3:12 AM, Ryan McElroy wrote: > I'm +100 on this patch. We've been doing this in tweakdefaults for ages. > Everyone loves it. > > On 3/22/17 4:35 AM, Martin von Zweigbergk via Mercurial-devel wrote: >> >> # HG changeset patch >> # User Martin von Zweigbergk >> # Date 1490143844 25200 >> # Tue Mar 21 17:50:44 2017 -0700 >> # Node ID e0e123324f205071c80657079ff83a4e58db862c >> # Parent 102f291807c92864a2231e5e925d6cd64783bb59 >> status: support commands.status.relative config >> >> When the config is set to true, status output becomes relative to the >> working directory. This has bugged me since I started using hg and it >> turns it is sillily simple to support it (unless I missed something, >> of course). >> >> We could also add a --relative flag, but I would personally always >> want that on, and I haven't heard any use for having it sometimes on, >> so this patch only lets you enable it via config. >> >> diff -r 102f291807c9 -r e0e123324f20 mercurial/commands.py >> --- a/mercurial/commands.py Mon Mar 20 16:34:12 2017 -0700 >> +++ b/mercurial/commands.py Tue Mar 21 17:50:44 2017 -0700 >> @@ -4734,7 +4734,8 @@ >> else: >> node1, node2 = scmutil.revpair(repo, revs) >> -if pats: >> +if pats or (not ui.plain() and >> +ui.configbool('commands', 'status.relative', False)): > > > Style-nits: > * The "false" isn't necessary -- that's the default, isn't it? Ah, thanks. (Guess where I inherited that from :-)) > * Also, I think it would be clearer to divide this into two lines: > > relative = not ui.plain and ui.configbool('commands', 'status.relative') > if pats or relative: As Yuya pointed out, the ui.plain() should probably be done in one place (in ui.py) for all [commands] config, which will make this a little simpler. I still think your proposal is good, so I'll address that in V2. > > > >> cwd = repo.getcwd() >> else: >> cwd = '' >> diff -r 102f291807c9 -r e0e123324f20 mercurial/help/config.txt >> --- a/mercurial/help/config.txt Mon Mar 20 16:34:12 2017 -0700 >> +++ b/mercurial/help/config.txt Tue Mar 21 17:50:44 2017 -0700 >> @@ -417,6 +417,10 @@ >> ``commands`` >> -- >> +``status.relative`` >> +Make paths in ``hg status`` output relative to the current directory. >> +(default: False) >> + >> ``update.requiredest`` >> Require that the user pass a destination when running ``hg update``. >> For example, ``hg update .::`` will be allowed, but a plain ``hg >> update`` >> diff -r 102f291807c9 -r e0e123324f20 tests/test-status.t >> --- a/tests/test-status.t Mon Mar 20 16:34:12 2017 -0700 >> +++ b/tests/test-status.t Tue Mar 21 17:50:44 2017 -0700 >> @@ -40,6 +40,20 @@ >> ? ../b/2/in_b_2 >> ? ../b/in_b >> ? ../in_root >> + $ hg --config commands.status.relative=True status --cwd a >> + ? 1/in_a_1 >> + ? in_a >> + ? ../b/1/in_b_1 >> + ? ../b/2/in_b_2 >> + ? ../b/in_b >> + ? ../in_root >> + $ HGPLAIN=1 hg --config commands.status.relative=True status --cwd a >> + ? a/1/in_a_1 >> + ? a/in_a >> + ? b/1/in_b_1 >> + ? b/2/in_b_2 >> + ? b/in_b >> + ? in_root >> $ hg status --cwd b >> ? a/1/in_a_1 >> > ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2] update: ignore commands.update.requiredest if HGPLAIN=1
On Wed, Mar 22, 2017 at 6:09 AM, Yuya Nishihara wrote: > On Tue, 21 Mar 2017 21:27:20 -0700, Martin von Zweigbergk via Mercurial-devel > wrote: >> # HG changeset patch >> # User Martin von Zweigbergk >> # Date 1490156520 25200 >> # Tue Mar 21 21:22:00 2017 -0700 >> # Node ID 2558f3d814f50681641fff9815d30129de2ab5ad >> # Parent 13dc00c233b7e374a6fa0b9846510a94c2615671 >> update: ignore commands.update.requiredest if HGPLAIN=1 >> >> diff -r 13dc00c233b7 -r 2558f3d814f5 mercurial/commands.py >> --- a/mercurial/commands.py Tue Mar 14 17:43:44 2017 -0700 >> +++ b/mercurial/commands.py Tue Mar 21 21:22:00 2017 -0700 >> @@ -5349,7 +5349,8 @@ >> if rev and node: >> raise error.Abort(_("please specify just one revision")) >> >> -if ui.configbool('commands', 'update.requiredest', False): >> +if (not ui.plain() and >> +ui.configbool('commands', 'update.requiredest', False)): >> if not node and not rev and not date: >> raise error.Abort(_('you must specify a destination'), >>hint=_('for example: hg update ".::"')) > > Perhaps it will be better to handle this kind of HGPLAIN stuff in ui.py > like how 'defaults' section is ignored. Makes sense. I'll just check that "HGPLAIN=1 hg --config commands.update.requiredest=1 up" does not fail (I assume HGPLAIN should also make it ignore commands.* configs provided via --config). ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] show: new extension for displaying various repository data
> On Mar 22, 2017, at 04:51, Ryan McElroy wrote: > > > >> On 3/22/17 7:29 AM, Sean Farley wrote: >> Yuya Nishihara writes: >> On Sun, 12 Mar 2017 21:38:00 -0700, Gregory Szorc wrote: # HG changeset patch # User Gregory Szorc # Date 1489378362 25200 # Sun Mar 12 21:12:42 2017 -0700 # Node ID d30057d358076cbe7d632cd573095af97543f932 # Parent 1c3352d7eaf24533ad52d4b8a024211e9189fb0b show: new extension for displaying various repository data >>> The idea sounds nice to me. I just checked minor implementation details >>> about formatter. >> Just a quick reply (as I whittle down my backlog), but a lot of people >> (including myself) have a 'show' alias (inspired by 'git show'). >> >> That may or may not be a factor in this. > > Greg called this out specifically in his excellent summary. > > FB also has a "show" extension that replaced our "show" alias: > https://bitbucket.org/facebook/hg-experimental/src/default/hgext3rd/show.py At Paris, people from Facebook mildly objected to "show" because of the conflict. At Mountain View, Durham said to just use "show" and FB would deal with it. I myself was convinced to use "display" after Paris and that's what I initially implemented. Justification for "display" was summarized in that RFC patch's commit message. However, enough people said the reasons weren't strong enough and Durham gave me a green light, so I changed to my preference: show. Anyway, the command and extension name is a bikeshed and can be changed before 4.2. I'd prefer review focus on the behavior so we can get something landed and iterate on the feature. I *really* want a smartlog/wip feature in the core distribution and this extension/command is where it will live. > > Therefore, I would also slightly prefer "view", but I admit I don't care > about hgk (even though we have it on at FB and it doesn't seem to work at > all...) > > I'll respond to the original as well so I can respond inline to the code and > summary. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 V2] show: new extension for displaying various repository data
On Tue, 21 Mar 2017 23:52:42 -0700, Gregory Szorc wrote: > On Tue, Mar 21, 2017 at 11:49 PM, Gregory Szorc > wrote: > > > # HG changeset patch > > # User Gregory Szorc > > # Date 1490165337 25200 > > # Tue Mar 21 23:48:57 2017 -0700 > > # Node ID 80ca2bee4a06887f918e3328b3f005e4c1cb1ab1 > > # Parent ae796e23fd42b036352b298f570af8949c2db2d9 > > show: new extension for displaying various repository data > > > > Yuya, et al: > > Since the default output isn't covered by BC guarantees, we probably want > HGPLAIN to be. I'm not sure what the preferred way to do that should be. > Should I create a separate topic within the template for the plain view? No idea about BC guarantees vs HGPLAIN. HGPLAIN is to disable user configuration. If "hg show" is covered by e.g. compat version, we'll only need to set it to the lowest version if HGPLAIN set. > I'm still a bit confused as to how formatters work :/ [...] > > +@showview('bookmarks', fmtopic='bookmarks') > > +def showbookmarks(ui, repo, fm): > > +"""bookmarks and their associated changeset""" > > +marks = repo._bookmarks > > +if not len(marks): > > +ui.write(_('(no bookmarks set)\n')) > > +return > > + > > +active = repo._activebookmark > > +longest = max(len(b) for b in marks) > > + > > +for bm, node in sorted(marks.items()): > > +fm.startitem() > > +fm.context(ctx=repo[node]) > > +fm.write('bookmark', '%s', bm) > > +fm.write('node', fm.hexfunc(node), fm.hexfunc(node)) > > +fm.data(active=bm == active, > > +_longestlen=longest) I think the formatter API was designed to make hand-written output formatting templatable, so the default (plain) output doesn't use template file. bookmarkfmt = '%%-%ds' % longest fm.write('bookmark', bookmarkfmt, bm) fm.write('node', '%s\n', fm.hexfunc_that_uses_shortest(node)) But 'hg show' does use template by default. That's why fm.plain() doesn't work. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 V2] formatter: reserve _ prefixed keys as internal and don't render
On Tue, 21 Mar 2017 23:49:25 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc > # Date 1490164306 25200 > # Tue Mar 21 23:31:46 2017 -0700 > # Node ID ae796e23fd42b036352b298f570af8949c2db2d9 > # Parent 102f291807c92864a2231e5e925d6cd64783bb59 > formatter: reserve _ prefixed keys as internal and don't render > > As part of implementing `hg show`, Yuya noticed that JSON formatting > was rendering an internal-only key, which was unfortunate. > > In this patch, I document new behavior on fm.data() that all > keys beginning with underscores are reserved. I change the behavior > of the JSON formatter to not render keys beginning with underscores. > > I ran the test suite with fm.data() raising if any key with a leading > underscore was passed in and there were no test failures. So I think > it is safe to adopt this convention. > > diff --git a/mercurial/formatter.py b/mercurial/formatter.py > --- a/mercurial/formatter.py > +++ b/mercurial/formatter.py > @@ -176,7 +176,11 @@ class baseformatter(object): > '''insert context objects to be used to render template keywords''' > pass > def data(self, **data): > -'''insert data into item that's not shown in default output''' > +'''insert data into item that's not shown in default output > + > +Keys beginning with '_' are designated as internal and may not be > +rendered by all formatters. > +''' > self._item.update(data) > def write(self, fields, deftext, *fielddata, **opts): > '''do default text output while assigning data to item''' > @@ -315,6 +319,9 @@ class jsonformatter(baseformatter): > self._out.write("\n {\n") > first = True > for k, v in sorted(self._item.items()): > +# Don't format hidden elements. > +if k.startswith('_'): > +continue The idea of using _ prefix seems okay, but I don't think internal keys should be usable in template. If "longestlen" should be available for user templates, it shouldn't be _-prefixed. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4 py3] similar: avoid sorting and making copies of addedfiles and removedfiles sets
> On Mar 22, 2017, at 09:43, Yuya Nishihara wrote: > > On Tue, 21 Mar 2017 15:13:00 -0400, Augie Fackler wrote: >> # HG changeset patch >> # User Augie Fackler >> # Date 1489903420 14400 >> # Sun Mar 19 02:03:40 2017 -0400 >> # Node ID a4745fd9219ed5b408bfc0403a4a8e6acd41df6c >> # Parent 66c3ae6d886cae0e3a3cff6a0058e2d2a866fd9d >> similar: avoid sorting and making copies of addedfiles and removedfiles sets >> >> The process of porting to Python 3 exposed some weirdness in this >> code: workingfilectx doesn't define rich comparison operators, so in >> Python 2 the default comparison devolved to id(value), which is the >> pointer address of the object. Inspection of _findexactmatches and >> _findsimilarmatches revealed that they didn't care about the sort >> order of the data, so we remove the sort (and potentially make >> addremove faster since it's not sorting things). We now have to do one >> little extra set dance in order to not mutate the addedfiles set >> during its iteration, but that's a small price to pay for the >> resulting cleaner nature of the code. > > I have unsent patch to sort files alphabetically, not by memory address. IIRC, > I wrote it because a TortoiseHg user reported that the similarity detection > was unstable if there were multiple candidates of the copy source. Ah, I see by inspection now: the issue arises if multiple files are the same amount of similarity (or if there are multiple exact matches), if we don't sort the list, we'll end up with slightly random results. > I'll post my patch soon. Thanks! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 5 of 6] osutil: add a C function getting filesystem type
On Mon, 20 Mar 2017 17:04:38 -0700, Jun Wu wrote: > # HG changeset patch > # User Jun Wu > # Date 1490052299 25200 > # Mon Mar 20 16:24:59 2017 -0700 > # Node ID f710d54d1985975d7d37aa58e9d5740ebdcf5b7b > # Parent 8a3c7ac9923732e980a3660f0555c2e109ee93e0 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > f710d54d1985 > osutil: add a C function getting filesystem type > +#ifdef EXT2_SUPER_MAGIC > + if (buf.f_type == EXT2_SUPER_MAGIC) > + return "ext2"; > +#endif > +#ifdef EXT3_SUPER_MAGIC > + if (buf.f_type == EXT3_SUPER_MAGIC) > + return "ext3"; > +#endif > +#ifdef EXT4_SUPER_MAGIC > + if (buf.f_type == EXT4_SUPER_MAGIC) > + return "ext4"; > +#endif Just FYI, my /home drive was reported as ext2 since ext[234] magics are identical. EXT2_SUPER_MAGIC 0xef53 EXT3_SUPER_MAGIC 0xef53 EXT4_SUPER_MAGIC 0xef53 Anyway, this series looks promising, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 V2] show: new extension for displaying various repository data
On 3/22/17 6:49 AM, Gregory Szorc wrote: # HG changeset patch # User Gregory Szorc # Date 1490165337 25200 # Tue Mar 21 23:48:57 2017 -0700 # Node ID 80ca2bee4a06887f918e3328b3f005e4c1cb1ab1 # Parent ae796e23fd42b036352b298f570af8949c2db2d9 show: new extension for displaying various repository data Currently, Mercurial has a number of commands to show information. And, there are features coming down the pipe that will introduce more commands for showing information. Currently, when introducing a new class of data or a view that we wish to expose to the user, the strategy is to introduce a new command or overload an existing command, sometimes both. For example, there is a desire to formalize the wip/smartlog/underway/mine functionality that many have devised. There is also a desire to introduce a "topics" concept. Others would like views of "the current stack." In the current model, we'd need a new command for wip/smartlog/etc (that behaves a lot like a pre-defined alias of `hg log`). For topics, we'd likely overload `hg topic[s]` to both display and manipulate topics. Adding new commands for every pre-defined query doesn't scale well and pollutes `hg help`. Overloading commands to perform read-only and write operations is arguably an UX anti-pattern: while having all functionality for a given concept in one command is nice, having a single command doing multiple discrete operations is not. Furthermore, a user may be surprised that a command they thought was read-only actually changes something. We discussed this at the Mercurial 4.0 Sprint in Paris and decided that having a single command where we could hang pre-defined views of various data would be a good idea. Having such a command would: * Help prevent an explosion of new query-related commands * Create a clear separation between read and write operations (mitigates footguns) * Avoids overloading the meaning of commands that manipulate data (bookmark, tag, branch, etc) (while we can't take away the existing behavior for BC reasons, we now won't introduce this behavior on new commands) I'm not convinced that these "footguns" are a bad ui though. I certainly would be less comfortable asking people who are used to writing "hg boo" to change to "hg show bookmarks" (see comment on * Allows users to discover informational views more easily by aggregating them in a single location * Lowers the barrier to creating the new views (since the barrier to creating a top-level command is relatively high) So, this commit introduces the `hg show` command via the "show" extension. This command accepts a positional argument of the "view" to show. New views can be registered with a decorator. To prove it works, we implement the "bookmarks" view, which shows a table of bookmarks and their associated nodes. We introduce a new style to hold everything used by `hg show`. Ah, this answers some of my inline questions below about the new styles. For our initial bookmarks view, the output varies from `hg bookmarks`: * Padding is performed in the template itself as opposed to Python * Revision integers are not shown * shortest() is used to display a 5 character node by default (as opposed to static 12 characters) I chose to implement the "bookmarks" view first because it is simple and shouldn't invite too much bikeshedding that detracts from the evaluation of `hg show` itself. But there is an important point to consider: we now have 2 ways to show a list of bookmarks. I'm not a fan of introducing multiple ways to do very similar things. So it might be worth discussing how we wish to tackle this issue for bookmarks, tags, branches, MQ series, etc. I'm pretty concerned about this too. I don't have an answer right now but I'll think about it. I also made the choice of explicitly declaring the default show template not part of the standard BC guarantees. History has shown that we make mistakes and poor choices with output formatting but can't fix these mistakes later because random tools are parsing output and we don't want to break these tools. Optimizing for human consumption is one of my goals for `hg show`. So, by not covering the formatting as part of BC, the barrier to future change is much lower and humans benefit. This is awesome. See inline comments for additional idea. First "porcelain" hg command :-p. There are some improvements that can be made to formatting. For example, we don't yet use label() in the templates. We obviously want this for color. But I'm not sure if we should reuse the existing log.* labels or invent new ones. I figure we can punt that to a follow-up. Seems that this patch is good for collecting shed colors, but this would probably want to be broken up into a series before it actually goes in, right? At the aforementioned Sprint, we discussed and discarded various alternatives to `hg show`. We considered making `hg log ` perform this behavior. The main reason we can't do this is because a p
Re: [PATCH 1 of 8 py3] pycompat: alias urlreq.unquote to unquote_to_bytes
On Tue, 21 Mar 2017 22:56:38 -0700, Gregory Szorc wrote: > # HG changeset patch > # User Gregory Szorc > # Date 1490160011 25200 > # Tue Mar 21 22:20:11 2017 -0700 > # Node ID 285f48d5644ea070f717473af077e6728df6ea82 > # Parent 102f291807c92864a2231e5e925d6cd64783bb59 > pycompat: alias urlreq.unquote to unquote_to_bytes Queued the series, many thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 4 py3] revsetlang: work around repr() returning unicode on py3
On Tue, 21 Mar 2017 15:13:01 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler > # Date 1489900459 14400 > # Sun Mar 19 01:14:19 2017 -0400 > # Node ID 63466a54ec9e266031cce12fbd699ccfccd40738 > # Parent a4745fd9219ed5b408bfc0403a4a8e6acd41df6c > revsetlang: work around repr() returning unicode on py3 > > I'm not confident in my choice of "encode to utf8" here: it seems > reasonable that we could expect the revset engine to do the right > thing there. On the other hand these strings might have encoding > weirdness to begin with if there's `branch(some-weird-byte-sequence)`. > --- a/mercurial/revsetlang.py > +++ b/mercurial/revsetlang.py > @@ -607,7 +607,11 @@ def formatspec(expr, *args): > ''' > > def quote(s): > -return repr(str(s)) > +r = repr(bytes(s)) > +if pycompat.ispy3: > +r = r[1:] # strip off b prefix > +return r.encode('utf-8') utf-8 is wrong, but it would be okay as repr(bytes) wouldn't contain non-ascii characters. That said, it'll be better to use util.escapestr(). "'" + util.escapestr(s) + "'" ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] findrenames: sort files not by object id but by path for stable result
# HG changeset patch # User Yuya Nishihara # Date 1426413536 -32400 # Sun Mar 15 18:58:56 2015 +0900 # Node ID 425379e72e817b6c79e955173b015b9a0fe090e9 # Parent 102f291807c92864a2231e5e925d6cd64783bb59 findrenames: sort files not by object id but by path for stable result It seems the original implementation tried to sort added/removed files alphabetically, but actually it did sort fctx objects by address. This patch removes the use of set()s in order to preserve the order of added/removed files. addedfiles.remove() could be slightly slower than before, but it doesn't make much difference. benchmark (on tmpfs): $ hg up -C 15afda349b11; hg purge --all; mv tests tests.new $ LANG=C hg --time addremove -n > /dev/null original: real 0.420 secs (user 0.390+0.000 sys 0.030+0.000) this patch: real 0.430 secs (user 0.390+0.000 sys 0.040+0.000) diff --git a/mercurial/similar.py b/mercurial/similar.py --- a/mercurial/similar.py +++ b/mercurial/similar.py @@ -101,19 +101,18 @@ def findrenames(repo, added, removed, th # Zero length files will be frequently unrelated to each other, and # tracking the deletion/addition of such a file will probably cause more # harm than good. We strip them out here to avoid matching them later on. -addedfiles = set([workingctx[fp] for fp in added -if workingctx[fp].size() > 0]) -removedfiles = set([parentctx[fp] for fp in removed -if fp in parentctx and parentctx[fp].size() > 0]) +addedfiles = [workingctx[fp] for fp in sorted(added) + if workingctx[fp].size() > 0] +removedfiles = [parentctx[fp] for fp in sorted(removed) +if fp in parentctx and parentctx[fp].size() > 0] # Find exact matches. -for (a, b) in _findexactmatches(repo, -sorted(addedfiles), sorted(removedfiles)): +for (a, b) in _findexactmatches(repo, addedfiles[:], removedfiles): addedfiles.remove(b) yield (a.path(), b.path(), 1.0) # If the user requested similar files to be matched, search for them also. if threshold < 1.0: -for (a, b, score) in _findsimilarmatches(repo, -sorted(addedfiles), sorted(removedfiles), threshold): +for (a, b, score) in _findsimilarmatches(repo, addedfiles, + removedfiles, threshold): yield (a.path(), b.path(), score) diff --git a/tests/test-addremove-similar.t b/tests/test-addremove-similar.t --- a/tests/test-addremove-similar.t +++ b/tests/test-addremove-similar.t @@ -55,6 +55,57 @@ comparing two empty files caused ZeroDiv $ hg commit -m B +should be sorted by path for stable result + + $ for i in `python $TESTDIR/seq.py 0 9`; do + > cp small-file $i + > done + $ rm small-file + $ hg addremove + adding 0 + adding 1 + adding 2 + adding 3 + adding 4 + adding 5 + adding 6 + adding 7 + adding 8 + adding 9 + removing small-file + recording removal of small-file as rename to 0 (100% similar) + recording removal of small-file as rename to 1 (100% similar) + recording removal of small-file as rename to 2 (100% similar) + recording removal of small-file as rename to 3 (100% similar) + recording removal of small-file as rename to 4 (100% similar) + recording removal of small-file as rename to 5 (100% similar) + recording removal of small-file as rename to 6 (100% similar) + recording removal of small-file as rename to 7 (100% similar) + recording removal of small-file as rename to 8 (100% similar) + recording removal of small-file as rename to 9 (100% similar) + $ hg commit -m '10 same files' + + $ cp 0 a + $ for i in `python $TESTDIR/seq.py 0 9`; do + > echo $i >> $i + > done + $ hg commit -m 'make them slightly different' + $ rm `python $TESTDIR/seq.py 0 9` + $ hg addremove -s50 + removing 0 + removing 1 + removing 2 + removing 3 + removing 4 + removing 5 + removing 6 + removing 7 + removing 8 + removing 9 + adding a + recording removal of 9 as rename to a (99% similar) + $ hg commit -m 'always the same file should be selected' + should all fail $ hg addremove -s foo ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4 py3] similar: avoid sorting and making copies of addedfiles and removedfiles sets
On Tue, 21 Mar 2017 15:13:00 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler > # Date 1489903420 14400 > # Sun Mar 19 02:03:40 2017 -0400 > # Node ID a4745fd9219ed5b408bfc0403a4a8e6acd41df6c > # Parent 66c3ae6d886cae0e3a3cff6a0058e2d2a866fd9d > similar: avoid sorting and making copies of addedfiles and removedfiles sets > > The process of porting to Python 3 exposed some weirdness in this > code: workingfilectx doesn't define rich comparison operators, so in > Python 2 the default comparison devolved to id(value), which is the > pointer address of the object. Inspection of _findexactmatches and > _findsimilarmatches revealed that they didn't care about the sort > order of the data, so we remove the sort (and potentially make > addremove faster since it's not sorting things). We now have to do one > little extra set dance in order to not mutate the addedfiles set > during its iteration, but that's a small price to pay for the > resulting cleaner nature of the code. I have unsent patch to sort files alphabetically, not by memory address. IIRC, I wrote it because a TortoiseHg user reported that the similarity detection was unstable if there were multiple candidates of the copy source. I'll post my patch soon. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 4 py3] revsetlang: portably turn int into bytestring
On Tue, 21 Mar 2017 15:13:02 -0400, Augie Fackler wrote: > # HG changeset patch > # User Augie Fackler > # Date 1489899833 14400 > # Sun Mar 19 01:03:53 2017 -0400 > # Node ID 3af735529b5f475e5c53ffaf7b136eecb97fcd61 > # Parent 63466a54ec9e266031cce12fbd699ccfccd40738 > revsetlang: portably turn int into bytestring Queued this, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2] update: ignore commands.update.requiredest if HGPLAIN=1
On Tue, 21 Mar 2017 21:27:20 -0700, Martin von Zweigbergk via Mercurial-devel wrote: > # HG changeset patch > # User Martin von Zweigbergk > # Date 1490156520 25200 > # Tue Mar 21 21:22:00 2017 -0700 > # Node ID 2558f3d814f50681641fff9815d30129de2ab5ad > # Parent 13dc00c233b7e374a6fa0b9846510a94c2615671 > update: ignore commands.update.requiredest if HGPLAIN=1 > > diff -r 13dc00c233b7 -r 2558f3d814f5 mercurial/commands.py > --- a/mercurial/commands.py Tue Mar 14 17:43:44 2017 -0700 > +++ b/mercurial/commands.py Tue Mar 21 21:22:00 2017 -0700 > @@ -5349,7 +5349,8 @@ > if rev and node: > raise error.Abort(_("please specify just one revision")) > > -if ui.configbool('commands', 'update.requiredest', False): > +if (not ui.plain() and > +ui.configbool('commands', 'update.requiredest', False)): > if not node and not rev and not date: > raise error.Abort(_('you must specify a destination'), >hint=_('for example: hg update ".::"')) Perhaps it will be better to handle this kind of HGPLAIN stuff in ui.py like how 'defaults' section is ignored. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] show: new extension for displaying various repository data
On 3/22/17 7:29 AM, Sean Farley wrote: Yuya Nishihara writes: On Sun, 12 Mar 2017 21:38:00 -0700, Gregory Szorc wrote: # HG changeset patch # User Gregory Szorc # Date 1489378362 25200 # Sun Mar 12 21:12:42 2017 -0700 # Node ID d30057d358076cbe7d632cd573095af97543f932 # Parent 1c3352d7eaf24533ad52d4b8a024211e9189fb0b show: new extension for displaying various repository data The idea sounds nice to me. I just checked minor implementation details about formatter. Just a quick reply (as I whittle down my backlog), but a lot of people (including myself) have a 'show' alias (inspired by 'git show'). That may or may not be a factor in this. Greg called this out specifically in his excellent summary. FB also has a "show" extension that replaced our "show" alias: https://bitbucket.org/facebook/hg-experimental/src/default/hgext3rd/show.py Therefore, I would also slightly prefer "view", but I admit I don't care about hgk (even though we have it on at FB and it doesn't seem to work at all...) I'll respond to the original as well so I can respond inline to the code and summary. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 11 of 11 V2] pager: do not read from environment variable
On 3/22/17 7:51 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1489456112 25200 # Mon Mar 13 18:48:32 2017 -0700 # Node ID d2b34be3b64a6ca60644576b806e5b7172d524cc # Parent 713d562d0a2426c8658675a66158e6c412ae9dcc pager: do not read from environment variable Overall, I'm a big +1 on this series. It's a good bug fix and a great clean up. I think it can be even better with the suggestions I made, but feel free to push back if you think I missed something about your approach that's better than what I suggested. We have converted $PAGER to config, ui.pager() now can just read the config, without looking at environment variables. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -846,12 +846,6 @@ class ui(object): return -# TODO: add a "system defaults" config section so this default -# of more(1) can be easily replaced with a global -# configuration file. For example, on OS X the sane default is -# less(1), not more(1), and on debian it's -# sensible-pager(1). We should probably also give the system -# default editor command similar treatment. -envpager = encoding.environ.get('PAGER', 'more') -pagercmd = self.config('pager', 'pager', envpager) +fallbackpager = 'more' +pagercmd = self.config('pager', 'pager', fallbackpager) if not pagercmd: return ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 08 of 11 V2] config: list environment variables in debug output
On 3/22/17 7:50 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1489455351 25200 # Mon Mar 13 18:35:51 2017 -0700 # Node ID 23b2b1ed59763e5e676f06a4ac4f6bf567874220 # Parent add83f47bf3a51edbd58aa0fb6e571d186bdae6e # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=huA2rodPgFB3VM_ycpq_OLuxGpg_dDjbtlRqYlYdCiU&s=7mjJAE3v-lJCAXwqy4z4aclKYf_Kv3qDeKZFSpMws0g&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=huA2rodPgFB3VM_ycpq_OLuxGpg_dDjbtlRqYlYdCiU&s=7mjJAE3v-lJCAXwqy4z4aclKYf_Kv3qDeKZFSpMws0g&e= -r 23b2b1ed5976 config: list environment variables in debug output So we can verify the feature in tests. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1803,6 +1803,12 @@ def config(ui, repo, *values, **opts): ui.pager('config') fm = ui.formatter('config', opts) -for f in scmutil.rcpath(): -ui.debug('read config from: %s\n' % f) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +ui.debug('read config from: %s\n' % f) +elif t == 'items' and f: +for item in f: +source = item[3] +ui.debug('set config by: %s\n' % source) + untrusted = bool(opts.get('untrusted')) if values: diff --git a/tests/test-hgrc.t b/tests/test-hgrc.t --- a/tests/test-hgrc.t +++ b/tests/test-hgrc.t @@ -177,4 +177,18 @@ plain hgrc --quiet: ui.quiet=False +with environment variables + + $ PAGER=p1 EDITOR=e1 VISUAL=e2 hg showconfig --debug + set config by: $EDITOR + set config by: $VISUAL + set config by: $PAGER + read config from: $TESTTMP/hgrc + repo: bundle.mainreporoot=$TESTTMP + $PAGER: pager.pager=p1 + $VISUAL: ui.editor=e2 + --verbose: ui.verbose=False + --debug: ui.debug=True + --quiet: ui.quiet=False + plain mode with exceptions This functionality is awesome. Well done! ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 07 of 11 V2] ui: use scmutil.rccomponents to load configs (BC)
On 3/22/17 7:50 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1489462886 25200 # Mon Mar 13 20:41:26 2017 -0700 # Node ID add83f47bf3a51edbd58aa0fb6e571d186bdae6e # Parent df768455486ff51b4047fd3a8dfbef158516d2aa ui: use scmutil.rccomponents to load configs (BC) This is BC because system configs won't be able to override $EDITOR, $PAGER. The new behavior is arguably more rational. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -212,6 +212,18 @@ class ui(object): u = cls() # we always trust global config files -for f in scmutil.rcpath(): -u.readconfig(f, trust=True) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +u.readconfig(f, trust=True) +elif t == 'items': +sections = set() +for section, name, value, source in f: +# do not set ocfg +u._tcfg.set(section, name, value, source) +u._ucfg.set(section, name, value, source) +sections.add(section) +for section in sections: +u.fixconfig(section=section) +else: +raise error.ProgrammingError('unexpected rccomponent: %s' % t) return u Seeing this makes me not like this "union type" (rccomponents) that you've created. Can we do this differently for more cleanliness? Consider instead of having rccomponents be a parsed config "source" (either a file or environment for now). Then this patch simply combines them in order. This gives us the nice property of reading each config file only once, which was a patch series that dsop sent but had BC issues, but doing it this way means there are no BC issues. Of course, it also cleans up this code so we don't have the type check in there. Essentially, envconfig() can be generalized into a "parsedconfig" container, and then it's just about ordering for the final config from there. I think this would make the code cleaner -- thoughts? diff --git a/tests/test-config-env.py b/tests/test-config-env.py new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py @@ -0,0 +1,48 @@ +# Test the config layer generated by environment variables + +from __future__ import absolute_import, print_function + +import os + +from mercurial import ( +encoding, +scmutil, +ui as uimod, +) + +testtmp = encoding.environ['TESTTMP'] + +# prepare hgrc files +def join(name): +return os.path.join(testtmp, name) + +with open(join('sysrc'), 'w') as f: +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') + +with open(join('userrc'), 'w') as f: +f.write('[ui]\neditor=e1') + +# replace rcpath functions so they point to the files above +def systemrcpath(): +return [join('sysrc')] + +def userrcpath(): +return [join('userrc')] + +scmutil.systemrcpath = systemrcpath +scmutil.userrcpath = userrcpath +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc + +# utility to print configs +def printconfigs(env): +encoding.environ = env +scmutil._rccomponents = None # reset cache +ui = uimod.ui.load() +for section, name, value in ui.walkconfig(): +source = ui.configsource(section, name) +print('%s.%s=%s # %s' % (section, name, value, source)) +print('') + +# environment variable overrides +printconfigs({}) +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py.out @@ -0,0 +1,6 @@ +pager.pager=p0 # $TESTTMP/sysrc:4 +ui.editor=e1 # $TESTTMP/userrc:2 + +pager.pager=p2 # $PAGER +ui.editor=e1 # $TESTTMP/userrc:2 + diff --git a/tests/test-config.t b/tests/test-config.t --- a/tests/test-config.t +++ b/tests/test-config.t @@ -165,2 +165,16 @@ edit failure abort: edit failed: false exited with status 1 [255] + +config affected by environment variables + + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' + $VISUAL: ui.editor=e2 + + $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor' + --config: ui.editor=e3 + + $ PAGER=p1 hg config --debug | grep 'pager\.pager' + $PAGER: pager.pager=p1 + + $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep 'pager\.pager' + --config: pager.pager=p2 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 05 of 11 V2] scmutil: extract path reading function from rccomponents
On 3/22/17 7:50 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1490168676 25200 # Wed Mar 22 00:44:36 2017 -0700 # Node ID c18d9f3e0dac6d1676bd58617477c64953be96a3 # Parent 75f661b31640a914dd513d42b2ce1389c9b61c0a # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=4N9cXP1PfAM3QX2l-gLhA58Qj5cP-SbF4XJKyQ5Yjhw&s=WVkqRLpTQLL-QK5ldWoPQFxy4VmwwR7uNpH4piHGljQ&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=4N9cXP1PfAM3QX2l-gLhA58Qj5cP-SbF4XJKyQ5Yjhw&s=WVkqRLpTQLL-QK5ldWoPQFxy4VmwwR7uNpH4piHGljQ&e= -r c18d9f3e0dac scmutil: extract path reading function from rccomponents This makes the code better structured. A side effect is "normpath" will be called on paths in $HGRCPATH, which seems to be more correct. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -452,4 +452,13 @@ def rcpath(): _rccomponents = None +def _readrcpath(path): +'''path could be a single file or a directory. return a list of paths''' Thanks for providing a docblock -- we need more of these in general, but the return value is unclear from the doc block (the type is clear, but not what it contains). I'd modify it so it's clear that the list contains paths of files in the order that they should be read). +p = util.expandpath(path) +join = os.path.join +if os.path.isdir(p): +return [join(p, f) for f, k in osutil.listdir(p) if f.endswith('.rc')] +else: +return [p] + def rccomponents(): '''return an ordered [(type, obj)] about where to load configs. @@ -465,4 +474,8 @@ def rccomponents(): ''' global _rccomponents + +def pathize(path): +return ('path', os.path.normpath(path)) + It seems that this patch and the last patch could be re-done to reduce the number of churning lines, making both easier to review. For example, why not introduce _readrcpath in it's own patch, then use it when you create rccomponents? That would make each patch smaller and the overall arc of this series more clear to me. if _rccomponents is None: if 'HGRCPATH' in encoding.environ: @@ -473,15 +486,6 @@ def rccomponents(): if not p: continue -p = util.expandpath(p) -if os.path.isdir(p): -for f, kind in osutil.listdir(p): -if f.endswith('.rc'): -_rccomponents.append(('path', os.path.join(p, f))) -else: -_rccomponents.append(('path', p)) +_rccomponents.extend(map(pathize, _readrcpath(p))) else: -def pathize(path): -return ('path', os.path.normpath(path)) - _rccomponents = map(pathize, defaultrcpath()) _rccomponents.extend(map(pathize, systemrcpath())) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 01 of 11 V2] scmutil: add a method to convert environment variables to config items
On 3/22/17 7:50 AM, Jun Wu wrote: # HG changeset patch # User Jun Wu # Date 1489449998 25200 # Mon Mar 13 17:06:38 2017 -0700 # Node ID fa1618118c0603dafd8b7afbeab0e95f3e4307b0 # Parent 102f291807c92864a2231e5e925d6cd64783bb59 # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=dOvsJimzZK2HUO1Uuv03sjad5iNJbyVwkDFJTjCGklk&s=5wu-xCgtBalppj9ukMNAcetnR0vS291ibigIMAEi-4Q&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=dOvsJimzZK2HUO1Uuv03sjad5iNJbyVwkDFJTjCGklk&s=5wu-xCgtBalppj9ukMNAcetnR0vS291ibigIMAEi-4Q&e= -r fa1618118c06 scmutil: add a method to convert environment variables to config items We will put this "config generated by environment variables" thing in a desired layer - ex. above system configs, below user configs. The method was designed to be reusable if we want more complex layers - like multiple environment-generated configs; or test environment configs using a different environ dict. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -405,4 +405,18 @@ def osrcpath(): return path +def envconfig(envlist, env=None): +'''[(section, name, value, source)] extracted from environment variables + +envlist is a list of (envname, section, configname) +''' +if env is None: +env = encoding.environ +result = [] +for envname, section, configname in envlist: +if envname not in env: +continue +result.append((section, configname, env[envname], '$%s' % envname)) +return result + _rcpath = None This function is fine, but scmutil feels like the wrong place for it. Why is it not in config.py? This same question applies to patches 2-5 as well. I seems like most of this should be living in config.py. We can move it over in a future series, I suppose? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] fancyopts: making config defaults actually override defaults
Rodrigo: for some reason, patchwork thinks you are Martin. Any idea why? https://patchwork.mercurial-scm.org/patch/19133/ On 3/14/17 10:16 PM, Rodrigo Damazio via Mercurial-devel wrote: On Tue, Mar 14, 2017 at 12:50 PM, David Soria Parra mailto:d...@experimentalworks.net>> wrote: On Sat, Mar 11, 2017 at 06:03:30PM -0800, Rodrigo Damazio Bovendorp via Mercurial-devel wrote: > # HG changeset patch > # User Rodrigo Damazio mailto:rdama...@google.com>> > # Date 1489274373 28800 > # Sat Mar 11 15:19:33 2017 -0800 > # Node ID 8c833b81a994e2d3304c3b06793f536355528aab > # Parent 62939e0148f170b67ca8c7374f36c413b67fd387 > fancyopts: making config defaults actually override defaults > Overall this LGTM, and clearly makes defaults much better :). My concern is that we are encouraging the use of defaults again, while they are deprecated. Defaults have inherent problems that they overwrite arguments which might be mutable exclusive with others (e.g. --graph in incoming and outgoing), or lead to undesired behavior if it's set by an admin. an exmaple is if you would specifiy defaults.update.check=True, the user will not find an --no-check option in the help message or anywhere else. This is not a problem if we assume defaults are alway set by the user and he knows about them. Thanks for the review. Yes, we discussed the update --check case specifically during Sprint: https://public.etherpad-mozilla.org/p/sprint-hg4.2 (search for "Flags and defaults breakout") Note that I copied the notes over the the wiki for posterity: https://www.mercurial-scm.org/wiki/4.2sprint/Notes If people do some cleanup passes and categorization, that would be useful. I may contribute here at some point as well. The conclusion was that this gains us the ability to do proper single-flag overrides, which is good, but doesn't solve all the issues. There are other changes we also want to make flags and defaults useful again: - make the passed-in flag values not be simple primitive types, but rather enhance them with addition information about where the value is coming from, so commands like update can decide that an explicit --clean overrides a system default of --check, and should only fail if both come from the same level - we want to add a --no- counterflag for every flag, not just booleans, as a way to unset it (useful for revision-specifying flags for instance) - we want to add environment variables to the stack of overrides along with the different levels of config files and command-line arguments - we want to try making all positional arguments map to flags (e.g. "hg update 123" would be equivalent to "hg update -r 123" by making 123 be passed to the command as the -r flag, also allowing config overrides for those) - we want to investigate why we support callables in flag defaults, and remove support if that's not useful to anyone While I like this initial direction, I think this needs to be turned into a series of smaller steps, and we need more discussion around whether we will revive the defaults section or keep it deprecated. I'll drop this from patchwork for now while we discuss. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] rebase: ignore commands.rebase.requiredest if HGPLAIN=1
On 3/22/17 4:27 AM, Martin von Zweigbergk via Mercurial-devel wrote: # HG changeset patch # User Martin von Zweigbergk # Date 1490156812 25200 # Tue Mar 21 21:26:52 2017 -0700 # Node ID 23f767fb3142615597c4d3c2d5b4404e6c10f57a # Parent 2558f3d814f50681641fff9815d30129de2ab5ad rebase: ignore commands.rebase.requiredest if HGPLAIN=1 Thanks for the follow-up! Both patches in this series look correct to me and fit the hg philosophy. They should be queued. === Disclaimer: All of the following is not an objection to this series. This series should be queued as-is. I want to start a broader discussion here that ties into the "compatibility levels" discussion we had at the sprint, but is a little more specific to the implementation of HGPLAIN. Zooming out a level, if HGPLAIN remains a large hammer that disables all ui modernizations, I wonder if we should be thinking about a way to get output intended for tools but still have some modernizations (for example, relative paths in your recent patch). Otherwise, we'll eventually have two totally different hg's: the HGPLAIN one which behaves like a 2005-era VCS, and the one humans use which behaves like a 2020-era VCS. Eventually That will make fewer people want to use HGPLAIN for their scripts, which is a bad outcome. We need some way of saying "I'm a script but I still want hg to behave in a modern way". I guess the compatibility layer stuff can achieve this -- perhaps by making some options ignore HGPLAIN? After having thought it through a bit while writing this, I think this is the way to go (please poke holes it it if you find any of course) -- the upcoming config registry we agreed to at the sprint should probably handle everything to do with HGPLAIN as well. Then we don't need HGPLAIN checks scattered throughout the code -- HGPLAIN consideration is taken into account at the config registry level. Not only will this make things more consistent and less buggy (like, I wouldn't be able to forget to add HGPLAIN support that you're fixing up here), but also it will provide a path for certain compatibility levels to ignore HGPLAIN for some settings. Thoughts? diff -r 2558f3d814f5 -r 23f767fb3142 hgext/rebase.py --- a/hgext/rebase.py Tue Mar 21 21:22:00 2017 -0700 +++ b/hgext/rebase.py Tue Mar 21 21:26:52 2017 -0700 @@ -686,7 +686,8 @@ # Validate input and define rebasing points destf = opts.get('dest', None) -if ui.config('commands', 'rebase.requiredest', False): +if (not ui.plain() and +ui.config('commands', 'rebase.requiredest', False)): if not destf: raise error.Abort(_('you must specify a destination'), hint=_('use: hg rebase -d REV')) diff -r 2558f3d814f5 -r 23f767fb3142 tests/test-rebase-base.t --- a/tests/test-rebase-base.t Tue Mar 21 21:22:00 2017 -0700 +++ b/tests/test-rebase-base.t Tue Mar 21 21:26:52 2017 -0700 @@ -413,3 +413,7 @@ $ hg rebase -d 1 rebasing 2:5db65b93a12b "cc" (tip) saved backup bundle to $TESTTMP/repo/.hg/strip-backup/5db65b93a12b-4fb789ec-backup.hg (glob) + $ hg rebase -d 0 -r . -q + $ HGPLAIN=1 hg rebase + rebasing 2:889b0bc6a730 "cc" (tip) + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/889b0bc6a730-41ec4f81-backup.hg (glob) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 7 V3] revset: factor out linerange processing into a utility function
# HG changeset patch # User Denis Laxalde # Date 1487957948 -3600 # Fri Feb 24 18:39:08 2017 +0100 # Node ID b93ba42f47ac861922b483ce9870fbe6a5cc412c # Parent 613e7e42d14311059bdaf4c500147f9e35fb31fa # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r b93ba42f47ac # EXP-Topic linerange-log/hgweb-filelog revset: factor out linerange processing into a utility function Similar processing will be done in hgweb.webutil in forthcoming changeset. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -945,11 +945,7 @@ def followlines(repo, subset, x): lr = getrange(args['lines'][0], _("followlines expects a line range")) fromline, toline = [getinteger(a, _("line range bounds must be integers")) for a in lr] -if toline - fromline < 0: -raise error.ParseError(_("line range must be positive")) -if fromline < 1: -raise error.ParseError(_("fromline must be strictly positive")) -fromline -= 1 +fromline, toline = util.processlinerange(fromline, toline) fctx = repo[rev].filectx(fname) revs = (c.rev() for c, _linerange diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -2119,6 +2119,27 @@ def unitcountfn(*unittable): return go +def processlinerange(fromline, toline): +"""Check that linerange : makes sense and return a +0-based range. + +>>> processlinerange(10, 20) +(9, 20) +>>> processlinerange(2, 1) +Traceback (most recent call last): +... +ParseError: line range must be positive +>>> processlinerange(0, 5) +Traceback (most recent call last): +... +ParseError: fromline must be strictly positive +""" +if toline - fromline < 0: +raise error.ParseError(_("line range must be positive")) +if fromline < 1: +raise error.ParseError(_("fromline must be strictly positive")) +return fromline - 1, toline + bytecount = unitcountfn( (100, 1 << 30, _('%.0f GB')), (10, 1 << 30, _('%.1f GB')), ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 7 V3] hgweb: add a "patch" query parameter to filelog command
# HG changeset patch # User Denis Laxalde # Date 1489398073 -3600 # Mon Mar 13 10:41:13 2017 +0100 # Node ID 613e7e42d14311059bdaf4c500147f9e35fb31fa # Parent 2620dc84c013ab9d60d9327aa33435936bd25a01 # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r 613e7e42d143 # EXP-Topic linerange-log/hgweb-filelog hgweb: add a "patch" query parameter to filelog command Add support for a "patch" query parameter in filelog web command similar to --patch option of `hg log` to display the diff of each changeset in the table of revisions. The diff text is displayed in a dedicated row of the table that follows the existing one for each entry and spans over all columns. Only update "paper" template in this patch. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -973,6 +973,10 @@ def filelog(web, req, tmpl): morevars = copy.copy(tmpl.defaults['sessionvars']) morevars['revcount'] = revcount * 2 +patch = 'patch' in req.form +if patch: +lessvars['patch'] = morevars['patch'] = req.form['patch'][0] + count = fctx.filerev() + 1 start = max(0, count - revcount) # first rev on this page end = min(count, start + revcount) # last rev on this page @@ -981,12 +985,27 @@ def filelog(web, req, tmpl): repo = web.repo revs = fctx.filelog().revs(start, end - 1) entries = [] + +diffstyle = web.config('web', 'style', 'paper') +if 'style' in req.form: +diffstyle = req.form['style'][0] + +def diff(fctx): +ctx = fctx.changectx() +basectx = ctx.p1() +path = fctx.path() +return webutil.diffs(web.repo, tmpl, ctx, basectx, [path], diffstyle) + for i in revs: iterfctx = fctx.filectx(i) +diffs = None +if patch: +diffs = diff(iterfctx) entries.append(dict( parity=next(parity), filerev=i, file=f, +diff=diffs, rename=webutil.renamelink(iterfctx), **webutil.commonentry(repo, iterfctx))) entries.reverse() @@ -1000,6 +1019,7 @@ def filelog(web, req, tmpl): nav=nav, symrev=webutil.symrevorshortnode(req, fctx), entries=entries, +patch=patch, latestentry=latestentry, revcount=revcount, morevars=morevars, diff --git a/mercurial/templates/paper/filelogentry.tmpl b/mercurial/templates/paper/filelogentry.tmpl --- a/mercurial/templates/paper/filelogentry.tmpl +++ b/mercurial/templates/paper/filelogentry.tmpl @@ -6,3 +6,4 @@ {inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{bookmarks%changelogtag}{rename%filelogrename} + {if(patch, '{diff}')} diff --git a/tests/test-hgweb-filelog.t b/tests/test-hgweb-filelog.t --- a/tests/test-hgweb-filelog.t +++ b/tests/test-hgweb-filelog.t @@ -221,6 +221,7 @@ tip - two revisions a-branch + Thu, 01 Jan 1970 00:00:00 + test @@ -229,6 +230,7 @@ tip - two revisions a-tag a-bookmark + @@ -340,6 +342,7 @@ second version - two revisions a-branch + Thu, 01 Jan 1970 00:00:00 + test @@ -348,6 +351,7 @@ second version - two revisions a-tag a-bookmark + @@ -459,6 +463,7 @@ first deleted - one revision a-tag a-bookmark + @@ -570,6 +575,7 @@ first version - one revision a-tag a-bookmark + @@ -762,6 +768,135 @@ should show base link, use spartan becau +filelog with patch + + $ (get-with-headers.py localhost:$HGPORT 'log/4/a?patch=1') + 200 Script output follows + + http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";> + http://www.w3.org/1999/xhtml"; xml:lang="en-US"> + + + + + + + test: a history + + + + + + + + + https://mercurial-scm.org/";> + + + + log + graph + tags + bookmarks + branches + + + changeset + browse + + + file + diff + comparison + annotate + file log + raw + + + help + + + + + + + + + + Mercurial + + log a @ 4:3f41bc784e7e + a-branch + + + + + + Find changesets by keywords (author, files, the commit message), revision + number or hash, or revset expression. + + + + less + more + | (0) tip + + + + +age +author +description + + + + +Thu, 01 Jan 1970 00:00:00 + +test + + second a + a-branch + + + + --- /dev/null Thu Jan 01 00:00:00 1970 + + +++ b/a Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +b + +Thu, 01 Jan 1970 00:00:00 + +test + + first a + a-tag a-bookmark + + + + --- /dev/null Thu Jan 01
[PATCH 1 of 7 V3] hgweb: drop "parity" from webutil.diffs arguments
# HG changeset patch # User Denis Laxalde # Date 1489398019 -3600 # Mon Mar 13 10:40:19 2017 +0100 # Node ID 2620dc84c013ab9d60d9327aa33435936bd25a01 # Parent 527a247f114f8af37326805fd6cce923f9ac6453 # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r 2620dc84c013 # EXP-Topic linerange-log/hgweb-filelog hgweb: drop "parity" from webutil.diffs arguments This function yields "diffblock" templates which do not make use of "parity". In fact, maybe this template *should* make use of parity stripes as it would make /rev views more readable with the diff involves several files? diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -756,12 +756,11 @@ def filediff(web, req, tmpl): ctx = fctx.changectx() basectx = ctx.p1() -parity = paritygen(web.stripecount) style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] -diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, style) +diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], style) if fctx is not None: rename = webutil.renamelink(fctx) ctx = fctx diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py --- a/mercurial/hgweb/webutil.py +++ b/mercurial/hgweb/webutil.py @@ -388,8 +388,7 @@ def changesetentry(web, req, tmpl, ctx): if 'style' in req.form: style = req.form['style'][0] -parity = paritygen(web.stripecount) -diff = diffs(web.repo, tmpl, ctx, basectx, None, parity, style) +diff = diffs(web.repo, tmpl, ctx, basectx, None, style) parity = paritygen(web.stripecount) diffstatsgen = diffstatgen(ctx, basectx) @@ -414,7 +413,7 @@ def listfilediffs(tmpl, files, node, max if len(files) > max: yield tmpl('fileellipses') -def diffs(repo, tmpl, ctx, basectx, files, parity, style): +def diffs(repo, tmpl, ctx, basectx, files, style): def prettyprintlines(lines, blockno): for lineno, l in enumerate(lines, 1): @@ -450,7 +449,7 @@ def diffs(repo, tmpl, ctx, basectx, file for hunkrange, hunklines in hunks: lines.extend(hunklines) if lines: -yield tmpl('diffblock', parity=next(parity), blockno=blockno, +yield tmpl('diffblock', blockno=blockno, lines=prettyprintlines(lines, blockno)) def compare(tmpl, context, leftlines, rightlines): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 7 V3] hgweb: expose a followlines UI in filerevision view (RFC)
# HG changeset patch # User Denis Laxalde # Date 1489594320 -3600 # Wed Mar 15 17:12:00 2017 +0100 # Node ID cb742fcfe0edb2d393b59674c4eebcf8775ecfe1 # Parent 9e3ae74c1ca558f0584067c62835bec82034c245 # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r cb742fcfe0ed hgweb: expose a followlines UI in filerevision view (RFC) In filerevision view (/file//) we add some event listeners on mouse selection of elements in the block. Those listeners will capture the range of mouse-selected lines and, upon mouse release, a box inviting to follow the history of selected lines will show up. This action is advertised by a :after pseudo-element on file lines that shows up on hover and invite to "select a block of lines to follow its history". This is proposal implementation, comments welcome on any aspects. diff --git a/mercurial/templates/paper/filerevision.tmpl b/mercurial/templates/paper/filerevision.tmpl --- a/mercurial/templates/paper/filerevision.tmpl +++ b/mercurial/templates/paper/filerevision.tmpl @@ -73,6 +73,11 @@ line source {text%fileline} + + +installLineSelect("{url|urlescape}log/{symrev}/{file|urlescape}"); + + diff --git a/mercurial/templates/static/mercurial.js b/mercurial/templates/static/mercurial.js --- a/mercurial/templates/static/mercurial.js +++ b/mercurial/templates/static/mercurial.js @@ -434,6 +434,81 @@ function ajaxScrollInit(urlFormat, scrollHandler(); } +//** install mouse event listeners on */ +function installLineSelect(targetUri) { +var sourcelines = document.getElementsByClassName('sourcelines')[0]; +if (typeof sourcelines === 'undefined') { +return; +} +// add event listener to the whole block to have +// it available in all children +sourcelines.addEventListener('mousedown', lineSelectStart); + +//** event handler for "mousedown" */ +function lineSelectStart(e) { +var startElement = e.target; +if (startElement.tagName !== 'SPAN') { +// we may be on a +return; +} +// retarget "mouseup" to sourcelines element so that if this event +// occurs outside the we don't miss it +sourcelines.setCapture(); +// drop any prior +var previousInvite = document.getElementById('followlines'); +if (previousInvite !== null) { +previousInvite.parentNode.removeChild(previousInvite); +} + +var startId = parseInt(startElement.id.slice(1)); + +//** event handler for "mouseup" */ +function lineSelectEnd(e) { +// remove "mouseup" listener +sourcelines.removeEventListener('mouseup', lineSelectEnd); + +var endElement = e.target; +if (endElement.tagName !== 'SPAN') { +// not on , probably outside , +// we cannot compute endId +return; +} + +// compute line range (startId, endId) and insert the +// "followlines" element +var endId = parseInt(endElement.id.slice(1)); +if (endId == startId) { +return; +} +var inviteElement = endElement; +if (endId < startId) { +var tmp = endId; +endId = startId; +startId = tmp; +inviteElement = startElement; +} +var div = followlinesBox(startId, endId); +inviteElement.appendChild(div); +} + +sourcelines.addEventListener('mouseup', lineSelectEnd); + +} + +//** return a with a link for followlines action */ +function followlinesBox(startId, endId) { +var div = document.createElement('div'); +div.id = 'followlines'; +var a = document.createElement('a'); +var url = targetUri + '?patch=&linerange=' + startId + ':' + endId; +a.setAttribute('href', url); +a.textContent = 'follow lines ' + startId + ':' + endId; +div.appendChild(a); +return div; +} + +} + document.addEventListener('DOMContentLoaded', function() { process_dates(); }, false); diff --git a/mercurial/templates/static/style-paper.css b/mercurial/templates/static/style-paper.css --- a/mercurial/templates/static/style-paper.css +++ b/mercurial/templates/static/style-paper.css @@ -276,10 +276,28 @@ td.annotate:hover div.annotate-info { di float: left; } +div.overflow pre.sourcelines > span:hover:after { + content: "select a block of lines to follow its history"; + display: inline; + float: right; + line-height: 1em; + background-color: #FF; + color: #001199; +} + .sourcelines > span:target, tr:target td { background-color: #bfdfff; } +div#followlines { + display: inline; + position: absolute; + background-color: #FF; + border: 1px solid #999; + color: #00; + padding: 2px; +} + .sourcelines > a { displa
[PATCH 4 of 7 V3] hgweb: handle a "linerange" request parameter in filelog command
# HG changeset patch # User Denis Laxalde # Date 1484844060 -3600 # Thu Jan 19 17:41:00 2017 +0100 # Node ID 1fb2e7f3ed38dc79379cccb04133e745fd5825fa # Parent b93ba42f47ac861922b483ce9870fbe6a5cc412c # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r 1fb2e7f3ed38 # EXP-Topic linerange-log/hgweb-filelog hgweb: handle a "linerange" request parameter in filelog command We now handle a "linerange" URL query parameter to filter filelog using a logic similar to followlines() revset. The URL syntax is: log//?linerange=: As a result, filelog entries only consists of revision changing specified line range. The linerange information is propagated to "more"/"less" navigation links but not to numeric navigation links as this would apparently require a dedicated "revnav" class. Only update the "paper" template in this patch. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -28,6 +28,7 @@ from .common import ( from .. import ( archival, +context, encoding, error, graphmod, @@ -968,6 +969,8 @@ def filelog(web, req, tmpl): except ValueError: pass +lrange = webutil.linerange(req) + lessvars = copy.copy(tmpl.defaults['sessionvars']) lessvars['revcount'] = max(revcount / 2, 1) morevars = copy.copy(tmpl.defaults['sessionvars']) @@ -996,24 +999,49 @@ def filelog(web, req, tmpl): path = fctx.path() return webutil.diffs(web.repo, tmpl, ctx, basectx, [path], diffstyle) -for i in revs: -iterfctx = fctx.filectx(i) -diffs = None -if patch: -diffs = diff(iterfctx) -entries.append(dict( -parity=next(parity), -filerev=i, -file=f, -diff=diffs, -rename=webutil.renamelink(iterfctx), -**webutil.commonentry(repo, iterfctx))) -entries.reverse() +linerange = None +if lrange is not None: +linerange = webutil.formatlinerange(*lrange) +# deactivate numeric nav links when linerange is specified as this +# would required a dedicated "revnav" class +nav = None +ancestors = context.blockancestors(fctx, *lrange) +for i, (c, lr) in enumerate(ancestors, 1): +diffs = None +if patch: +diffs = diff(c) +# follow renames accross filtered (not in range) revisions +path = c.path() +entries.append(dict( +parity=next(parity), +filerev=c.rev(), +file=path, +diff=diffs, +linerange=webutil.formatlinerange(*lr), +**webutil.commonentry(repo, c))) +if i == revcount: +break +lessvars['linerange'] = webutil.formatlinerange(*lrange) +morevars['linerange'] = lessvars['linerange'] +else: +for i in revs: +iterfctx = fctx.filectx(i) +diffs = None +if patch: +diffs = diff(iterfctx) +entries.append(dict( +parity=next(parity), +filerev=i, +file=f, +diff=diffs, +rename=webutil.renamelink(iterfctx), +**webutil.commonentry(repo, iterfctx))) +entries.reverse() +revnav = webutil.filerevnav(web.repo, fctx.path()) +nav = revnav.gen(end - 1, revcount, count) latestentry = entries[:1] -revnav = webutil.filerevnav(web.repo, fctx.path()) -nav = revnav.gen(end - 1, revcount, count) return tmpl("filelog", file=f, nav=nav, @@ -1021,6 +1049,7 @@ def filelog(web, req, tmpl): entries=entries, patch=patch, latestentry=latestentry, +linerange=linerange, revcount=revcount, morevars=morevars, lessvars=lessvars, diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py --- a/mercurial/hgweb/webutil.py +++ b/mercurial/hgweb/webutil.py @@ -18,6 +18,7 @@ from ..node import hex, nullid, short from .common import ( ErrorResponse, +HTTP_BAD_REQUEST, HTTP_NOT_FOUND, paritygen, ) @@ -317,6 +318,26 @@ def filectx(repo, req): return fctx +def linerange(req): +linerange = req.form.get('linerange') +if linerange is None: +return None +if len(linerange) > 1: +raise ErrorResponse(HTTP_BAD_REQUEST, +'redundant linerange parameter') +try: +fromline, toline = map(int, linerange[0].split(':', 1)) +except ValueError: +raise ErrorResponse(HTTP_BAD_REQUEST, +'invalid linerange parameter') +try: +return util.processlinerange(fromline, tol
[PATCH 6 of 7 V3] hgweb: filter diff hunks when 'linerange' and 'patch' are specified in filelog
# HG changeset patch # User Denis Laxalde # Date 1489414640 -3600 # Mon Mar 13 15:17:20 2017 +0100 # Node ID 9e3ae74c1ca558f0584067c62835bec82034c245 # Parent 18d413236b1670c476584c4a6d6e103639ae7996 # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r 9e3ae74c1ca5 # EXP-Topic linerange-log/hgweb-filelog hgweb: filter diff hunks when 'linerange' and 'patch' are specified in filelog diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -993,11 +993,12 @@ def filelog(web, req, tmpl): if 'style' in req.form: diffstyle = req.form['style'][0] -def diff(fctx): +def diff(fctx, linerange=None): ctx = fctx.changectx() basectx = ctx.p1() path = fctx.path() -return webutil.diffs(web.repo, tmpl, ctx, basectx, [path], diffstyle) +return webutil.diffs(web.repo, tmpl, ctx, basectx, [path], diffstyle, + linerange=linerange) linerange = None if lrange is not None: @@ -1009,7 +1010,7 @@ def filelog(web, req, tmpl): for i, (c, lr) in enumerate(ancestors, 1): diffs = None if patch: -diffs = diff(c) +diffs = diff(c, linerange=lr) # follow renames accross filtered (not in range) revisions path = c.path() entries.append(dict( diff --git a/tests/test-hgweb-filelog.t b/tests/test-hgweb-filelog.t --- a/tests/test-hgweb-filelog.t +++ b/tests/test-hgweb-filelog.t @@ -1159,6 +1159,328 @@ filelog with patch +filelog with 'linerange' and 'patch' + + $ cat c + b + c + $ cat < c + > b + > c+ + > + > a + > a + > + > d + > e + > f + > EOF + $ hg ci -m 'make c bigger and touch its beginning' c + $ cat < c + > b + > c+ + > + > a + > a + > + > d + > e+ + > f + > EOF + $ hg ci -m 'just touch end of c' c + $ cat < c + > b + > c++ + > + > a + > a + > + > d + > e+ + > f + > EOF + $ hg ci -m 'touch beginning of c' c + $ cat < c + > b- + > c++ + > + > a + > a + > + > d + > e+ + > f+ + > EOF + $ hg ci -m 'touching beginning and end of c' c + $ hg log -r 'followlines(c, 1:2, startrev=tip) and follow(c)' -p + changeset: 0:6563da9dcf87 + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: b + + diff -r -r 6563da9dcf87 b + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/b Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +b + + changeset: 7:46c1a66bd8fc + branch: a-branch + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: change c + + diff -r c9637d3cc8ef -r 46c1a66bd8fc c + --- a/c Thu Jan 01 00:00:00 1970 + + +++ b/c Thu Jan 01 00:00:00 1970 + + @@ -1,1 +1,2 @@ + b + +c + + changeset: 8:c40702dbfc57 + branch: a-branch + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: make c bigger and touch its beginning + + diff -r 46c1a66bd8fc -r c40702dbfc57 c + --- a/c Thu Jan 01 00:00:00 1970 + + +++ b/c Thu Jan 01 00:00:00 1970 + + @@ -1,2 +1,9 @@ + b + -c + +c+ + + + +a + +a + + + +d + +e + +f + + changeset: 10:f94018eca295 + branch: a-branch + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: touch beginning of c + + diff -r 07faa31d6d1c -r f94018eca295 c + --- a/c Thu Jan 01 00:00:00 1970 + + +++ b/c Thu Jan 01 00:00:00 1970 + + @@ -1,5 +1,5 @@ + b + -c+ + +c++ + + a + a + + changeset: 11:ea4193bdd9bf + branch: a-branch + tag: tip + user:test + date:Thu Jan 01 00:00:00 1970 + + summary: touching beginning and end of c + + diff -r f94018eca295 -r ea4193bdd9bf c + --- a/c Thu Jan 01 00:00:00 1970 + + +++ b/c Thu Jan 01 00:00:00 1970 + + @@ -1,4 +1,4 @@ + -b + +b- + c++ + + a + @@ -6,4 +6,4 @@ + + d + e+ + -f + +f+ + + $ (get-with-headers.py localhost:$HGPORT 'log/tip/c?linerange=1:2&patch=') + 200 Script output follows + + http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";> + http://www.w3.org/1999/xhtml"; xml:lang="en-US"> + + + + + + + test: c history + + + + + + + + + https://mercurial-scm.org/";> + + + + log + graph + tags + bookmarks + branches + + + changeset + browse + + + file + diff + comparison + annotate + file log + raw + + + help + + + + + + + + + + Mercurial + + log c @ 11:ea4193bdd9bf + a-branch tip +(following lines 1:2 back to filelog) + + + + + + Find changesets by keywords (author, files, the commit message), revision + number or hash, or revset expression. + + + + less + more + | + + +
[PATCH 5 of 7 V3] hgweb: add a 'linerange' parameter to webutil.diffs()
# HG changeset patch # User Denis Laxalde # Date 1489414549 -3600 # Mon Mar 13 15:15:49 2017 +0100 # Node ID 18d413236b1670c476584c4a6d6e103639ae7996 # Parent 1fb2e7f3ed38dc79379cccb04133e745fd5825fa # Available At http://hg.logilab.org/users/dlaxalde/hg # hg pull http://hg.logilab.org/users/dlaxalde/hg -r 18d413236b16 # EXP-Topic linerange-log/hgweb-filelog hgweb: add a 'linerange' parameter to webutil.diffs() This is used to filter out hunks based on their range (with respect to 'node2' for patch.diffhunks() call, i.e. 'ctx' for webutil.diffs()). This is the simplest way to filter diff hunks, here done on server side. Later on, it might be interesting to perform this filtering on client side and expose a "toggle" action to alternate between full and filtered diff. diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py --- a/mercurial/hgweb/webutil.py +++ b/mercurial/hgweb/webutil.py @@ -434,7 +434,7 @@ def listfilediffs(tmpl, files, node, max if len(files) > max: yield tmpl('fileellipses') -def diffs(repo, tmpl, ctx, basectx, files, style): +def diffs(repo, tmpl, ctx, basectx, files, style, linerange=None): def prettyprintlines(lines, blockno): for lineno, l in enumerate(lines, 1): @@ -468,6 +468,11 @@ def diffs(repo, tmpl, ctx, basectx, file header = header[1:] lines = [h + '\n' for h in header] for hunkrange, hunklines in hunks: +if linerange is not None and hunkrange is not None: +s1, l1, s2, l2 = hunkrange +lb, ub = linerange +if not (lb <= s2 < ub or lb < s2 + l2 <= ub): +continue lines.extend(hunklines) if lines: yield tmpl('diffblock', blockno=blockno, ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 7 of 7] tests: add a test case verifying that mq respects --no-git option
FYI, there's a discussion going on about the "correct" behavior on the issue tracker: https://bz.mercurial-scm.org/show_bug.cgi?id=5510 On 3/21/17 8:30 PM, Ryan McElroy wrote: Overall this series looks good to me, except for this last patch. See inline comments. For now, I'd take the rest of this series if we're okay with the BC break, and just drop this patch while we figure out the mq stuff. On 3/21/17 5:08 PM, Alexander Fomin wrote: # HG changeset patch # User Alexander Fomin # Date 1490113938 25200 # Tue Mar 21 09:32:18 2017 -0700 # Node ID 9a11a79f6bcdd1134484ddd8eace997b55e7073a # Parent e9044ade1523e847877f4eee1d4e06734e2aa4cd tests: add a test case verifying that mq respects --no-git option This patch adds a test case to verify that --no-git option still works in mq after making it explicitly request binary diff even in Git mode (issue5510). diff --git a/tests/test-mq.t b/tests/test-mq.t --- a/tests/test-mq.t +++ b/tests/test-mq.t @@ -1162,6 +1162,21 @@ check binary patches can be popped and p 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus +check binary patches respect --no-git + + $ cat > writebin.py < import sys + > path = sys.argv[1] + > open(path, 'wb').write('BIN\x42RY') Hex 42 is the character 'B', isn't it? So this isn't binary at all. Also, binary detection just searches for \x00 I think. So that would be more appropriate to use here. + > EOF + $ python writebin.py answer Rather than creating a little python program, I think you could just use printf here: $ printf 'BIN\x00RY' > answer + + $ python "$TESTDIR/md5sum.py" answer + ce0b4fda508e3d9f9ece98f8e823b6f7 answer What is the reason for the md5sum here? Did you want to check round-tripping? (but I don't see that here) + $ hg add answer + $ hg qnew -f --no-git addanswer What does --no-git do before this patch series? I don't see any differences in patch files with or without --no-git today, so I'm not sure it's actually respected today. + $ grep diff .hg/patches/addanswer + diff -r [a-f0-9]* -r [a-f0-9]* answer (re) strip again ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_mailman_listinfo_mercurial-2Ddevel&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=2gvSPeBA6Q2eteGH5pR0M0qoiyQsjRbkUa0BkXzQ2C4&s=eYuPnseRo71oYyYXfcJgzwAbECl69gbMV2QU6VUmAVw&e= ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] status: support commands.status.relative config
I'm +100 on this patch. We've been doing this in tweakdefaults for ages. Everyone loves it. On 3/22/17 4:35 AM, Martin von Zweigbergk via Mercurial-devel wrote: # HG changeset patch # User Martin von Zweigbergk # Date 1490143844 25200 # Tue Mar 21 17:50:44 2017 -0700 # Node ID e0e123324f205071c80657079ff83a4e58db862c # Parent 102f291807c92864a2231e5e925d6cd64783bb59 status: support commands.status.relative config When the config is set to true, status output becomes relative to the working directory. This has bugged me since I started using hg and it turns it is sillily simple to support it (unless I missed something, of course). We could also add a --relative flag, but I would personally always want that on, and I haven't heard any use for having it sometimes on, so this patch only lets you enable it via config. diff -r 102f291807c9 -r e0e123324f20 mercurial/commands.py --- a/mercurial/commands.py Mon Mar 20 16:34:12 2017 -0700 +++ b/mercurial/commands.py Tue Mar 21 17:50:44 2017 -0700 @@ -4734,7 +4734,8 @@ else: node1, node2 = scmutil.revpair(repo, revs) -if pats: +if pats or (not ui.plain() and +ui.configbool('commands', 'status.relative', False)): Style-nits: * The "false" isn't necessary -- that's the default, isn't it? * Also, I think it would be clearer to divide this into two lines: relative = not ui.plain and ui.configbool('commands', 'status.relative') if pats or relative: cwd = repo.getcwd() else: cwd = '' diff -r 102f291807c9 -r e0e123324f20 mercurial/help/config.txt --- a/mercurial/help/config.txt Mon Mar 20 16:34:12 2017 -0700 +++ b/mercurial/help/config.txt Tue Mar 21 17:50:44 2017 -0700 @@ -417,6 +417,10 @@ ``commands`` -- +``status.relative`` +Make paths in ``hg status`` output relative to the current directory. +(default: False) + ``update.requiredest`` Require that the user pass a destination when running ``hg update``. For example, ``hg update .::`` will be allowed, but a plain ``hg update`` diff -r 102f291807c9 -r e0e123324f20 tests/test-status.t --- a/tests/test-status.t Mon Mar 20 16:34:12 2017 -0700 +++ b/tests/test-status.t Tue Mar 21 17:50:44 2017 -0700 @@ -40,6 +40,20 @@ ? ../b/2/in_b_2 ? ../b/in_b ? ../in_root + $ hg --config commands.status.relative=True status --cwd a + ? 1/in_a_1 + ? in_a + ? ../b/1/in_b_1 + ? ../b/2/in_b_2 + ? ../b/in_b + ? ../in_root + $ HGPLAIN=1 hg --config commands.status.relative=True status --cwd a + ? a/1/in_a_1 + ? a/in_a + ? b/1/in_b_1 + ? b/2/in_b_2 + ? b/in_b + ? in_root $ hg status --cwd b ? a/1/in_a_1 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] checkheads: extract obsolete post processing in its own function
On 3/21/17 10:42 PM, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David # Date 1490135413 -3600 # Tue Mar 21 23:30:13 2017 +0100 # Node ID 787354f0d60eccda66ba0de4db8e6e47897acc7c # Parent 66c3ae6d886cae0e3a3cff6a0058e2d2a866fd9d # EXP-Topic checkheads # Available At https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk&s=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI&e= # hg pull https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Jw8rundaE7TbmqBYd1txIQ&m=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk&s=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI&e= -r 787354f0d60e checkheads: extract obsolete post processing in its own function The checkheads function is long and complex, extract that logic in a subfunction is win in itself. I agree, this looks good to me. As the comment in the code says, this postprocessing is currently very basic and either misbehave or fails to detect valid push in many cases. My deeper motive for this extraction is to be make it easier to provide extensive testing of this case and strategy to cover them. Final test and logic will makes it to core once done. diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -343,38 +343,12 @@ def checkheads(pushop): oldhs.update(unsyncedheads) candidate_newhs.update(unsyncedheads) dhs = None # delta heads, the new heads on branch -discardedheads = set() if not repo.obsstore: +discardedheads = set() newhs = candidate_newhs else: -# remove future heads which are actually obsoleted by another -# pushed element: -# -# XXX as above, There are several cases this code does not handle -# XXX properly -# -# (1) if is public, it won't be affected by obsolete marker -# and a new is created -# -# (2) if the new heads have ancestors which are not obsolete and -# not ancestors of any other heads we will have a new head too. -# -# These two cases will be easy to handle for known changeset but -# much more tricky for unsynced changes. -# -# In addition, this code is confused by prune as it only looks for -# successors of the heads (none if pruned) leading to issue4354 -newhs = set() -for nh in candidate_newhs: -if nh in repo and repo[nh].phase() <= phases.public: -newhs.add(nh) -else: -for suc in obsolete.allsuccessors(repo.obsstore, [nh]): -if suc != nh and suc in allfuturecommon: -discardedheads.add(nh) -break -else: -newhs.add(nh) +newhs, discardedheads = _postprocessobsolete(repo, allfuturecommon, + candidate_newhs) unsynced = sorted(h for h in unsyncedheads if h not in discardedheads) if unsynced: if None in unsynced: @@ -434,3 +408,41 @@ def checkheads(pushop): repo.ui.note((" %s\n") % short(h)) if errormsg: raise error.Abort(errormsg, hint=hint) + +def _postprocessobsolete(repo, common, candidate): +"""post process the list of new heads with obsolescence information + +Exist as a subfunction to contains the complexity and allow extensions to +experiment with smarter logic. +Returns (newheads, discarded_heads) tuple +""" +# remove future heads which are actually obsoleted by another +# pushed element: +# +# XXX as above, There are several cases this code does not handle +# XXX properly +# +# (1) if is public, it won't be affected by obsolete marker +# and a new is created +# +# (2) if the new heads have ancestors which are not obsolete and +# not ancestors of any other heads we will have a new head too. +# +# These two cases will be easy to handle for known changeset but +# much more tricky for unsynced changes. +# +# In addition, this code is confused by prune as it only looks for +# successors of the heads (none if pruned) leading to issue4354 +newhs = set() +discarded = set() +for nh in candidate: +if nh in repo and repo[nh].phase() <= phases.public: +newhs.add(nh) +else: +for suc in obsolete.allsuccessors(repo.obsstore, [nh]): +if suc != nh and suc in common: +discarded.add
[PATCH 10 of 11 V2] ui: simplify geteditor
# HG changeset patch # User Jun Wu # Date 1489456194 25200 # Mon Mar 13 18:49:54 2017 -0700 # Node ID 713d562d0a2426c8658675a66158e6c412ae9dcc # Parent 9f90c479585c75ece920043c220093058d968b97 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 713d562d0a24 ui: simplify geteditor Now $EDITOR and $VISUAL will affect ui.editor directly. The logic can be simplified. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1308,7 +1308,5 @@ class ui(object): editor = 'vi' return (encoding.environ.get("HGEDITOR") or -self.config("ui", "editor") or -encoding.environ.get("VISUAL") or -encoding.environ.get("EDITOR", editor)) +self.config("ui", "editor", editor)) @util.propertycache ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 11 of 11 V2] pager: do not read from environment variable
# HG changeset patch # User Jun Wu # Date 1489456112 25200 # Mon Mar 13 18:48:32 2017 -0700 # Node ID d2b34be3b64a6ca60644576b806e5b7172d524cc # Parent 713d562d0a2426c8658675a66158e6c412ae9dcc # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r d2b34be3b64a pager: do not read from environment variable We have converted $PAGER to config, ui.pager() now can just read the config, without looking at environment variables. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -846,12 +846,6 @@ class ui(object): return -# TODO: add a "system defaults" config section so this default -# of more(1) can be easily replaced with a global -# configuration file. For example, on OS X the sane default is -# less(1), not more(1), and on debian it's -# sensible-pager(1). We should probably also give the system -# default editor command similar treatment. -envpager = encoding.environ.get('PAGER', 'more') -pagercmd = self.config('pager', 'pager', envpager) +fallbackpager = 'more' +pagercmd = self.config('pager', 'pager', fallbackpager) if not pagercmd: return ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 09 of 11 V2] scmutil: remove rcpath
# HG changeset patch # User Jun Wu # Date 1489455385 25200 # Mon Mar 13 18:36:25 2017 -0700 # Node ID 9f90c479585c75ece920043c220093058d968b97 # Parent 23b2b1ed59763e5e676f06a4ac4f6bf567874220 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 9f90c479585c scmutil: remove rcpath It's no longer used. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -423,31 +423,4 @@ def envconfig(envlist, env=None): return result -_rcpath = None - -def rcpath(): -'''return hgrc search path. if env var HGRCPATH is set, use it. -for each item in path, if directory, use files ending in .rc, -else use item. -make HGRCPATH empty to only look in .hg/hgrc of current repo. -if no HGRCPATH, use default os-specific path.''' -global _rcpath -if _rcpath is None: -if 'HGRCPATH' in encoding.environ: -_rcpath = [] -for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): -if not p: -continue -p = util.expandpath(p) -if os.path.isdir(p): -for f, kind in osutil.listdir(p): -if f.endswith('.rc'): -_rcpath.append(os.path.join(p, f)) -else: -_rcpath.append(p) -else: -paths = defaultrcpath() + systemrcpath() + userrcpath() -_rcpath = map(os.path.normpath, paths) -return _rcpath - _rccomponents = None ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 08 of 11 V2] config: list environment variables in debug output
# HG changeset patch # User Jun Wu # Date 1489455351 25200 # Mon Mar 13 18:35:51 2017 -0700 # Node ID 23b2b1ed59763e5e676f06a4ac4f6bf567874220 # Parent add83f47bf3a51edbd58aa0fb6e571d186bdae6e # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 23b2b1ed5976 config: list environment variables in debug output So we can verify the feature in tests. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1803,6 +1803,12 @@ def config(ui, repo, *values, **opts): ui.pager('config') fm = ui.formatter('config', opts) -for f in scmutil.rcpath(): -ui.debug('read config from: %s\n' % f) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +ui.debug('read config from: %s\n' % f) +elif t == 'items' and f: +for item in f: +source = item[3] +ui.debug('set config by: %s\n' % source) + untrusted = bool(opts.get('untrusted')) if values: diff --git a/tests/test-hgrc.t b/tests/test-hgrc.t --- a/tests/test-hgrc.t +++ b/tests/test-hgrc.t @@ -177,4 +177,18 @@ plain hgrc --quiet: ui.quiet=False +with environment variables + + $ PAGER=p1 EDITOR=e1 VISUAL=e2 hg showconfig --debug + set config by: $EDITOR + set config by: $VISUAL + set config by: $PAGER + read config from: $TESTTMP/hgrc + repo: bundle.mainreporoot=$TESTTMP + $PAGER: pager.pager=p1 + $VISUAL: ui.editor=e2 + --verbose: ui.verbose=False + --debug: ui.debug=True + --quiet: ui.quiet=False + plain mode with exceptions ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 07 of 11 V2] ui: use scmutil.rccomponents to load configs (BC)
# HG changeset patch # User Jun Wu # Date 1489462886 25200 # Mon Mar 13 20:41:26 2017 -0700 # Node ID add83f47bf3a51edbd58aa0fb6e571d186bdae6e # Parent df768455486ff51b4047fd3a8dfbef158516d2aa # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r add83f47bf3a ui: use scmutil.rccomponents to load configs (BC) This is BC because system configs won't be able to override $EDITOR, $PAGER. The new behavior is arguably more rational. diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -212,6 +212,18 @@ class ui(object): u = cls() # we always trust global config files -for f in scmutil.rcpath(): -u.readconfig(f, trust=True) +for (t, f) in scmutil.rccomponents(): +if t == 'path': +u.readconfig(f, trust=True) +elif t == 'items': +sections = set() +for section, name, value, source in f: +# do not set ocfg +u._tcfg.set(section, name, value, source) +u._ucfg.set(section, name, value, source) +sections.add(section) +for section in sections: +u.fixconfig(section=section) +else: +raise error.ProgrammingError('unexpected rccomponent: %s' % t) return u diff --git a/tests/test-config-env.py b/tests/test-config-env.py new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py @@ -0,0 +1,48 @@ +# Test the config layer generated by environment variables + +from __future__ import absolute_import, print_function + +import os + +from mercurial import ( +encoding, +scmutil, +ui as uimod, +) + +testtmp = encoding.environ['TESTTMP'] + +# prepare hgrc files +def join(name): +return os.path.join(testtmp, name) + +with open(join('sysrc'), 'w') as f: +f.write('[ui]\neditor=e0\n[pager]\npager=p0\n') + +with open(join('userrc'), 'w') as f: +f.write('[ui]\neditor=e1') + +# replace rcpath functions so they point to the files above +def systemrcpath(): +return [join('sysrc')] + +def userrcpath(): +return [join('userrc')] + +scmutil.systemrcpath = systemrcpath +scmutil.userrcpath = userrcpath +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc + +# utility to print configs +def printconfigs(env): +encoding.environ = env +scmutil._rccomponents = None # reset cache +ui = uimod.ui.load() +for section, name, value in ui.walkconfig(): +source = ui.configsource(section, name) +print('%s.%s=%s # %s' % (section, name, value, source)) +print('') + +# environment variable overrides +printconfigs({}) +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'}) diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out new file mode 100644 --- /dev/null +++ b/tests/test-config-env.py.out @@ -0,0 +1,6 @@ +pager.pager=p0 # $TESTTMP/sysrc:4 +ui.editor=e1 # $TESTTMP/userrc:2 + +pager.pager=p2 # $PAGER +ui.editor=e1 # $TESTTMP/userrc:2 + diff --git a/tests/test-config.t b/tests/test-config.t --- a/tests/test-config.t +++ b/tests/test-config.t @@ -165,2 +165,16 @@ edit failure abort: edit failed: false exited with status 1 [255] + +config affected by environment variables + + $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor' + $VISUAL: ui.editor=e2 + + $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep 'ui\.editor' + --config: ui.editor=e3 + + $ PAGER=p1 hg config --debug | grep 'pager\.pager' + $PAGER: pager.pager=p1 + + $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep 'pager\.pager' + --config: pager.pager=p2 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 05 of 11 V2] scmutil: extract path reading function from rccomponents
# HG changeset patch # User Jun Wu # Date 1490168676 25200 # Wed Mar 22 00:44:36 2017 -0700 # Node ID c18d9f3e0dac6d1676bd58617477c64953be96a3 # Parent 75f661b31640a914dd513d42b2ce1389c9b61c0a # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r c18d9f3e0dac scmutil: extract path reading function from rccomponents This makes the code better structured. A side effect is "normpath" will be called on paths in $HGRCPATH, which seems to be more correct. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -452,4 +452,13 @@ def rcpath(): _rccomponents = None +def _readrcpath(path): +'''path could be a single file or a directory. return a list of paths''' +p = util.expandpath(path) +join = os.path.join +if os.path.isdir(p): +return [join(p, f) for f, k in osutil.listdir(p) if f.endswith('.rc')] +else: +return [p] + def rccomponents(): '''return an ordered [(type, obj)] about where to load configs. @@ -465,4 +474,8 @@ def rccomponents(): ''' global _rccomponents + +def pathize(path): +return ('path', os.path.normpath(path)) + if _rccomponents is None: if 'HGRCPATH' in encoding.environ: @@ -473,15 +486,6 @@ def rccomponents(): if not p: continue -p = util.expandpath(p) -if os.path.isdir(p): -for f, kind in osutil.listdir(p): -if f.endswith('.rc'): -_rccomponents.append(('path', os.path.join(p, f))) -else: -_rccomponents.append(('path', p)) +_rccomponents.extend(map(pathize, _readrcpath(p))) else: -def pathize(path): -return ('path', os.path.normpath(path)) - _rccomponents = map(pathize, defaultrcpath()) _rccomponents.extend(map(pathize, systemrcpath())) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 06 of 11 V2] run-tests: drop environment variables affecting configs
# HG changeset patch # User Jun Wu # Date 1489455061 25200 # Mon Mar 13 18:31:01 2017 -0700 # Node ID df768455486ff51b4047fd3a8dfbef158516d2aa # Parent c18d9f3e0dac6d1676bd58617477c64953be96a3 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r df768455486f run-tests: drop environment variables affecting configs Those environment variables can affect future tests. Drop them so tests run reliably. diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -908,4 +908,5 @@ class Test(unittest.TestCase): for k in ('HG HGPROF CDPATH GREP_OPTIONS http_proxy no_proxy ' + 'HGPLAIN HGPLAINEXCEPT ' + + 'EDITOR VISUAL PAGER ' + 'NO_PROXY CHGDEBUG').split(): if k in env: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 03 of 11 V2] scmutil: split osrcpath to return default.d paths
# HG changeset patch # User Jun Wu # Date 1490165660 25200 # Tue Mar 21 23:54:20 2017 -0700 # Node ID 7775943a59cfaaae77e2143cbfa0bf0d8d95a447 # Parent 5de0f85888f87c705bcbc38d3e92e97b7e23d1d9 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 7775943a59cf scmutil: split osrcpath to return default.d paths After this change, there are 3 rcpath functions: - defaultrcpath - systemrcpath - userrcpath This will allow us to insert another config layer in the middle. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -392,6 +392,6 @@ def walkrepos(path, followsym=False, see dirs[:] = newdirs -def osrcpath(): -'''return default os-specific hgrc search path''' +def defaultrcpath(): +'''return rc paths in default.d''' path = [] defaultpath = os.path.join(util.datapath, 'default.d') @@ -400,7 +400,4 @@ def osrcpath(): if f.endswith('.rc'): path.append(os.path.join(defaultpath, f)) -path.extend(systemrcpath()) -path.extend(userrcpath()) -path = [os.path.normpath(f) for f in path] return path @@ -449,5 +446,6 @@ def rcpath(): _rcpath.append(p) else: -_rcpath = osrcpath() +paths = defaultrcpath() + systemrcpath() + userrcpath() +_rcpath = map(os.path.normpath, paths) return _rcpath ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 04 of 11 V2] scmutil: add a rcpath-like method to return multiple config sources
# HG changeset patch # User Jun Wu # Date 1489452890 25200 # Mon Mar 13 17:54:50 2017 -0700 # Node ID 75f661b31640a914dd513d42b2ce1389c9b61c0a # Parent 7775943a59cfaaae77e2143cbfa0bf0d8d95a447 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 75f661b31640 scmutil: add a rcpath-like method to return multiple config sources rcpath has the limitation that it only returns paths. Now we also have raw configs generated from environ. So rccomponents was added. It is similar to rcpath, but it can return mixed path and raw configs (currently calculated from environment variables). The code was basically copy-pasted from rcpath, and will be cleaned up a bit by the next patch. Python does not have union types or pattern matching. So we use a tuple (type, obj) to denote things of different types. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -450,4 +450,44 @@ def rcpath(): return _rcpath +_rccomponents = None + +def rccomponents(): +'''return an ordered [(type, obj)] about where to load configs. + +respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is +used. if $HGRCPATH is not set, the platform default will be used. + +if a directory is provided, *.rc files under it will be used. + +type could be either 'path' or 'items', if type is 'path', obj is a string, +and is the config file path. if type is 'items', obj is a list of (section, +name, value, source) that should fill the config directly. +''' +global _rccomponents +if _rccomponents is None: +if 'HGRCPATH' in encoding.environ: +# assume HGRCPATH is all about user configs so environments can be +# overridden. +_rccomponents = [('items', envconfig(_sysenvlist))] +for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): +if not p: +continue +p = util.expandpath(p) +if os.path.isdir(p): +for f, kind in osutil.listdir(p): +if f.endswith('.rc'): +_rccomponents.append(('path', os.path.join(p, f))) +else: +_rccomponents.append(('path', p)) +else: +def pathize(path): +return ('path', os.path.normpath(path)) + +_rccomponents = map(pathize, defaultrcpath()) +_rccomponents.extend(map(pathize, systemrcpath())) +_rccomponents.append(('items', envconfig(_sysenvlist))) +_rccomponents.extend(map(pathize, userrcpath())) +return _rccomponents + def intrev(rev): """Return integer for a given revision that can be used in comparison or ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 01 of 11 V2] scmutil: add a method to convert environment variables to config items
# HG changeset patch # User Jun Wu # Date 1489449998 25200 # Mon Mar 13 17:06:38 2017 -0700 # Node ID fa1618118c0603dafd8b7afbeab0e95f3e4307b0 # Parent 102f291807c92864a2231e5e925d6cd64783bb59 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r fa1618118c06 scmutil: add a method to convert environment variables to config items We will put this "config generated by environment variables" thing in a desired layer - ex. above system configs, below user configs. The method was designed to be reusable if we want more complex layers - like multiple environment-generated configs; or test environment configs using a different environ dict. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -405,4 +405,18 @@ def osrcpath(): return path +def envconfig(envlist, env=None): +'''[(section, name, value, source)] extracted from environment variables + +envlist is a list of (envname, section, configname) +''' +if env is None: +env = encoding.environ +result = [] +for envname, section, configname in envlist: +if envname not in env: +continue +result.append((section, configname, env[envname], '$%s' % envname)) +return result + _rcpath = None ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 02 of 11 V2] scmutil: define a list of configs overriding system rc, but not users
# HG changeset patch # User Jun Wu # Date 1489450537 25200 # Mon Mar 13 17:15:37 2017 -0700 # Node ID 5de0f85888f87c705bcbc38d3e92e97b7e23d1d9 # Parent fa1618118c0603dafd8b7afbeab0e95f3e4307b0 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 5de0f85888f8 scmutil: define a list of configs overriding system rc, but not users It's mainly about pager and editor for now. That's the problem the series is trying to solve. We may move other things here later. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -405,4 +405,11 @@ def osrcpath(): return path +# environments overriding system configs but not user configs +_sysenvlist = [ +('EDITOR', 'ui', 'editor'), +('VISUAL', 'ui', 'editor'), +('PAGER', 'pager', 'pager'), +] + def envconfig(envlist, env=None): '''[(section, name, value, source)] extracted from environment variables ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] show: new extension for displaying various repository data
Yuya Nishihara writes: > On Sun, 12 Mar 2017 21:38:00 -0700, Gregory Szorc wrote: >> # HG changeset patch >> # User Gregory Szorc >> # Date 1489378362 25200 >> # Sun Mar 12 21:12:42 2017 -0700 >> # Node ID d30057d358076cbe7d632cd573095af97543f932 >> # Parent 1c3352d7eaf24533ad52d4b8a024211e9189fb0b >> show: new extension for displaying various repository data > > The idea sounds nice to me. I just checked minor implementation details > about formatter. Just a quick reply (as I whittle down my backlog), but a lot of people (including myself) have a 'show' alias (inspired by 'git show'). That may or may not be a factor in this. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel