Re: [PATCH 10 of 13 V3] config: list environment variables in debug output

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
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)

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
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

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
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

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
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

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
# 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

2017-03-22 Thread Mercurial Commits
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

2017-03-22 Thread Sean Farley
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

2017-03-22 Thread Jun Wu
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

2017-03-22 Thread Sean Farley
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 V2] merge: add `internal:dumpjson` tool to `resolve`, which outputs conflict state

2017-03-22 Thread Phillip Cohen
> 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


[PATCH] convert: Fix the handling of empty changlist descriptions in P4

2017-03-22 Thread David Soria Parra
# 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


[PATCH 10 of 13 V3] config: list environment variables in debug output

2017-03-22 Thread Jun Wu
# 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 09 of 13 V3] ui: use scmutil.rccomponents to load configs (BC)

2017-03-22 Thread Jun Wu
# 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 08 of 13 V3] run-tests: drop environment variables affecting configs

2017-03-22 Thread Jun Wu
# 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 02 of 13 V3] scmutil: define a list of configs overriding system rc, but not users

2017-03-22 Thread Jun Wu
# 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

2017-03-22 Thread Jun Wu
# 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 01 of 13 V3] scmutil: add a method to convert environment variables to config items

2017-03-22 Thread Jun Wu
# 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


Re: [PATCH] doc: fix short underline which causes make -C doc to fail

2017-03-22 Thread Ryan McElroy


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=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=XwlnUJ7Dm-i0fD3GxgWTBsbB8Z7wrRzm28VTv3swSy8=ICe_Z0HfgsVXfef1aAZy7kC_51u1Iimt8HqYWdV5Jzg=


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


Re: [PATCH] checkheads: extract obsolete post processing in its own function

2017-03-22 Thread Pierre-Yves David



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_=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI=

#  hg pull
https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI=
-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


[PATCH] doc: fix short underline which causes make -C doc to fail

2017-03-22 Thread Kostia Balytskyi
# 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

2017-03-22 Thread Jun Wu
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

2017-03-22 Thread Martin von Zweigbergk via Mercurial-devel
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 2 of 2 V2] show: new extension for displaying various repository data

2017-03-22 Thread Yuya Nishihara
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

2017-03-22 Thread Yuya Nishihara
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


[PATCH] findrenames: sort files not by object id but by path for stable result

2017-03-22 Thread Yuya Nishihara
# 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] show: new extension for displaying various repository data

2017-03-22 Thread Ryan McElroy



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

2017-03-22 Thread Ryan McElroy

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

2017-03-22 Thread Ryan McElroy

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=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=huA2rodPgFB3VM_ycpq_OLuxGpg_dDjbtlRqYlYdCiU=7mjJAE3v-lJCAXwqy4z4aclKYf_Kv3qDeKZFSpMws0g=
#  hg pull 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=huA2rodPgFB3VM_ycpq_OLuxGpg_dDjbtlRqYlYdCiU=7mjJAE3v-lJCAXwqy4z4aclKYf_Kv3qDeKZFSpMws0g=
  -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 01 of 11 V2] scmutil: add a method to convert environment variables to config items

2017-03-22 Thread Ryan McElroy

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=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=dOvsJimzZK2HUO1Uuv03sjad5iNJbyVwkDFJTjCGklk=5wu-xCgtBalppj9ukMNAcetnR0vS291ibigIMAEi-4Q=
#  hg pull 
https://urldefense.proofpoint.com/v2/url?u=https-3A__bitbucket.org_quark-2Dzju_hg-2Ddraft=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=dOvsJimzZK2HUO1Uuv03sjad5iNJbyVwkDFJTjCGklk=5wu-xCgtBalppj9ukMNAcetnR0vS291ibigIMAEi-4Q=
  -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

2017-03-22 Thread Ryan McElroy
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 
> 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.
___
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)

2017-03-22 Thread Denis Laxalde
# 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==' + 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 

[PATCH 4 of 7 V3] hgweb: handle a "linerange" request parameter in filelog command

2017-03-22 Thread Denis Laxalde
# 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 

[PATCH 6 of 7 V3] hgweb: filter diff hunks when 'linerange' and 'patch' are specified in filelog

2017-03-22 Thread Denis Laxalde
# 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=')
+  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
+  

[PATCH 5 of 7 V3] hgweb: add a 'linerange' parameter to webutil.diffs()

2017-03-22 Thread Denis Laxalde
# 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

2017-03-22 Thread Ryan McElroy
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=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=2gvSPeBA6Q2eteGH5pR0M0qoiyQsjRbkUa0BkXzQ2C4=eYuPnseRo71oYyYXfcJgzwAbECl69gbMV2QU6VUmAVw=


___
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

2017-03-22 Thread Ryan McElroy

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_=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI=
#  hg pull 
https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_repo_users_marmoute_mercurial_=DwIGaQ=5VD0RTtNlTh3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=X1PCqIb1foE38fk_XWYf-aaAwDmJ4P0klZVtI7TGEWk=BDwmpGmjYfrQ5_BZQ-19-vlGJwbvEH2-rewqp3-9cCI=
  -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:
+

[PATCH 10 of 11 V2] ui: simplify geteditor

2017-03-22 Thread Jun Wu
# 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 08 of 11 V2] config: list environment variables in debug output

2017-03-22 Thread Jun Wu
# 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 06 of 11 V2] run-tests: drop environment variables affecting configs

2017-03-22 Thread Jun Wu
# 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

2017-03-22 Thread Jun Wu
# 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

2017-03-22 Thread Jun Wu
# 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

2017-03-22 Thread Jun Wu
# 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

2017-03-22 Thread Jun Wu
# 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 2 of 2 V2] show: new extension for displaying various repository data

2017-03-22 Thread Gregory Szorc
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?
I'm still a bit confused as to how formatters work :/


>
> 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)
> * 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`.
>
> 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 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.
>
> 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.
>
> 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 positional argument to `hg log`
> can be a file path and if there is a conflict between a path name and
> a view 

[PATCH 2 of 2 V2] show: new extension for displaying various repository data

2017-03-22 Thread Gregory Szorc
# 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)
* 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`.

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 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.

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.

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 positional argument to `hg log`
can be a file path and if there is a conflict between a path name and
a view name, behavior is ambiguous. We could have introduced
`hg log --view` or similar, but we felt that required too much typing
(we don't want to require a command flag to show a view) and wasn't
very discoverable. Furthermore, `hg log` is optimized for showing
changelog data and there are things that `hg display` could display
that aren't changelog centric.

There were concerns about using "show" as the command name.

Some users already have a "show" alias that is similar to `hg export`.

There were also concerns that Git users adapted to 

[PATCH 1 of 2 V2] formatter: reserve _ prefixed keys as internal and don't render

2017-03-22 Thread Gregory Szorc
# 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
 if first:
 first = False
 else:
___
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

2017-03-22 Thread Gregory Szorc
On Mon, Mar 13, 2017 at 7:21 PM, Yuya Nishihara  wrote:

> 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.
>
> > +@command('show', commands.formatteropts, _('[VIEW]'))
> > +def show(ui, repo, view=None, template=None):
> > +"""show various repository information
> > +
> > +A requested view of repository data is displayed.
> > +
> > +If no view is requested, the list of available views is shown.
> > +
> > +.. note::
> > +
> > +   The default output from this command is not covered under
> Mercurial's
> > +   default backwards-compatible mechanism (which puts an emphasis on
> > +   not changing behavior). This means output from this command may
> change
> > +   in any future release. However, the values fed to the formatter
> are
> > +   covered under the default backwards-compatible mechanism.
> > +
> > +   Automated consumers of this command should specify an explicit
> template
> > +   via ``-T/--template`` to guarantee output is stable.
> > +
> > +List of available views:
> > +
> > +"""
> > +views = showview._table
> > +
> > +if not view:
> > +ui.write(_('available views:\n'))
> > +ui.write('\n')
> > +
> > +for name, func in sorted(views.items()):
> > +ui.write(_('%s\n') % func.__doc__)
> > +
> > +ui.write('\n')
> > +raise error.Abort(_('no view requested'),
> > +  hint=_('use `hg show ` to choose a
> view'))
> > +
> > +if view not in views:
> > +raise error.Abort(_('unknown view: %s') % view,
> > +  hint=_('run `hg show` to see available
> views'))
> > +
> > +template = template or 'show'
> > +fmtopic = views[view]._formatter
> > +formatter = ui.formatter(fmtopic, {'template': template})
> > +
> > +return views[view](ui, repo, formatter)
>
> s/formatter/fm/ seems better for consistency. Also, I prefer calling
> fm.end()
> here as it should be paired with the construction.
>
>   with ui.formatter(...) as fm:
>   return views[view](...)
>
> > +@showview('bookmarks', formatter='bookmarks')
>
> s/formatter=/topic=/ or /fmtopic=/ ?
>
> If this 'bookmarks' template can't be compatible with the default template
> used by "hg bookmarks" command, we'll need another topic name.
>
> > +def showbookmarks(ui, repo, fm):
> > +"""bookmarks and their associated changeset"""
> > +marks = repo._bookmarks
> > +if not len(marks):
> > +ui.write_err('(no bookmarks set)\n')
> > +return 0
>
> If this is an error, it should error out. Otherwise, use fm.plain().
>

fm.plain() no-ops when using templateformatter though.

I'm not sure what to do here. We probably want a message printed to the
user without an error exit code. So I'm going to keep this as ui.write() in
V2 and you can suggest a workaround.


>
> > +active = repo._activebookmark
> > +longest = max(len(b) for b in marks)
> > +
> > +for bm, node in sorted(marks.items()):
> > +fm.startitem()
> > +fm.write('bookmark', '%s', bm)
> > +fm.write('node', fm.hexfunc(node), fm.hexfunc(node))
> > +fm.data(ctx=repo[node],
> > +active=bm == active,
> > +longestlen=longest)
>
> As changectx can't be serialized, it shouldn't be passed to e.g.
> jsonformatter.
> fm.context(ctx=repo[node]) can be used. It's unfortunate that 'longestlen'
> appears in JSON output, but I have no better idea other than abusing
> fm.context().
>

I have an idea. I may test the waters in V2.
___
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

2017-03-22 Thread Jun Wu
Excerpts from Jun Wu's message of 2017-03-21 22:42:11 -0700:
> 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.

Sorry. It should be "Currently, 3 is always treated as happened before 2".
There are no cycles in this simple case.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 4 py3 V2] pycompat: custom implementation of urllib.parse.quote()

2017-03-22 Thread Gregory Szorc
On Tue, Mar 14, 2017 at 1:43 AM, Yuya Nishihara  wrote:

> On Mon, 13 Mar 2017 13:08:51 -0700, Gregory Szorc wrote:
> > # HG changeset patch
> > # User Gregory Szorc 
> > # Date 1489432607 25200
> > #  Mon Mar 13 12:16:47 2017 -0700
> > # Node ID ae4c0d8f0ca7218c8b1d259b72660c99b4c085aa
> > # Parent  4dca07be3c215ee7f47ccd7473d78514968f1bb4
> > pycompat: custom implementation of urllib.parse.quote()
> >
> > urllib.parse.quote() accepts either str or bytes and returns str.
> >
> > There exists a urllib.parse.quote_from_bytes() which only accepts
> > bytes. We should probably use that to retain strong typing and
> > avoid surprises.
> >
> > In addition, since nearly all strings in Mercurial are bytes, we
> > probably don't want quote() returning unicode.
> >
> > So, this patch implements a custom quote() that only accepts bytes
> > and returns bytes. The quoted URL should only contain URL safe
> > characters which is a strict subset of ASCII. So
> > `.encode('ascii', 'strict')` should be safe.
> >
> > diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
> > --- a/mercurial/pycompat.py
> > +++ b/mercurial/pycompat.py
> > @@ -269,7 +269,6 @@ if not ispy3:
> >  else:
> >  import urllib.parse
> >  urlreq._registeraliases(urllib.parse, (
> > -"quote",
> >  "splitattr",
> >  "splitpasswd",
> >  "splitport",
> > @@ -313,3 +312,12 @@ else:
> >  "SimpleHTTPRequestHandler",
> >  "CGIHTTPRequestHandler",
> >  ))
> > +
> > +# urllib.parse.quote() accepts both str and bytes, decodes bytes
> > +# (if necessary), and returns str. This is wonky. We provide a
> custom
> > +# implementation that only accepts bytes and emits bytes.
> > +def quote(s, safe=r'/'):
> > +s = urllib.parse.quote_from_bytes(s, safe=safe)
> > +return s.encode('ascii', 'strict')
> > +
> > +urlreq.quote = quote
>
> unquote() is exported as pycompat.urlunquote(). Maybe we should choose one
> way.
>

I thought this change was trivial. But it turned into an 8 part series
which I just patchpombed. Thanks for spotting the redundancy.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel