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

2017-03-24 Thread Yuya Nishihara
On Thu, 23 Mar 2017 11:38:45 -0400, Augie Fackler wrote:
> On Thu, Mar 23, 2017 at 12:16:16AM +0900, Yuya Nishihara wrote:
> > 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.
> 
> My vision for `hg show` was that we document it as having explicitly
> unstable output and unsuitable for scripting. Perhaps in light of
> that, HGPLAIN=1 should cause `hg show` to say `abort: show is only for
> humans, you appear to be a robot` or similar.

Makes some sense, but `hg show` would support -Tjson, which is for scripting.
___
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-24 Thread Jun Wu
Excerpts from Denis Laxalde's message of 2017-03-23 10:14:14 +0100:
> Ryan McElroy a écrit :
> > 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 
> 
> It seems to me that all "show" extensions/aliases can be replaced by the
> proposed extension. Also if we look to the future, it seems to me that

The problem is top-level command names are rare resources. It's really hard
to name things. I think subcommands is a great choice.

> we'd have hard time to explain that this command is not called "show"
> because there used to be extensions/aliases with this name and that got
> replaced by said command.

Another benefit of the "show" approach is it's supposed to be read-only.
It feels cleaner than for example "hg bookmark" which could do either read
or write.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [1 of 4]

2017-03-24 Thread Augie Fackler
On Sat, Mar 25, 2017 at 12:49:05AM +0900, Yuya Nishihara wrote:
> On Fri, 24 Mar 2017 21:00:24 +0530, Pulkit Goyal wrote:
> > This series is a part of fixing things which we already know will lead to
> > exception or wrong result. So instead of waiting for those exceptions to
> > pop up, it fixes them. It fixes all the occurrences in mercurial/ (couple
> > of occurrences are left where using maplist was not required).
>
> Not all map() are needed to be converted to maplist(). If we don't want to
> sort out them, we can simply redirect map to maplist by importer.

Yeah, I'd rather we trip over cases where we used map
not-as-an-iterator and fix them incrementally rather than just
touching them all wholesale.

> ___
> 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 resend] rebase: move state serialization to use unfiltered repo

2017-03-24 Thread Augie Fackler
On Fri, Mar 24, 2017 at 10:08:05AM -0700, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode 
> # Date 1489347215 25200
> #  Sun Mar 12 12:33:35 2017 -0700
> # Node ID ec3731bcacca0a6c65da08e20f7784bdd210161d
> # Parent  718a57e95a897f4ac407ae3733a7d41e87354acb
> rebase: move state serialization to use unfiltered repo

Queued (again), thanks.

>
> Now that rebasestate is serialized as part of the transaction, the repo state 
> it
> sees is the version at the end of the transaction, which may have hidden 
> nodes.
> Therefore, it's possible parts of the rebase commit set are no longer visible 
> by
> the time the transaction is closing, which causes a filtered revision error in
> this code. I don't think state serialization should be blocked from accessing
> commits it knows exist, especially if all it's trying to do is get the hex of
> them, so let's use an unfiltered repo here.
>
> Unfortunately, the only known repro is with the fbamend Facebook extension, so
> I'm not sure how to repro it in core Mercurial for a test.
>
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -169,7 +169,7 @@ class rebaseruntime(object):
>  self._writestatus(f)
>
>  def _writestatus(self, f):
> -repo = self.repo
> +repo = self.repo.unfiltered()
>  f.write(repo[self.originalwd].hex() + '\n')
>  f.write(repo[self.target].hex() + '\n')
>  f.write(repo[self.external].hex() + '\n')
> ___
> 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 7 of 7] largefiles: avoid redundant standin() invocations

2017-03-24 Thread Augie Fackler
On Fri, Mar 24, 2017 at 10:38:41PM +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori 
> # Date 1490362162 -32400
> #  Fri Mar 24 22:29:22 2017 +0900
> # Node ID 6d7aec35c2bd7cf62793bd6135861c9a64a66da1
> # Parent  b0176fef06b79d8e4364bf2befa2522635c4d3ff
> largefiles: avoid redundant standin() invocations

Queued these, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH RFC] configoptions: introduce registrar for config options

2017-03-24 Thread Martin von Zweigbergk via Mercurial-devel
On Sun, Mar 12, 2017 at 12:18 PM, Gregory Szorc  wrote:
> # HG changeset patch
> # User Gregory Szorc 
> # Date 1489346234 25200
> #  Sun Mar 12 12:17:14 2017 -0700
> # Node ID dd26bc2a3056879181851aaa3ff4accbfc42e1ad
> # Parent  62939e0148f170b67ca8c7374f36c413b67fd387
> configoptions: introduce registrar for config options

I like the direction. I missed the discussion at the sprint. Was the
consensus that this is the way to go?

What's the next step? Will you send a non-RFC series adding a few
users as well? I'm also curious to see the "Actually hooking it up to
config loading" step.

>
> Various talks at the sprint have revolved around establishing more
> formalization around config options. Specific problems we'd like
> to solve or are thinking about solving include:
>
> * Experimental config options not documented and are not discoverable
>   to end-users.
> * Config options aren't strongly typed (it depends how they are
>   accessed).
> * Config options for extensions don't appear in `hg help config`.
> * There is no formal mechanism to map a config option to command
>   argument behavior. e.g. have a config option imply a command
>   argument. Instead, logic is done in the command implementation,
>   which results in inconsistent behavior, error messages, weird
>   `hg help ` output.
> * Config option validation is done at the call site and not as part
>   of config loading or command dispatching.
> * Config options are declared by side-effect all over the repo. It
>   might be nicer to have a single "registry" so the full context of
>   all options is easily referenced.
> * No mechanism to "alias" an old config option to a new one. e.g.
>   carrying over "experimental.feature" to its final value.
>
> This patch introduces a very eary proof of concept for improving
> the situation. It adds config options to the "registrar" mechanism,
> which allows their declaration to be formalized and recorded in
> a central location. This is conceptually similar to populating a
> central dict with the data. I chose to use decorators and (for now)
> empty functions for declaring config options. This allows docstrings
> to be used for writing the config help.
>
> In the future, one could imagine actually calling the function
> declaring the config option. It could receive a ui instance and
> an object defining the command being invoked. The function could
> then look for conflicting options, adjust command arguments, etc.
> It could do so in a way that is consistent across commands. e.g.
> a ConfigOptionConflict exception could be raised and the ui or
> dispatcher could consistently format that error condition rather
> than leaving it to individual command functions to raise on their
> own.
>
> It's worth noting that we need all the *core* options defined in
> a central file because of lazy module loading. If a module isn't
> loaded, the config option declarations wouldn't be called!
>
> There are several things missing from this patch and open issues to
> resolve:
>
> * i18n of help text
> * Actually using docstrings in `hg help`
> * Hooking up strong typing or hinted typing
> * Figuring out how to declare config options with sub-options
> * Better solution for declaring config options that have both global
>   options and per-item sub-options (like hostsecurity.ciphers)
> * Actually hooking it up to config loading
> * Mechanism for declaring config options in extensions
>
> diff --git a/mercurial/configoptions.py b/mercurial/configoptions.py
> new file mode 100644
> --- /dev/null
> +++ b/mercurial/configoptions.py
> @@ -0,0 +1,102 @@
> +# configoptions.py -- Declaration of configuration options
> +#
> +# Copyright 2017 Gregory Szorc 
> +#
> +# This software may be used and distributed according to the terms of the
> +# GNU General Public License version 2 or any later version.
> +
> +from . import (
> +registrar,
> +)
> +
> +configoption = registrar.configoption()
> +
> +@configoption('hostsecurity.ciphers')
> +def optionciphers():
> +"""Defines the cryptographic ciphers to use for connections.
> +
> +Value must be a valid OpenSSL Cipher List Format as documented at
> +
> https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
> +
> +This setting is for advanced users only. Setting to incorrect values
> +can significantly lower connection security or decrease performance.
> +You have been warned.
> +
> +This option requires Python 2.7.
> +"""
> +
> +@configoption('hostsecurity.minimumprotocol')
> +def optionminimumprotocol():
> +"""Defines the minimum channel encryption protocol to use.
> +
> +By default, the highest version of TLS supported by both client and
> +server is used.
> +
> +Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
> +
> +When running on an old Python version, only ``tls1.0`` is allowed since
> +old versions of Python only 

mercurial@31607: 5 new changesets

2017-03-24 Thread Mercurial Commits
5 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/fbe8502c4480
changeset:   31603:fbe8502c4480
user:Augie Fackler 
date:Thu Mar 23 10:33:20 2017 -0400
summary: revsetlang: portably bytestring-ify another pair of int() calls

https://www.mercurial-scm.org/repo/hg/rev/7eac6fcf2ffa
changeset:   31604:7eac6fcf2ffa
user:Augie Fackler 
date:Sun Mar 19 01:14:19 2017 -0400
summary: revsetlang: move quoting function to not be a closure

https://www.mercurial-scm.org/repo/hg/rev/0b94c19b641c
changeset:   31605:0b94c19b641c
user:Augie Fackler 
date:Thu Mar 23 10:41:34 2017 -0400
summary: revsetlang: add docstring with some tests to _quote

https://www.mercurial-scm.org/repo/hg/rev/0b3eb280564b
changeset:   31606:0b3eb280564b
user:Augie Fackler 
date:Thu Mar 23 10:46:50 2017 -0400
summary: revsetlang: perform quoting using ui.escapestr instead of repr()

https://www.mercurial-scm.org/repo/hg/rev/aea8ec3f7dd1
changeset:   31607:aea8ec3f7dd1
bookmark:@
tag: tip
user:Augie Fackler 
date:Sun Mar 19 01:47:56 2017 -0400
summary: py3: prove `hg {add,addremove,commit} all work

-- 
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 1 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [1 of 4]

2017-03-24 Thread Yuya Nishihara
On Fri, 24 Mar 2017 21:00:24 +0530, Pulkit Goyal wrote:
> This series is a part of fixing things which we already know will lead to
> exception or wrong result. So instead of waiting for those exceptions to
> pop up, it fixes them. It fixes all the occurrences in mercurial/ (couple
> of occurrences are left where using maplist was not required).

Not all map() are needed to be converted to maplist(). If we don't want to
sort out them, we can simply redirect map to maplist by importer.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6 py3 v2] revsetlang: perform quoting using ui.escapestr instead of repr()

2017-03-24 Thread Yuya Nishihara
On Fri, 24 Mar 2017 11:02:28 -0400, Augie Fackler wrote:
> On Fri, Mar 24, 2017 at 10:59 AM, Yuya Nishihara  wrote:
> > On Thu, 23 Mar 2017 11:11:38 -0400, Augie Fackler wrote:
> >> # HG changeset patch
> >> # User Augie Fackler 
> >> # Date 1490280410 14400
> >> #  Thu Mar 23 10:46:50 2017 -0400
> >> # Node ID 2190115dab97a551cd5aac44a8a55e2df9fd6307
> >> # Parent  6158a45eb9f22ee651f2677b420665788fcc72e2
> >> revsetlang: perform quoting using ui.escapestr instead of repr()
> >
> >> @@ -581,11 +582,11 @@ def _quote(s):
> >>  >>> _quote("asdf'\"")
> >>  '\'asdf\\\'"\''
> >>  >>> _quote('asdf\'')
> >> -'"asdf\'"'
> >> +"'asdf\\''"
> >>  >>> _quote(1)
> >>  "'1'"
> >>  """
> >> -return repr(str(s))
> >> +return "'%s'" % util.escapestr('%s' % s)
> >   
> >
> > Ah, found nit. I don't know if _quote(int) is necessary, but b'%s' can't be
> > used to convert int to byte string on Python 3. pycompat.bytestr() should
> > do a job.
> 
> Should I send a followup?

Yes, please. I've already pushed this with no inflight fix.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [1 of 4]

2017-03-24 Thread Pulkit Goyal
This series is a part of fixing things which we already know will lead to
exception or wrong result. So instead of waiting for those exceptions to
pop up, it fixes them. It fixes all the occurrences in mercurial/ (couple
of occurrences are left where using maplist was not required).

On Fri, Mar 24, 2017 at 8:48 PM, Pulkit Goyal <7895pul...@gmail.com> wrote:

> # HG changeset patch
> # User Pulkit Goyal <7895pul...@gmail.com>
> # Date 1490367921 -19800
> #  Fri Mar 24 20:35:21 2017 +0530
> # Node ID 35e6f3d8dbb1242c6cac1c64fd799db543e30444
> # Parent  e8bd005c0af791a87903de339482692db1137ff0
> maplist: replace instances of map() with pycompat.maplist() [1 of 4]
>
> This series replaces the instances of the inbuilt map() function with
> pycompat.maplist() as map() returns a map object instead of list on Python
> 3.
>
> diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/byterange.py
> --- a/mercurial/byterange.pyThu Mar 23 12:03:19 2017 -0700
> +++ b/mercurial/byterange.pyFri Mar 24 20:35:21 2017 +0530
> @@ -28,6 +28,7 @@
>  import stat
>
>  from . import (
> +pycompat,
>  util,
>  )
>
> @@ -278,7 +279,7 @@
>  raise urlerr.urlerror(msg)
>  path, attrs = splitattr(req.get_selector())
>  dirs = path.split('/')
> -dirs = map(unquote, dirs)
> +dirs = pycompat.maplist(unquote, dirs)
>  dirs, file = dirs[:-1], dirs[-1]
>  if dirs and not dirs[0]:
>  dirs = dirs[1:]
> diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/chgserver.py
> --- a/mercurial/chgserver.pyThu Mar 23 12:03:19 2017 -0700
> +++ b/mercurial/chgserver.pyFri Mar 24 20:35:21 2017 +0530
> @@ -151,7 +151,7 @@
>  except OSError:
>  # could be ENOENT, EPERM etc. not fatal in any case
>  pass
> -return _hashlist(map(trystat, paths))[:12]
> +return _hashlist(pycompat.maplist(trystat, paths))[:12]
>
>  class hashstate(object):
>  """a structure storing confighash, mtimehash, paths used for
> mtimehash"""
> diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py  Thu Mar 23 12:03:19 2017 -0700
> +++ b/mercurial/cmdutil.py  Fri Mar 24 20:35:21 2017 +0530
> @@ -1573,12 +1573,13 @@
>  fm.write('precnode', '%s ', hex(marker.precnode()))
>  succs = marker.succnodes()
>  fm.condwrite(succs, 'succnodes', '%s ',
> - fm.formatlist(map(hex, succs), name='node'))
> + fm.formatlist(pycompat.maplist(hex, succs),
> name='node'))
>  fm.write('flag', '%X ', marker.flags())
>  parents = marker.parentnodes()
>  if parents is not None:
>  fm.write('parentnodes', '{%s} ',
> - fm.formatlist(map(hex, parents), name='node', sep=', '))
> + fm.formatlist(pycompat.maplist(hex, parents),
> + name='node', sep=', '))
>  fm.write('date', '(%s) ', fm.formatdate(marker.date()))
>  meta = marker.metadata().copy()
>  meta.pop('date', None)
> diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/commands.py
> --- a/mercurial/commands.py Thu Mar 23 12:03:19 2017 -0700
> +++ b/mercurial/commands.py Fri Mar 24 20:35:21 2017 +0530
> @@ -1349,7 +1349,7 @@
>  raise error.Abort(_("--base is incompatible with specifying "
> "a destination"))
>  common = [repo.lookup(rev) for rev in base]
> -heads = revs and map(repo.lookup, revs) or None
> +heads = revs and pycompat.maplist(repo.lookup, revs) or None
>  outgoing = discovery.outgoing(repo, common, heads)
>  cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
>  bundlecaps=bundlecaps,
> @@ -1360,7 +1360,7 @@
>  dest, branches = hg.parseurl(dest, opts.get('branch'))
>  other = hg.peer(repo, opts, dest)
>  revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
> -heads = revs and map(repo.lookup, revs) or revs
> +heads = revs and pycompat.maplist(repo.lookup, revs) or revs
>  outgoing = discovery.findcommonoutgoing(repo, other,
>  onlyheads=heads,
>  force=opts.get('force'),
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [2 of 4]

2017-03-24 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1490368062 -19800
#  Fri Mar 24 20:37:42 2017 +0530
# Node ID 1b471d88cab47d897afd5aa5ddda3031bd70a300
# Parent  35e6f3d8dbb1242c6cac1c64fd799db543e30444
maplist: replace instances of map() with pycompat.maplist() [2 of 4]

diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/crecord.py
--- a/mercurial/crecord.py  Fri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/crecord.py  Fri Mar 24 20:37:42 2017 +0530
@@ -20,6 +20,7 @@
 encoding,
 error,
 patch as patchmod,
+pycompat,
 scmutil,
 util,
 )
@@ -494,7 +495,8 @@
 chunkselector = curseschunkselector(headerlist, ui, operation)
 if testfn and os.path.exists(testfn):
 testf = open(testfn)
-testcommands = map(lambda x: x.rstrip('\n'), testf.readlines())
+testcommands = pycompat.maplist(lambda x: x.rstrip('\n'),
+testf.readlines())
 testf.close()
 while True:
 if chunkselector.handlekeypressed(testcommands.pop(0), test=True):
diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/dagutil.py
--- a/mercurial/dagutil.py  Fri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/dagutil.py  Fri Mar 24 20:37:42 2017 +0530
@@ -10,6 +10,7 @@
 
 from .i18n import _
 from .node import nullrev
+from . import pycompat
 
 class basedag(object):
 '''generic interface for DAGs
@@ -144,11 +145,11 @@
 def _internalizeall(self, ids, filterunknown):
 rl = self._revlog
 if filterunknown:
-return [r for r in map(rl.nodemap.get, ids)
+return [r for r in pycompat.maplist(rl.nodemap.get, ids)
 if (r is not None
 and r != nullrev
 and r not in rl.filteredrevs)]
-return map(self._internalize, ids)
+return pycompat.maplist(self._internalize, ids)
 
 
 class revlogdag(revlogbaseddag):
diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/dispatch.py
--- a/mercurial/dispatch.py Fri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/dispatch.py Fri Mar 24 20:37:42 2017 +0530
@@ -280,7 +280,7 @@
 def aliasargs(fn, givenargs):
 args = getattr(fn, 'args', [])
 if args:
-cmd = ' '.join(map(util.shellquote, args))
+cmd = ' '.join(pycompat.maplist(util.shellquote, args))
 
 nums = []
 def replacer(m):
@@ -402,7 +402,7 @@
 
 @property
 def args(self):
-args = map(util.expandpath, self.givenargs)
+args = pycompat.maplist(util.expandpath, self.givenargs)
 return aliasargs(self.fn, args)
 
 def __getattr__(self, name):
@@ -815,7 +815,7 @@
 if not func.optionalrepo:
 if func.inferrepo and args and not path:
 # try to infer -R from command args
-repos = map(cmdutil.findrepo, args)
+repos = pycompat.maplist(cmdutil.findrepo, args)
 guess = repos[0]
 if guess and repos.count(guess) == len(repos):
 req.args = ['--repository', guess] + fullargs
diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/revlog.py
--- a/mercurial/revlog.py   Fri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/revlog.py   Fri Mar 24 20:37:42 2017 +0530
@@ -963,7 +963,7 @@
 ancs = ancestor.ancestors(self.parentrevs, a, b)
 if ancs:
 # choose a consistent winner when there's a tie
-return min(map(self.node, ancs))
+return min(pycompat.maplist(self.node, ancs))
 return nullid
 
 def _match(self, id):
diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/revsetlang.py
--- a/mercurial/revsetlang.py   Fri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/revsetlang.py   Fri Mar 24 20:37:42 2017 +0530
@@ -52,7 +52,7 @@
 _syminitletters = set(pycompat.iterbytestr(
 string.ascii_letters.encode('ascii') +
 string.digits.encode('ascii') +
-'._@')) | set(map(pycompat.bytechr, xrange(128, 256)))
+'._@')) | set(pycompat.maplist(pycompat.bytechr, xrange(128, 256)))
 
 # default set of valid characters for non-initial letters of symbols
 _symletters = _syminitletters | set(pycompat.iterbytestr('-/'))
@@ -674,7 +674,7 @@
 
 def depth(tree):
 if isinstance(tree, tuple):
-return max(map(depth, tree)) + 1
+return max(pycompat.maplist(depth, tree)) + 1
 else:
 return 0
 
diff -r 35e6f3d8dbb1 -r 1b471d88cab4 mercurial/treediscovery.py
--- a/mercurial/treediscovery.pyFri Mar 24 20:35:21 2017 +0530
+++ b/mercurial/treediscovery.pyFri Mar 24 20:37:42 2017 +0530
@@ -16,6 +16,7 @@
 )
 from . import (
 error,
+pycompat,
 )
 
 def findcommonincoming(repo, remote, heads=None, force=False):
@@ -105,7 +106,7 @@
 reqcnt += 1
 repo.ui.progress(_('searching'), reqcnt, unit=_('queries'))
 repo.ui.debug("request %d: %s\n" %
-   

[PATCH 3 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [3 of 4]

2017-03-24 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1490368126 -19800
#  Fri Mar 24 20:38:46 2017 +0530
# Node ID 86026839d8fd76528af12a7fd9a876488d257483
# Parent  1b471d88cab47d897afd5aa5ddda3031bd70a300
maplist: replace instances of map() with pycompat.maplist() [3 of 4]

diff -r 1b471d88cab4 -r 86026839d8fd mercurial/exchange.py
--- a/mercurial/exchange.py Fri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/exchange.py Fri Mar 24 20:38:46 2017 +0530
@@ -26,6 +26,7 @@
 obsolete,
 phases,
 pushkey,
+pycompat,
 scmutil,
 sslutil,
 streamclone,
@@ -609,7 +610,7 @@
 ui.debug("checking for updated bookmarks\n")
 ancestors = ()
 if pushop.revs:
-revnums = map(repo.changelog.rev, pushop.revs)
+revnums = pycompat.maplist(repo.changelog.rev, pushop.revs)
 ancestors = repo.changelog.ancestors(revnums, inclusive=True)
 remotebookmark = remote.listkeys('bookmarks')
 
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/hbisect.py
--- a/mercurial/hbisect.py  Fri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/hbisect.py  Fri Mar 24 20:38:46 2017 +0530
@@ -19,6 +19,7 @@
 )
 from . import (
 error,
+pycompat,
 )
 
 def bisect(changelog, state):
@@ -202,7 +203,7 @@
 """
 state = load_state(repo)
 if status in ('good', 'bad', 'skip', 'current'):
-return map(repo.changelog.rev, state[status])
+return pycompat.maplist(repo.changelog.rev, state[status])
 else:
 # In the following sets, we do *not* call 'bisect()' with more
 # than one level of recursion, because that can be very, very
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/store.py
--- a/mercurial/store.pyFri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/store.pyFri Mar 24 20:38:46 2017 +0530
@@ -100,7 +100,7 @@
 '''
 e = '_'
 xchr = pycompat.bytechr
-asciistr = list(map(xchr, range(127)))
+asciistr = pycompat.maplist(xchr, range(127))
 capitals = list(range(ord("A"), ord("Z") + 1))
 
 cmap = dict((x, x) for x in asciistr)
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/streamclone.py
--- a/mercurial/streamclone.py  Fri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/streamclone.py  Fri Mar 24 20:38:46 2017 +0530
@@ -13,6 +13,7 @@
 from . import (
 branchmap,
 error,
+pycompat,
 store,
 util,
 )
@@ -131,7 +132,7 @@
 
 l = fp.readline()
 try:
-filecount, bytecount = map(int, l.split(' ', 1))
+filecount, bytecount = pycompat.maplist(int, l.split(' ', 1))
 except (ValueError, TypeError):
 raise error.ResponseError(
 _('unexpected response from remote server:'), l)
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/util.py
--- a/mercurial/util.py Fri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/util.py Fri Mar 24 20:38:46 2017 +0530
@@ -1936,7 +1936,7 @@
 datetime.timedelta(days=1)).strftime('%b %d')
 
 try:
-when, offset = map(int, date.split(' '))
+when, offset = pycompat.maplist(int, date.split(' '))
 except ValueError:
 # fill out defaults
 now = makedate()
@@ -3384,7 +3384,7 @@
 pos = pos2
 parts.append(z.flush())
 
-if sum(map(len, parts)) < insize:
+if sum(pycompat.maplist(len, parts)) < insize:
 return ''.join(parts)
 return None
 
@@ -3569,7 +3569,7 @@
 pos = pos2
 chunks.append(z.flush())
 
-if sum(map(len, chunks)) < insize:
+if sum(pycompat.maplist(len, chunks)) < insize:
 return ''.join(chunks)
 return None
 
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/verify.py
--- a/mercurial/verify.py   Fri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/verify.py   Fri Mar 24 20:38:46 2017 +0530
@@ -17,6 +17,7 @@
 
 from . import (
 error,
+pycompat,
 revlog,
 scmutil,
 util,
@@ -103,7 +104,8 @@
 if self.lrugetctx(l)[f].filenode() == node]
 except Exception:
 pass
-self.warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
+self.warn(_(" (expected %s)") % " ".join(pycompat.maplist(str,
+linkrevs)))
 lr = None # can't be trusted
 
 try:
diff -r 1b471d88cab4 -r 86026839d8fd mercurial/wireproto.py
--- a/mercurial/wireproto.pyFri Mar 24 20:37:42 2017 +0530
+++ b/mercurial/wireproto.pyFri Mar 24 20:38:46 2017 +0530
@@ -157,12 +157,12 @@
 
 def decodelist(l, sep=' '):
 if l:
-return map(bin, l.split(sep))
+return pycompat.maplist(bin, l.split(sep))
 return []
 
 def encodelist(l, sep=' '):
 try:
-return sep.join(map(hex, l))
+return sep.join(pycompat.maplist(hex, l))
 except TypeError:
 raise
 

[PATCH 1 of 4 py3] maplist: replace instances of map() with pycompat.maplist() [1 of 4]

2017-03-24 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1490367921 -19800
#  Fri Mar 24 20:35:21 2017 +0530
# Node ID 35e6f3d8dbb1242c6cac1c64fd799db543e30444
# Parent  e8bd005c0af791a87903de339482692db1137ff0
maplist: replace instances of map() with pycompat.maplist() [1 of 4]

This series replaces the instances of the inbuilt map() function with
pycompat.maplist() as map() returns a map object instead of list on Python 3.

diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/byterange.py
--- a/mercurial/byterange.pyThu Mar 23 12:03:19 2017 -0700
+++ b/mercurial/byterange.pyFri Mar 24 20:35:21 2017 +0530
@@ -28,6 +28,7 @@
 import stat
 
 from . import (
+pycompat,
 util,
 )
 
@@ -278,7 +279,7 @@
 raise urlerr.urlerror(msg)
 path, attrs = splitattr(req.get_selector())
 dirs = path.split('/')
-dirs = map(unquote, dirs)
+dirs = pycompat.maplist(unquote, dirs)
 dirs, file = dirs[:-1], dirs[-1]
 if dirs and not dirs[0]:
 dirs = dirs[1:]
diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/chgserver.py
--- a/mercurial/chgserver.pyThu Mar 23 12:03:19 2017 -0700
+++ b/mercurial/chgserver.pyFri Mar 24 20:35:21 2017 +0530
@@ -151,7 +151,7 @@
 except OSError:
 # could be ENOENT, EPERM etc. not fatal in any case
 pass
-return _hashlist(map(trystat, paths))[:12]
+return _hashlist(pycompat.maplist(trystat, paths))[:12]
 
 class hashstate(object):
 """a structure storing confighash, mtimehash, paths used for mtimehash"""
diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/cmdutil.py
--- a/mercurial/cmdutil.py  Thu Mar 23 12:03:19 2017 -0700
+++ b/mercurial/cmdutil.py  Fri Mar 24 20:35:21 2017 +0530
@@ -1573,12 +1573,13 @@
 fm.write('precnode', '%s ', hex(marker.precnode()))
 succs = marker.succnodes()
 fm.condwrite(succs, 'succnodes', '%s ',
- fm.formatlist(map(hex, succs), name='node'))
+ fm.formatlist(pycompat.maplist(hex, succs), name='node'))
 fm.write('flag', '%X ', marker.flags())
 parents = marker.parentnodes()
 if parents is not None:
 fm.write('parentnodes', '{%s} ',
- fm.formatlist(map(hex, parents), name='node', sep=', '))
+ fm.formatlist(pycompat.maplist(hex, parents),
+ name='node', sep=', '))
 fm.write('date', '(%s) ', fm.formatdate(marker.date()))
 meta = marker.metadata().copy()
 meta.pop('date', None)
diff -r e8bd005c0af7 -r 35e6f3d8dbb1 mercurial/commands.py
--- a/mercurial/commands.py Thu Mar 23 12:03:19 2017 -0700
+++ b/mercurial/commands.py Fri Mar 24 20:35:21 2017 +0530
@@ -1349,7 +1349,7 @@
 raise error.Abort(_("--base is incompatible with specifying "
"a destination"))
 common = [repo.lookup(rev) for rev in base]
-heads = revs and map(repo.lookup, revs) or None
+heads = revs and pycompat.maplist(repo.lookup, revs) or None
 outgoing = discovery.outgoing(repo, common, heads)
 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
 bundlecaps=bundlecaps,
@@ -1360,7 +1360,7 @@
 dest, branches = hg.parseurl(dest, opts.get('branch'))
 other = hg.peer(repo, opts, dest)
 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
-heads = revs and map(repo.lookup, revs) or revs
+heads = revs and pycompat.maplist(repo.lookup, revs) or revs
 outgoing = discovery.findcommonoutgoing(repo, other,
 onlyheads=heads,
 force=opts.get('force'),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6 py3 v2] revsetlang: perform quoting using ui.escapestr instead of repr()

2017-03-24 Thread Augie Fackler
On Fri, Mar 24, 2017 at 10:59 AM, Yuya Nishihara  wrote:
> On Thu, 23 Mar 2017 11:11:38 -0400, Augie Fackler wrote:
>> # HG changeset patch
>> # User Augie Fackler 
>> # Date 1490280410 14400
>> #  Thu Mar 23 10:46:50 2017 -0400
>> # Node ID 2190115dab97a551cd5aac44a8a55e2df9fd6307
>> # Parent  6158a45eb9f22ee651f2677b420665788fcc72e2
>> revsetlang: perform quoting using ui.escapestr instead of repr()
>
>> @@ -581,11 +582,11 @@ def _quote(s):
>>  >>> _quote("asdf'\"")
>>  '\'asdf\\\'"\''
>>  >>> _quote('asdf\'')
>> -'"asdf\'"'
>> +"'asdf\\''"
>>  >>> _quote(1)
>>  "'1'"
>>  """
>> -return repr(str(s))
>> +return "'%s'" % util.escapestr('%s' % s)
>   
>
> Ah, found nit. I don't know if _quote(int) is necessary, but b'%s' can't be
> used to convert int to byte string on Python 3. pycompat.bytestr() should
> do a job.

Should I send a followup?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 6 py3 v2] revsetlang: perform quoting using ui.escapestr instead of repr()

2017-03-24 Thread Yuya Nishihara
On Thu, 23 Mar 2017 11:11:38 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1490280410 14400
> #  Thu Mar 23 10:46:50 2017 -0400
> # Node ID 2190115dab97a551cd5aac44a8a55e2df9fd6307
> # Parent  6158a45eb9f22ee651f2677b420665788fcc72e2
> revsetlang: perform quoting using ui.escapestr instead of repr()

> @@ -581,11 +582,11 @@ def _quote(s):
>  >>> _quote("asdf'\"")
>  '\'asdf\\\'"\''
>  >>> _quote('asdf\'')
> -'"asdf\'"'
> +"'asdf\\''"
>  >>> _quote(1)
>  "'1'"
>  """
> -return repr(str(s))
> +return "'%s'" % util.escapestr('%s' % s)
  

Ah, found nit. I don't know if _quote(int) is necessary, but b'%s' can't be
used to convert int to byte string on Python 3. pycompat.bytestr() should
do a job.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 3] osutil: report fstype for BSD and OSX

2017-03-24 Thread Yuya Nishihara
On Thu, 23 Mar 2017 22:32:53 -0700, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu 
> # Date 1490332382 25200
> #  Thu Mar 23 22:13:02 2017 -0700
> # Node ID 825bb185512c66a43ae6927933196b8356c99798
> # Parent  597a29c947fe2b9f9ac0a6a03cf710ab9f69757c
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
> 825bb185512c
> osutil: report fstype for BSD and OSX
> 
> diff --git a/mercurial/osutil.c b/mercurial/osutil.c
> --- a/mercurial/osutil.c
> +++ b/mercurial/osutil.c
> @@ -28,8 +28,6 @@
>  #include 
>  #endif
> -#ifdef HAVE_SYS_MOUNT_H
> +#ifdef HAVE_BSD_STATFS
>  #include 
> -#endif
> -#ifdef HAVE_SYS_PARAM_H
>  #include 
>  #endif
> @@ -802,5 +800,10 @@ static PyObject *setprocname(PyObject *s
>  /* given a directory path, return filesystem type (best-effort), or None */
>  const char *getfstype(const char *path) {
> +#ifdef HAVE_BSD_STATFS
> + /* need to return a string field */
> + static struct statfs buf;
> +#else
>   struct statfs buf;
> +#endif

Nit: I prefer moving the stack allocation of struct statfs to caller. We might
blindly port getfstype() to cffi module and get in trouble due to the static
storage.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH hglib RESEND] hglib: fix hg clone --uncompressed option typo (issue5458)

2017-03-24 Thread Long Vu
# HG changeset patch
# User Long Vu 
# Date 1490322881 14400
#  Thu Mar 23 22:34:41 2017 -0400
# Node ID 820d7c1e470aaa11dad8f33e9161179a8115cef6
# Parent  ae38fb772613604dac7fcf63705e8a2a17ff50cd
hglib: fix hg clone --uncompressed option typo (issue5458)

Was getting error.CommandError
"hg clone: option --uncompresses not recognized".

diff --git a/hglib/__init__.py b/hglib/__init__.py
--- a/hglib/__init__.py
+++ b/hglib/__init__.py
@@ -28,7 +28,7 @@
   insecure=False, encoding=None, configs=None):
 args = util.cmdbuilder('clone', source, dest, noupdate=noupdate,
updaterev=updaterev, rev=rev, branch=branch,
-   pull=pull, uncompresses=uncompressed,
+   pull=pull, uncompressed=uncompressed,
e=ssh, remotecmd=remotecmd, insecure=insecure)
 
 args.insert(0, HGPATH)
diff --git a/tests/test-clone.py b/tests/test-clone.py
--- a/tests/test-clone.py
+++ b/tests/test-clone.py
@@ -11,3 +11,6 @@
 self.assertRaises(ValueError, cloned.log)
 cloned.open()
 self.assertEquals(self.client.log(), cloned.log())
+
+def test_clone_uncompressed(self):
+hglib.clone(b('.'), b('cloned'), uncompressed=True)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH hglib] hglib: fix hg clone --uncompressed option typo

2017-03-24 Thread Long Vu



On 2017-03-24 05:45 AM, Pulkit Goyal wrote:



On Fri, Mar 24, 2017 at 8:48 AM, Long Vu > wrote:

# HG changeset patch
# User Long Vu >
# Date 1490322881 14400
#  Thu Mar 23 22:34:41 2017 -0400
# Node ID a6ae14f83d7a5e822b214ab0216e9685395b778f
# Parent  ae38fb772613604dac7fcf63705e8a2a17ff50cd
hglib: fix hg clone --uncompressed option typo


This is issue5458. The person pushing this change
​,​
add
​it​
to commit message so that our Bugzilla bot can mark this as fixed.
​(I am not sure though how the bugzilla bot works.)​



Done, resent.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH V3] pager: fix the invocation of `more` on Windows

2017-03-24 Thread Yuya Nishihara
On Thu, 23 Mar 2017 21:57:50 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1489983573 14400
> #  Mon Mar 20 00:19:33 2017 -0400
> # Node ID d0c2db2d9f13dca534c598de050eb1919ef79059
> # Parent  df82f375fa005b9c71b463182e6b54aa47fa5999
> pager: fix the invocation of `more` on Windows

> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -844,6 +844,15 @@
>  if not pagercmd:
>  return
>  
> +if pycompat.osname == 'nt':
> +# `more` cannot be invoked with shell=False, but `more.com` can.
> +# Hide this implementation detail from the user, so we can also 
> get
> +# sane bad PAGER behavior.  If args are also given, the space in 
> the
> +# command line forces shell=True, so that case doesn't need to be
> +# handled here.
> +if pagercmd == 'more':
> +pagercmd = 'more.com'

Given MSYS nor MSYS2 doesn't provide more.exe by default, this seems fine.
Can we document this hack in help just in case someone installed more.exe?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


mercurial@31591: 4 new changesets

2017-03-24 Thread Mercurial Commits
4 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/37a0ad669051
changeset:   31588:37a0ad669051
parent:  31586:df82f375fa00
user:Martin von Zweigbergk 
date:Tue Mar 21 21:26:52 2017 -0700
summary: plain: ignore [commands] config

https://www.mercurial-scm.org/repo/hg/rev/7e3b145f8247
changeset:   31589:7e3b145f8247
user:Martin von Zweigbergk 
date:Tue Mar 21 17:50:44 2017 -0700
summary: status: support commands.status.relative config

https://www.mercurial-scm.org/repo/hg/rev/78ac8acfc4bd
changeset:   31590:78ac8acfc4bd
user:David Soria Parra 
date:Wed Mar 22 14:12:58 2017 -0500
summary: convert: fix the handling of empty changlist descriptions in P4

https://www.mercurial-scm.org/repo/hg/rev/2c02bb7fd7fc
changeset:   31591:2c02bb7fd7fc
bookmark:@
tag: tip
user:Martin von Zweigbergk 
date:Wed Mar 22 16:36:53 2017 -0700
summary: help: format ``commands`` heading correctly

-- 
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 2 of 6 py3 v2] revsetlang: portably bytestring-ify another pair of int() calls

2017-03-24 Thread Yuya Nishihara
On Thu, 23 Mar 2017 11:11:35 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler 
> # Date 1490279600 14400
> #  Thu Mar 23 10:33:20 2017 -0400
> # Node ID 28e859b6032c8c5c1b3186a5356f0e344575eb6b
> # Parent  1f45b1946c0cb34f84f93f8a4931ab5ea5114b1a
> revsetlang: portably bytestring-ify another pair of int() calls

Queued 2-6, thanks.

> @@ -629,7 +629,7 @@ def formatspec(expr, *args):
>  elif l == 1:
>  return argtype(t, s[0])
>  elif t == 'd':
> -return "_intlist('%s')" % "\0".join(str(int(a)) for a in s)
> +return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s)
>  elif t == 's':
>  return "_list('%s')" % "\0".join(s)
>  elif t == 'n':

This hunk was queued as 553ad16b274f, so dropped.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 7] largefiles: replace hashrepofile by hashfile (API)

2017-03-24 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1490362162 -32400
#  Fri Mar 24 22:29:22 2017 +0900
# Node ID b0176fef06b79d8e4364bf2befa2522635c4d3ff
# Parent  d8e91cf37cc9409c79c5d97969c1e63d0dbe8908
largefiles: replace hashrepofile by hashfile (API)

There is only one user for the former, and repo.wjoin()-ed value is
alread known by that user.

diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -370,9 +370,6 @@ def copyandhash(instream, outfile):
 outfile.write(data)
 return hasher.hexdigest()
 
-def hashrepofile(repo, file):
-return hashfile(repo.wjoin(file))
-
 def hashfile(file):
 if not os.path.exists(file):
 return ''
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1400,7 +1400,7 @@ def mergeupdate(orig, repo, node, branch
 lfileabs = repo.wvfs.join(lfile)
 if not repo.wvfs.exists(lfileabs):
 continue
-lfhash = lfutil.hashrepofile(repo, lfile)
+lfhash = lfutil.hashfile(lfileabs)
 standin = lfutil.standin(lfile)
 lfutil.writestandin(repo, standin, lfhash,
 lfutil.getexecutable(lfileabs))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] largefiles: avoid redundant standin() invocations

2017-03-24 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1490362162 -32400
#  Fri Mar 24 22:29:22 2017 +0900
# Node ID 6d7aec35c2bd7cf62793bd6135861c9a64a66da1
# Parent  b0176fef06b79d8e4364bf2befa2522635c4d3ff
largefiles: avoid redundant standin() invocations

There are some code paths, which apply standin() on same value
multilpe times instead of using already standin()-ed value.

"fstandin" is common name for "path to standin file" in lfutil.py, to
avoid shadowing "standin()".

diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py
+++ b/hgext/largefiles/lfcommands.py
@@ -220,7 +220,8 @@ def _lfconvert_addchangeset(rsrc, rdst, 
 normalfiles.add(f)
 
 if f in lfiles:
-dstfiles.append(lfutil.standin(f))
+fstandin = lfutil.standin(f)
+dstfiles.append(fstandin)
 # largefile in manifest if it has not been removed/renamed
 if f in ctx.manifest():
 fctx = ctx.filectx(f)
@@ -236,7 +237,7 @@ def _lfconvert_addchangeset(rsrc, rdst, 
 if f not in lfiletohash or lfiletohash[f] != hash:
 rdst.wwrite(f, ctx[f].data(), ctx[f].flags())
 executable = 'x' in ctx[f].flags()
-lfutil.writestandin(rdst, lfutil.standin(f), hash,
+lfutil.writestandin(rdst, fstandin, hash,
 executable)
 lfiletohash[f] = hash
 else:
diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -557,13 +557,13 @@ def updatestandinsbymatch(repo, match):
 # removed/renamed)
 for lfile in lfiles:
 if lfile in modifiedfiles:
-if repo.wvfs.exists(standin(lfile)):
+fstandin = standin(lfile)
+if repo.wvfs.exists(fstandin):
 # this handles the case where a rebase is being
 # performed and the working copy is not updated
 # yet.
 if repo.wvfs.exists(lfile):
-updatestandin(repo,
-standin(lfile))
+updatestandin(repo, fstandin)
 
 return match
 
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -739,8 +739,9 @@ def overriderevert(orig, ui, repo, ctx, 
 for lfile in s.modified:
 lfutil.updatestandin(repo, lfutil.standin(lfile))
 for lfile in s.deleted:
-if (repo.wvfs.exists(lfutil.standin(lfile))):
-repo.wvfs.unlink(lfutil.standin(lfile))
+fstandin = lfutil.standin(lfile)
+if (repo.wvfs.exists(fstandin)):
+repo.wvfs.unlink(fstandin)
 
 oldstandins = lfutil.getstandinsstate(repo)
 
@@ -1080,8 +1081,8 @@ def cmdutilforget(orig, ui, repo, match,
 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
 
 for f in forget:
-if lfutil.standin(f) not in repo.dirstate and not \
-repo.wvfs.isdir(lfutil.standin(f)):
+fstandin = lfutil.standin(f)
+if fstandin not in repo.dirstate and not repo.wvfs.isdir(fstandin):
 ui.warn(_('not removing %s: file is already untracked\n')
 % m.rel(f))
 bad.append(f)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 7] misc: update descriptions about removed file for filectxfn

2017-03-24 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1490361203 -32400
#  Fri Mar 24 22:13:23 2017 +0900
# Node ID 1f1ed3058fa829550b52110f35c65b4f79c92d10
# Parent  e8bd005c0af791a87903de339482692db1137ff0
misc: update descriptions about removed file for filectxfn

Since 650b5b6e75ed, filectxfn for memctx should return None for
removed file instead of raising IOError.

diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py
+++ b/hgext/largefiles/lfcommands.py
@@ -246,7 +246,7 @@ def _lfconvert_addchangeset(rsrc, rdst, 
 def getfilectx(repo, memctx, f):
 if lfutil.isstandin(f):
 # if the file isn't in the manifest then it was removed
-# or renamed, raise IOError to indicate this
+# or renamed, return None to indicate this
 srcfname = lfutil.splitstandin(f)
 try:
 fctx = ctx.filectx(srcfname)
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1864,8 +1864,8 @@ class memctx(committablectx):
 commit function for every file in 'files', but calls order is
 undefined. If the file is available in the revision being
 committed (updated or added), filectxfn returns a memfilectx
-object. If the file was removed, filectxfn raises an
-IOError. Moved files are represented by marking the source file
+object. If the file was removed, filectxfn return None for recent
+Mercurial. Moved files are represented by marking the source file
 removed and the new file added with copy information (see
 memfilectx).
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 7] largefiles: call readstandin() with changectx itself instead of rev or node

2017-03-24 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1490361994 -32400
#  Fri Mar 24 22:26:34 2017 +0900
# Node ID d8e91cf37cc9409c79c5d97969c1e63d0dbe8908
# Parent  ae4c9a5c687a7f7a8460dac36cd3f5f8404ef06b
largefiles: call readstandin() with changectx itself instead of rev or node

readstandin() takes "node" argument to get changectx by "repo[node]".

There are some readstandin() invocations, which use ctx.node(),
ctx.rev(), or '.' as "node" argument above, even though corresponded
changectx object is already looked up on caller side.

This patch calls readstandin() with already known changectx itself, to
avoid meaningless re-construction of changectx (indirect case via
copytostore() is also included).

BTW, copytostore() uses "rev" argument only for readstandin()
invocation. Therefore, this patch also renames it to "revorctx" to
indicate that it can take not only revision ID or so but also
changectx, for readability.

diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -245,9 +245,9 @@ def copyfromcache(repo, hash, filename):
 return False
 return True
 
-def copytostore(repo, rev, file, uploaded=False):
+def copytostore(repo, revorctx, file, uploaded=False):
 wvfs = repo.wvfs
-hash = readstandin(repo, file, rev)
+hash = readstandin(repo, file, revorctx)
 if instore(repo, hash):
 return
 if wvfs.exists(file):
@@ -263,7 +263,7 @@ def copyalltostore(repo, node):
 for filename in ctx.files():
 realfile = splitstandin(filename)
 if realfile is not None and filename in ctx.manifest():
-copytostore(repo, ctx.node(), realfile)
+copytostore(repo, ctx, realfile)
 
 def copytostoreabsolute(repo, file, hash):
 if inusercache(repo.ui, hash):
@@ -485,6 +485,11 @@ def markcommitted(orig, ctx, node):
 lfdirstate.write()
 
 # As part of committing, copy all of the largefiles into the cache.
+#
+# Using "node" instead of "ctx" implies additional "repo[node]"
+# lookup while copyalltostore(), but can omit redundant check for
+# files comming from the 2nd parent, which should exist in store
+# at merging.
 copyalltostore(repo, node)
 
 def getlfilestoupdate(oldstandins, newstandins):
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1354,7 +1354,7 @@ def overridecat(orig, ui, repo, file1, *
 data = repo.wwritedata(f, data)
 fp.write(data)
 else:
-hash = lfutil.readstandin(repo, lf, ctx.rev())
+hash = lfutil.readstandin(repo, lf, ctx)
 if not lfutil.inusercache(repo.ui, hash):
 store = storefactory.openstore(repo)
 success, missing = store.get([(lf, hash)])
@@ -1405,7 +1405,7 @@ def mergeupdate(orig, repo, node, branch
 lfutil.writestandin(repo, standin, lfhash,
 lfutil.getexecutable(lfileabs))
 if (standin in pctx and
-lfhash == lfutil.readstandin(repo, lfile, '.')):
+lfhash == lfutil.readstandin(repo, lfile, pctx)):
 oldclean.add(lfile)
 for lfile in s.added:
 lfutil.updatestandin(repo, lfutil.standin(lfile))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] largefiles: omit redundant isstandin() before splitstandin()

2017-03-24 Thread FUJIWARA Katsunori
# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1490361898 -32400
#  Fri Mar 24 22:24:58 2017 +0900
# Node ID 287005e896abc735c0209e2369117b98399f43d8
# Parent  1f1ed3058fa829550b52110f35c65b4f79c92d10
largefiles: omit redundant isstandin() before splitstandin()

There are many isstandin() invocations before splitstandin().

The former examines whether specified path starts with ".hglf/". The
latter returns after ".hglf/" of specified path if it starts with that
prefix, or returns None otherwise.

Therefore, value returned by splitstandin() can be used for
replacement of preceding isstandin(), and this replacement can omit
redundant string comparison after isstandin().

diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py
+++ b/hgext/largefiles/lfcommands.py
@@ -244,10 +244,10 @@ def _lfconvert_addchangeset(rsrc, rdst, 
 dstfiles.append(f)
 
 def getfilectx(repo, memctx, f):
-if lfutil.isstandin(f):
+srcfname = lfutil.splitstandin(f)
+if srcfname is not None:
 # if the file isn't in the manifest then it was removed
 # or renamed, return None to indicate this
-srcfname = lfutil.splitstandin(f)
 try:
 fctx = ctx.filectx(srcfname)
 except error.LookupError:
diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -261,8 +261,8 @@ def copyalltostore(repo, node):
 
 ctx = repo[node]
 for filename in ctx.files():
-if isstandin(filename) and filename in ctx.manifest():
-realfile = splitstandin(filename)
+realfile = splitstandin(filename)
+if realfile is not None and filename in ctx.manifest():
 copytostore(repo, ctx.node(), realfile)
 
 def copytostoreabsolute(repo, file, hash):
@@ -478,8 +478,8 @@ def markcommitted(orig, ctx, node):
 
 lfdirstate = openlfdirstate(repo.ui, repo)
 for f in ctx.files():
-if isstandin(f):
-lfile = splitstandin(f)
+lfile = splitstandin(f)
+if lfile is not None:
 synclfdirstate(repo, lfdirstate, lfile, False)
 lfdirstate.write()
 
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -649,10 +649,13 @@ def overridecopy(orig, ui, repo, pats, o
 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
 m._fileroots = set(m._files)
 origmatchfn = m.matchfn
-m.matchfn = lambda f: (lfutil.isstandin(f) and
-(f in manifest) and
-origmatchfn(lfutil.splitstandin(f)) or
-None)
+def matchfn(f):
+lfile = lfutil.splitstandin(f)
+return (lfile is not None and
+(f in manifest) and
+origmatchfn(lfile) or
+None)
+m.matchfn = matchfn
 return m
 oldmatch = installmatchfn(overridematch)
 listpats = []
@@ -767,8 +770,9 @@ def overriderevert(orig, ui, repo, ctx, 
 m._fileroots = set(m._files)
 origmatchfn = m.matchfn
 def matchfn(f):
-if lfutil.isstandin(f):
-return (origmatchfn(lfutil.splitstandin(f)) and
+lfile = lfutil.splitstandin(f)
+if lfile is not None:
+return (origmatchfn(lfile) and
 (f in ctx or f in mctx))
 return origmatchfn(f)
 m.matchfn = matchfn
@@ -968,18 +972,19 @@ def overridearchive(orig, repo, dest, no
 for f in ctx:
 ff = ctx.flags(f)
 getdata = ctx[f].data
-if lfutil.isstandin(f):
+lfile = lfutil.splitstandin(f)
+if lfile is not None:
 if node is not None:
 path = lfutil.findfile(repo, getdata().strip())
 
 if path is None:
 raise error.Abort(
_('largefile %s not found in repo store or system 
cache')
-   % lfutil.splitstandin(f))
+   % lfile)
 else:
-path = lfutil.splitstandin(f)
-
-f = lfutil.splitstandin(f)
+path = lfile
+
+f = lfile
 
 getdata = lambda: util.readfile(path)
 write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, getdata)
@@ -1018,18 +1023,19 @@ def hgsubrepoarchive(orig, repo, archive
 for f in ctx:
 ff = ctx.flags(f)
 getdata = ctx[f].data
-if lfutil.isstandin(f):
+lfile = lfutil.splitstandin(f)
+if lfile is not None:
 if ctx.node() is not None:
 path = 

Re: [PATCH 4 of 4] checkcode: enforce lowercase for extension docstring title

2017-03-24 Thread Augie Fackler
On Thu, Mar 23, 2017 at 09:24:48PM -0700, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu 
> # Date 1490329401 25200
> #  Thu Mar 23 21:23:21 2017 -0700
> # Node ID 0a73985fe80237a67ca50d7642ba6e02ed45e8e3
> # Parent  f2026595cb39cce3934995d6a3f8aa3d97b30501
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #  hg pull https://bitbucket.org/quark-zju/hg-draft -r 
> 0a73985fe802
> checkcode: enforce lowercase for extension docstring title

Queued, thanks.

>
> This will ensure new extensions are consistent and `hg help -e` has a
> consistent output.
>
> I have to add a new group since the normal "pypats" will be filtered by
> "pyfilters", which will remove comments and docstrings.
>
> diff --git a/contrib/check-code.py b/contrib/check-code.py
> --- a/contrib/check-code.py
> +++ b/contrib/check-code.py
> @@ -372,4 +372,11 @@ pyfilters = [
>  ]
>
> +# extension non-filter patterns
> +pyextnfpats = [
> +[(r'^"""\n?[A-Z]', "don't capitalize docstring title")],
> +# warnings
> +[],
> +]
> +
>  txtfilters = []
>
> @@ -481,4 +488,5 @@ py3pats = [
>  checks = [
>  ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats),
> +('python', r'.*hgext.*\.py$', '', [], pyextnfpats),
>  ('python 3', r'.*(hgext|mercurial).*(?  pyfilters, py3pats),
> ___
> 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 hglib] hglib: fix hg clone --uncompressed option typo

2017-03-24 Thread Pulkit Goyal
On Fri, Mar 24, 2017 at 8:48 AM, Long Vu  wrote:

> # HG changeset patch
> # User Long Vu 
> # Date 1490322881 14400
> #  Thu Mar 23 22:34:41 2017 -0400
> # Node ID a6ae14f83d7a5e822b214ab0216e9685395b778f
> # Parent  ae38fb772613604dac7fcf63705e8a2a17ff50cd
> hglib: fix hg clone --uncompressed option typo
>
>
This is issue5458. The person pushing this change
​,​
add
​it​
to commit message so that our Bugzilla bot can mark this as fixed.
​(I am not sure though how the bugzilla bot works.)​

> ​
>
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: GSoC 17: Release notes extension

2017-03-24 Thread Rishabh Madan
On Fri, Mar 24, 2017 at 10:32 AM, Martin von Zweigbergk <
martinv...@google.com> wrote:

> As an alternative to compiling the release notes from commit messages, we
> could do what Git does, which is to keep a file per release
> (Documentation/Relnotes/.txt in their case) that we update every
> now and then. I think Junio (the maintainer) generally updates that file.
> We don't have a single maintainer, but we could accept patches to from
> anyone of course.
>
> I think that is an organisation specific practice. We should keep in mind
that this extension if shipped with core would not only be specific to
Mercurial but other people using mercurial might also use this. Also, I
feel that having an automated (accompanied with copyediting) process for
generating release notes would definitely improve the quality of it since,
a lot of things get left out when writing these notes. For example, some
things might have been left out in the relnotes for 4.2 considering the
time gap between release of 4.1 and 4.2.

We could also keep the current process, which is to keep the release notes
> on the wiki (I just started on https://www.mercurial-scm.org/
> wiki/Release4.2 yesterday).
>
> I did like Greg's extension, but I wonder if it's worth the trouble of
> having each contributor write part of the release notes. I wonder if we
> won't want to restructure it enough afterwards anyway that I'm not sure the
> automated step is worth the trouble. I understand that it helps us not
> forget to include things in the release notes, but maybe it would be as
> effective to add a new commit message tag like (RN) in addition to the (BC)
> and (API) we already have.
>


> On Thu, Mar 23, 2017 at 9:14 PM, Gregory Szorc 
> wrote:
>
>> On Mon, Mar 20, 2017 at 6:04 PM, Rishabh Madan 
>> wrote:
>>
>>> Hello,
>>>
>>> I am Rishabh Madan and I will be a GSoC applicant this year under
>>> Mercurial.
>>>
>>> I wanted to discuss about the Release notes extension project.[1]
>>> 
>>> I have gone through the mailing list discussions. I am currently
>>> understanding the intial patch sent by Gregory Szorc, for the releasenotes
>>> extension.
>>>
>>
>> I hacked on this for an hour or two several days ago. A newer version is
>> at https://hg.mozilla.org/users/gszorc_mozilla.com/hg/rev/releasenotes.
>> Not much has fundamentally changed: I was just trying to make commit
>> message parsing more robust.
>>
>>
>>>
>>> I would like to get a few inputs for this project:
>>>
>>> 1. Commit message parser
>>> (i) I feel this is the core of the idea. From what I understand, we will
>>> have to keep a specific format for the commit messages that will be parsed
>>> and output will be stored in a changelog. But, this is a extension that
>>> would help other organizations as well. Do we expect them to abide by
>>> certain format for the commit message?
>>>
>>
>> For this idea to work, you have to standardize on *something*. I chose to
>> use ReStructured Text admonitions (".. directive:: ...") because a)
>> Mercurial already has a basic ReST parser and it was easy to leverage ReST
>> b) ReST is extensible and therefore is a natural fit for this use case.
>> There's no reason other formats couldn't be leveraged. But for a minimal
>> viable product, I'd focus on ReST.
>>
>> The code as currently written converts extracted release notes fragments
>> to Python data structures. So it should be possible to plug in other
>> formats/parsers easily enough.
>>
>>
>>> (ii) Is this going to be a hybrid process? I mean, will the notes once
>>> created be edited by maintainers at a later stage?
>>>
>>
>> This isn't implemented in my proof-of-concept yet, but yes, we absolutely
>> need to support edits. The way I envision this being implemented is that
>> there is some kind of similarity detection to reconcile differences between
>> release notes fragments in commit messages and release notes files.
>> Currently, the extension parses commit messages and a release notes file to
>> a common data structure type, merges/unions the data, and emits a new
>> release notes file. We need to add a step that attempts to match edited
>> release notes file entries to their original commit message fragments so
>> duplicates aren't produced. This can likely utilize the APIs already in
>> Mercurial for identifying similar content.
>>
>>
>>> (iii) The extension shouldn't add extremely small changesets to the
>>> changelog. I think this can be done by adding some keyword to the commit
>>> message (like [IGNORERST]).
>>>
>>
>> As currently implemented, a release notes entry is only produced if the
>> commit message contains special syntax - a ReST admonition. This avoids the
>> problem of "extremely small changesets" polluting the release notes. But it
>> has the drawback of requiring changeset authors to remember to write a
>> release notes admonition. This trade-off is arguably 

Re: GSoC 17: Release notes extension

2017-03-24 Thread Rishabh Madan
>
> For now, I'd assume we'd implement our own parser and if others want
> other formats, they'd need to send us patches.


Yes, we can do that, or once we have a workable parser ready we can also
have some default templates that the user can configure/set in the
.hgrc file.

 Another interesting approach is towncrier:
> https://github.com/hawkowl/towncrier though I'm not in love with the
> approach of commiting lots of short-lived files to the repository (I
> much prefer having it in the commit message).


Thank you for this reference. I had a look at this project and I think we
can get some good ideas from here, to begin with,
ᐧ
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7 V4] hgweb: expose a followlines UI in filerevision view (RFC)

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1489594320 -3600
#  Wed Mar 15 17:12:00 2017 +0100
# Node ID b633be53b40e8b2f5debb3a7aa528799072987bf
# Parent  f997405d59861cf460931d519425b361b7aea0fb
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r b633be53b40e
# EXP-Topic linerange-log/hgweb-filelog
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".

All JavaScript code lives in a new "linerangelog.js" file, sourced in
filerevision template (only in "paper" style for now).

This is proposal implementation, comments welcome on any aspects.

diff --git a/contrib/wix/templates.wxs b/contrib/wix/templates.wxs
--- a/contrib/wix/templates.wxs
+++ b/contrib/wix/templates.wxs
@@ -225,6 +225,7 @@
 
 
 
+
 
 
 
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
@@ -71,8 +71,11 @@
 
 line wrap: on
  line source
-{text%fileline}
+{text%fileline}
 
+
+
+
 
 
 
diff --git a/mercurial/templates/static/linerangelog.js 
b/mercurial/templates/static/linerangelog.js
new file mode 100644
--- /dev/null
+++ b/mercurial/templates/static/linerangelog.js
@@ -0,0 +1,83 @@
+// Copyright 2017 Logilab SA 
+//
+// This software may be used and distributed according to the terms
+// of the GNU General Public License, incorporated herein by reference.
+
+document.addEventListener('DOMContentLoaded', function() {
+// install mouse event listeners on 
+var sourcelines = document.getElementsByClassName('sourcelines')[0];
+if (typeof sourcelines === 'undefined') {
+return;
+}
+var targetUri = sourcelines.dataset.logurl;
+if (typeof targetUri === '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;
+}
+
+}, 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
@@ 

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

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1489414549 -3600
#  Mon Mar 13 15:15:49 2017 +0100
# Node ID 30d2823af2d2f38a3bb2adc8e925b61f0b1b1098
# Parent  3981358ae1e7b458e3152230740954f3ccfa4c3c
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r 30d2823af2d2
# 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(wep, tmpl, ctx, basectx, files, style):
+def diffs(web, tmpl, ctx, basectx, files, style, linerange=None):
 
 def prettyprintlines(lines, blockno):
 for lineno, l in enumerate(lines, 1):
@@ -470,6 +470,11 @@ def diffs(wep, tmpl, ctx, basectx, files
 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', parity=next(parity), blockno=blockno,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


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

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1484844060 -3600
#  Thu Jan 19 17:41:00 2017 +0100
# Node ID 3981358ae1e7b458e3152230740954f3ccfa4c3c
# Parent  3b234555196d4df1881b59c0e8c9a2531a53eed4
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r 3981358ae1e7
# 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, 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 1 of 7 V4] hgweb: handle "parity" internally in webutil.diffs()

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1489398019 -3600
#  Mon Mar 13 10:40:19 2017 +0100
# Node ID e62a136ee79973157cded80c7f578dc60b7f6a68
# Parent  527a247f114f8af37326805fd6cce923f9ac6453
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r e62a136ee799
# EXP-Topic linerange-log/hgweb-filelog
hgweb: handle "parity" internally in webutil.diffs()

There's apparently no reason to have the "parity" of diff blocks that
webutil.diffs() generates coming from outside the function. So have it
internally managed. We thus now pass a "web" object to webutil.diffs() to get
access to both "repo" and "stripecount" attribute.

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -756,12 +756,11 @@ def filediff(web, req, tmpl):
 ctx = fctx.changectx()
 basectx = ctx.p1()
 
-parity = paritygen(web.stripecount)
 style = web.config('web', 'style', 'paper')
 if 'style' in req.form:
 style = req.form['style'][0]
 
-diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, [path], parity, style)
+diffs = webutil.diffs(web, tmpl, ctx, basectx, [path], style)
 if fctx is not None:
 rename = webutil.renamelink(fctx)
 ctx = fctx
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -388,8 +388,7 @@ def changesetentry(web, req, tmpl, ctx):
 if 'style' in req.form:
 style = req.form['style'][0]
 
-parity = paritygen(web.stripecount)
-diff = diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
+diff = diffs(web, tmpl, ctx, basectx, None, style)
 
 parity = paritygen(web.stripecount)
 diffstatsgen = diffstatgen(ctx, basectx)
@@ -414,7 +413,7 @@ def listfilediffs(tmpl, files, node, max
 if len(files) > max:
 yield tmpl('fileellipses')
 
-def diffs(repo, tmpl, ctx, basectx, files, parity, style):
+def diffs(wep, tmpl, ctx, basectx, files, style):
 
 def prettyprintlines(lines, blockno):
 for lineno, l in enumerate(lines, 1):
@@ -433,6 +432,7 @@ def diffs(repo, tmpl, ctx, basectx, file
lineid="l%s" % difflineno,
linenumber="% 8s" % difflineno)
 
+repo = web.repo
 if files:
 m = match.exact(repo.root, repo.getcwd(), files)
 else:
@@ -441,6 +441,7 @@ def diffs(repo, tmpl, ctx, basectx, file
 diffopts = patch.diffopts(repo.ui, untrusted=True)
 node1 = basectx.node()
 node2 = ctx.node()
+parity = paritygen(web.stripecount)
 
 diffhunks = patch.diffhunks(repo, node1, node2, m, opts=diffopts)
 for blockno, (header, hunks) in enumerate(diffhunks, 1):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 7 V4] revset: factor out linerange processing into a utility function

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1487957948 -3600
#  Fri Feb 24 18:39:08 2017 +0100
# Node ID 3b234555196d4df1881b59c0e8c9a2531a53eed4
# Parent  bc1ca69d5b73f43fb2c93c4f075c909eaf32e531
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r 3b234555196d
# EXP-Topic linerange-log/hgweb-filelog
revset: factor out linerange processing into a utility function

Similar processing will be done in hgweb.webutil in forthcoming changeset.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -945,11 +945,7 @@ def followlines(repo, subset, x):
 lr = getrange(args['lines'][0], _("followlines expects a line range"))
 fromline, toline = [getinteger(a, _("line range bounds must be integers"))
 for a in lr]
-if toline - fromline < 0:
-raise error.ParseError(_("line range must be positive"))
-if fromline < 1:
-raise error.ParseError(_("fromline must be strictly positive"))
-fromline -= 1
+fromline, toline = util.processlinerange(fromline, toline)
 
 fctx = repo[rev].filectx(fname)
 revs = (c.rev() for c, _linerange
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -2119,6 +2119,27 @@ def unitcountfn(*unittable):
 
 return go
 
+def processlinerange(fromline, toline):
+"""Check that linerange : makes sense and return a
+0-based range.
+
+>>> processlinerange(10, 20)
+(9, 20)
+>>> processlinerange(2, 1)
+Traceback (most recent call last):
+...
+ParseError: line range must be positive
+>>> processlinerange(0, 5)
+Traceback (most recent call last):
+...
+ParseError: fromline must be strictly positive
+"""
+if toline - fromline < 0:
+raise error.ParseError(_("line range must be positive"))
+if fromline < 1:
+raise error.ParseError(_("fromline must be strictly positive"))
+return fromline - 1, toline
+
 bytecount = unitcountfn(
 (100, 1 << 30, _('%.0f GB')),
 (10, 1 << 30, _('%.1f GB')),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7 V4] hgweb: add a "patch" query parameter to filelog command

2017-03-24 Thread Denis Laxalde
# HG changeset patch
# User Denis Laxalde 
# Date 1489398073 -3600
#  Mon Mar 13 10:41:13 2017 +0100
# Node ID bc1ca69d5b73f43fb2c93c4f075c909eaf32e531
# Parent  e62a136ee79973157cded80c7f578dc60b7f6a68
# Available At http://hg.logilab.org/users/dlaxalde/hg
#  hg pull http://hg.logilab.org/users/dlaxalde/hg -r bc1ca69d5b73
# EXP-Topic linerange-log/hgweb-filelog
hgweb: add a "patch" query parameter to filelog command

Add support for a "patch" query parameter in filelog web command similar to
--patch option of `hg log` to display the diff of each changeset in the table
of revisions. The diff text is displayed in a dedicated row of the table that
follows the existing one for each entry and spans over all columns. Only
update "paper" template in this patch.

diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -973,6 +973,10 @@ def filelog(web, req, tmpl):
 morevars = copy.copy(tmpl.defaults['sessionvars'])
 morevars['revcount'] = revcount * 2
 
+patch = 'patch' in req.form
+if patch:
+lessvars['patch'] = morevars['patch'] = req.form['patch'][0]
+
 count = fctx.filerev() + 1
 start = max(0, count - revcount) # first rev on this page
 end = min(count, start + revcount) # last rev on this page
@@ -981,12 +985,27 @@ def filelog(web, req, tmpl):
 repo = web.repo
 revs = fctx.filelog().revs(start, end - 1)
 entries = []
+
+diffstyle = web.config('web', 'style', 'paper')
+if 'style' in req.form:
+diffstyle = req.form['style'][0]
+
+def diff(fctx):
+ctx = fctx.changectx()
+basectx = ctx.p1()
+path = fctx.path()
+return webutil.diffs(web, tmpl, ctx, basectx, [path], diffstyle)
+
 for i in revs:
 iterfctx = fctx.filectx(i)
+diffs = None
+if patch:
+diffs = diff(iterfctx)
 entries.append(dict(
 parity=next(parity),
 filerev=i,
 file=f,
+diff=diffs,
 rename=webutil.renamelink(iterfctx),
 **webutil.commonentry(repo, iterfctx)))
 entries.reverse()
@@ -1000,6 +1019,7 @@ def filelog(web, req, tmpl):
 nav=nav,
 symrev=webutil.symrevorshortnode(req, fctx),
 entries=entries,
+patch=patch,
 latestentry=latestentry,
 revcount=revcount,
 morevars=morevars,
diff --git a/mercurial/templates/paper/filelogentry.tmpl 
b/mercurial/templates/paper/filelogentry.tmpl
--- a/mercurial/templates/paper/filelogentry.tmpl
+++ b/mercurial/templates/paper/filelogentry.tmpl
@@ -6,3 +6,4 @@

{inbranch%changelogbranchname}{branches%changelogbranchhead}{tags%changelogtag}{bookmarks%changelogtag}{rename%filelogrename}
   
  
+ {if(patch, '{diff}')}
diff --git a/tests/test-hgweb-filelog.t b/tests/test-hgweb-filelog.t
--- a/tests/test-hgweb-filelog.t
+++ b/tests/test-hgweb-filelog.t
@@ -221,6 +221,7 @@ tip - two revisions
  a-branch 
 

+   

 Thu, 01 Jan 1970 00:00:00 +
 test
@@ -229,6 +230,7 @@ tip - two revisions
  a-tag a-bookmark 
 

+   
   
   
   
@@ -340,6 +342,7 @@ second version - two revisions
  a-branch 
 

+   

 Thu, 01 Jan 1970 00:00:00 +
 test
@@ -348,6 +351,7 @@ second version - two revisions
  a-tag a-bookmark 
 

+   
   
   
   
@@ -459,6 +463,7 @@ first deleted - one revision
  a-tag a-bookmark 
 

+   
   
   
   
@@ -570,6 +575,7 @@ first version - one revision
  a-tag a-bookmark 
 

+   
   
   
   
@@ -762,6 +768,135 @@ should show base link, use spartan becau
   
   
 
+filelog with patch
+
+  $ (get-with-headers.py localhost:$HGPORT 'log/4/a?patch=1')
+  200 Script output follows
+  
+  http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd;>
+  http://www.w3.org/1999/xhtml; xml:lang="en-US">
+  
+  
+  
+  
+  
+  
+  test: a history
+  
+  
+  
+  
+  
+  
+  
+  
+  https://mercurial-scm.org/;>
+  
+  
+  
+  log
+  graph
+  tags
+  bookmarks
+  branches
+  
+  
+  changeset
+  browse
+  
+  
+  file
+  diff
+  comparison
+  annotate
+  file log
+  raw
+  
+  
+  help
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  Mercurial 
+  
+   log a @ 4:3f41bc784e7e
+   a-branch 
+  
+  
+  
+  
+  
+  Find changesets by keywords (author, files, the commit 
message), revision
+  number or hash, or revset expression.
+  
+  
+  
+  less
+  more
+  | (0) tip 
+  
+  
+  
+   
+age
+author
+description
+   
+  
+  
+   
+Thu, 01 Jan 1970 00:00:00 +
+test
+
+ second a
+ a-branch 
+
+   
+   
+  --- /dev/null  Thu Jan 01 00:00:00 
1970 +
+  +++ b/a Thu Jan 01 00:00:00 1970 
+
+  @@ -0,0 +1,1 @@
+  +b
+   
+Thu, 01 Jan 1970 00:00:00 +
+test
+
+ first a
+ a-tag a-bookmark 
+
+   
+   
+  --- 

Re: [PATCH] fancyopts: making config defaults actually override defaults

2017-03-24 Thread Rodrigo Damazio via Mercurial-devel
On Thu, Mar 23, 2017 at 3:07 AM, Ryan McElroy  wrote:

> On 3/22/17 6:51 PM, Martin von Zweigbergk wrote:
>
>> On Wed, Mar 22, 2017 at 10:14 AM, Rodrigo Damazio 
>> wrote:
>>
>>> On Wed, Mar 22, 2017 at 3:50 AM, Ryan McElroy  wrote:
>>>
 Rodrigo: for some reason, patchwork thinks you are Martin. Any idea why?
 https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwo
 rk.mercurial-2Dscm.org_patch_19133_=DwIBaQ=5VD0RTtNlTh3y
 cd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=qgti-7e8saOlUI0k7ljLZ6H
 Ah4SsKVlgoONeD60WZRA=pKbjIO05blt_27t3IcMhFfzDFctfA-bMMaXrmGmiXJM=

>>> No idea, but I'm using a script he created for mailing patches directly
>>> to
>>> gmail's backend servers (to avoid reformatting) - Martin, any chance you
>>> hardcoded your own address there? :)
>>>
>> Nope. IIUC, patchwork has decided to associate any email from
>> mercurial-devel@mercurial-scm.org with me, because it probably first
>> received one from there from me. And the reason it is from
>> mercurial-devel@mercurial-scm.org in the first place is because we
>> (Google) set the DMARC/SPF/whatever headers to prevent spoofing of
>> @google.com addresses, so the mailing list has no choice but to
>> rewrite it as coming from the mailing list itself. I may very well
>> have misunderstood how that works, but hopefully you get the idea
>> anyway.
>>
>> On 3/14/17 10:16 PM, Rodrigo Damazio via Mercurial-devel wrote:

 On Tue, Mar 14, 2017 at 12:50 PM, David Soria Parra
  wrote:

> On Sat, Mar 11, 2017 at 06:03:30PM -0800, Rodrigo Damazio Bovendorp via
> Mercurial-devel wrote:
>
>> # HG changeset patch
>> # User Rodrigo Damazio 
>> # Date 1489274373 28800
>> #  Sat Mar 11 15:19:33 2017 -0800
>> # Node ID 8c833b81a994e2d3304c3b06793f536355528aab
>> # Parent  62939e0148f170b67ca8c7374f36c413b67fd387
>> fancyopts: making config defaults actually override defaults
>>
>> Overall this LGTM, and clearly makes defaults much better :).  My
> concern
> is that we are encouraging the use of defaults again, while they are
> deprecated. Defaults have inherent problems that they overwrite
> arguments
> which might be mutable exclusive with others (e.g. --graph in incoming
> and outgoing), or lead to undesired behavior if it's set by an admin.
> an
> exmaple
> is if you would specifiy defaults.update.check=True, the user will not
> find an
> --no-check option in the help message or anywhere else. This is not a
> problem if
> we assume defaults are alway set by the user and he knows about them.
>

 Thanks for the review.

 Yes, we discussed the update --check case specifically during Sprint:
 https://urldefense.proofpoint.com/v2/url?u=https-3A__public.
 etherpad-2Dmozilla.org_p_sprint-2Dhg4.2=DwIBaQ=5VD0RTtNl
 Th3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=qgti-7e8saOlUI0k7lj
 LZ6HAh4SsKVlgoONeD60WZRA=usophD9VL71sbr6iMbVTWMVQPbQLoK4f-
 qe9si7v3rU=
 (search for "Flags and defaults breakout")


 Note that I copied the notes over the the wiki for posterity:
 https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mer
 curial-2Dscm.org_wiki_4.2sprint_Notes=DwIBaQ=5VD0RTtNlTh
 3ycd41b3MUw=Jw8rundaE7TbmqBYd1txIQ=qgti-7e8saOlUI0k7ljLZ
 6HAh4SsKVlgoONeD60WZRA=5pz07una5PeOy9ugeIPoZIk4uGiP7gE5cwdweE6HcTI=


 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