[PATCH 2 of 5] tests: clarify demandimport disabled state

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474429177 0
#  Wed Sep 21 03:39:37 2016 +
# Node ID 982fe7cdb28bb263a96b1bc2c9c3b8aedb025ab6
# Parent  24d85146985b7d2fef3c27b97d4be983e57ae5c7
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
982fe7cdb28b
tests: clarify demandimport disabled state

diff -r 24d85146985b -r 982fe7cdb28b tests/test-demandimport.py
--- a/tests/test-demandimport.pyWed Sep 21 02:46:59 2016 +
+++ b/tests/test-demandimport.pyWed Sep 21 03:39:37 2016 +
@@ -65,6 +65,7 @@
 
 demandimport.disable()
 os.environ['HGDEMANDIMPORT'] = 'disable'
+# this enable call should not actually enable demandimport!
 demandimport.enable()
 from mercurial import node
 print("node =", f(node))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 5] demandimport: reject contextlib._GeneratorContextManager on Py < 3.2

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474429683 0
#  Wed Sep 21 03:48:03 2016 +
# Node ID e07c3d398573f74a2e382deb06462bdc15ed437f
# Parent  894cc47eb82a85d167f5717c9fe0a31392e5bb97
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
e07c3d398573
demandimport: reject contextlib._GeneratorContextManager on Py < 3.2

issue5373

diff -r 894cc47eb82a -r e07c3d398573 mercurial/demandimport.py
--- a/mercurial/demandimport.py Wed Sep 21 03:47:35 2016 +
+++ b/mercurial/demandimport.py Wed Sep 21 03:48:03 2016 +
@@ -306,6 +306,13 @@
 if not mod in rejects:
 rejects[mod] = {}
 rejects[mod][prop] = [cls, msg]
+
+# decorator imported by ipython from pygments does an import which isn't
+# friendly to demandimport.
+if sys.version_info[0] < 3 or sys.version_info[1] < 2:
+reject('contextlib', '_GeneratorContextManager',
+   ImportError, 'cannot import name _GeneratorContextManager')
+
 def isenabled():
 return builtins.__import__ == _demandimport
 
diff -r 894cc47eb82a -r e07c3d398573 tests/test-demandimport.py
--- a/tests/test-demandimport.pyWed Sep 21 03:47:35 2016 +
+++ b/tests/test-demandimport.pyWed Sep 21 03:48:03 2016 +
@@ -71,6 +71,15 @@
 except ImportError:
 pass
 
+if sys.version_info[0] < 3 or sys.version_info[1] < 2:
+try:
+from contextlib import _GeneratorContextManager
+print('contextlib._GeneratorContextManager needs to be an '
+  'immediate importerror on python <3.2')
+_GeneratorContextManager.__doc__
+except ImportError:
+pass
+
 demandimport.disable()
 os.environ['HGDEMANDIMPORT'] = 'disable'
 # this enable call should not actually enable demandimport!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 03 of 17] push: update help hint to point to config.paths section

2016-09-20 Thread Martin von Zweigbergk via Mercurial-devel
Yuya reminded me earlier today that double quotes are better for Windows
(single quotes are not supported). So this seems like a regression in that
regard, no?

On Tue, Sep 20, 2016, 17:19 timeless  wrote:

> # HG changeset patch
> # User timeless 
> # Date 1474402358 0
> #  Tue Sep 20 20:12:38 2016 +
> # Node ID ca073d2379d406e610450b957a955bf05ebf64f3
> # Parent  00192f6bab14f19bfd58738b732ea1a2d24317ea
> # Available At https://bitbucket.org/timeless/mercurial-crew
> #  hg pull https://bitbucket.org/timeless/mercurial-crew -r
> ca073d2379d4
> push: update help hint to point to config.paths section
>
> diff -r 00192f6bab14 -r ca073d2379d4 mercurial/commands.py
> --- a/mercurial/commands.py Fri Sep 02 21:49:33 2016 +
> +++ b/mercurial/commands.py Tue Sep 20 20:12:38 2016 +
> @@ -6020,7 +6020,7 @@
>  path = ui.paths.getpath(dest, default=('default-push', 'default'))
>  if not path:
>  raise error.Abort(_('default repository not configured!'),
> - hint=_('see the "path" section in "hg help
> config"'))
> + hint=_("see 'hg help config.paths'"))
>  dest = path.pushloc or path.loc
>  branches = (path.branch, opts.get('branch') or [])
>  ui.status(_('pushing to %s\n') % util.hidepassword(dest))
> diff -r 00192f6bab14 -r ca073d2379d4 tests/test-default-push.t
> --- a/tests/test-default-push.t Fri Sep 02 21:49:33 2016 +
> +++ b/tests/test-default-push.t Tue Sep 20 20:12:38 2016 +
> @@ -19,7 +19,7 @@
>$ cd c
>$ hg push --config paths.default=
>abort: default repository not configured!
> -  (see the "path" section in "hg help config")
> +  (see 'hg help config.paths')
>[255]
>
>$ cd ..
> ___
> 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 17 of 17] tests: favor single quotes for wrapping hg help

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415360 0
#  Tue Sep 20 23:49:20 2016 +
# Node ID 07306ec6e0c4e0accdaf3efee348361f36910295
# Parent  0f8eca5689fad5be2cef54141c8185b8bd5639f3
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
07306ec6e0c4
tests: favor single quotes for wrapping hg help ...

diff -r 0f8eca5689fa -r 07306ec6e0c4 tests/test-help.t
--- a/tests/test-help.t Tue Sep 20 23:49:00 2016 +
+++ b/tests/test-help.t Tue Sep 20 23:49:20 2016 +
@@ -1250,12 +1250,12 @@
 
   $ hg help config.`hg help config|grep '^"'| \
   >   tail -1|sed 's![ "]*!!g'`| \
-  >   grep "hg help -c config" > /dev/null
+  >   grep 'hg help -c config' > /dev/null
   [1]
 
 note to use help -c for general hg help config:
 
-  $ hg help config |grep "hg help -c config" > /dev/null
+  $ hg help config |grep 'hg help -c config' > /dev/null
 
 Test templating help
 
@@ -1589,7 +1589,7 @@
   > subsequent section
   > --
   > 
-  > This should be hidden at "hg help ambiguous" with section name.
+  > This should be hidden at 'hg help ambiguous' with section name.
   > '''
   > """ % (escape(upper), escape(lower)))
   > EOF
diff -r 0f8eca5689fa -r 07306ec6e0c4 tests/test-obsolete-checkheads.t
--- a/tests/test-obsolete-checkheads.t  Tue Sep 20 23:49:00 2016 +
+++ b/tests/test-obsolete-checkheads.t  Tue Sep 20 23:49:20 2016 +
@@ -122,7 +122,7 @@
 #   pushing to $TESTTMP/remote
 #   searching for changes
 #   abort: push creates new remote head 71e3228bffe1!
-#   (merge or see "hg help push" for details about pushing new heads)
+#   (merge or see 'hg help push' for details about pushing new heads)
 #   [255]
 
 old head is obsolete but replacement is not pushed
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 14 of 17] obsolete: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415299 0
#  Tue Sep 20 23:48:19 2016 +
# Node ID 7deb4156b10a2dc83fc0278fb5f9fcb42eb17f25
# Parent  745cb8e2928b177706cfee03f298ed0873c9d538
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
7deb4156b10a
obsolete: use single quotes in use warning

diff -r 745cb8e2928b -r 7deb4156b10a mercurial/obsolete.py
--- a/mercurial/obsolete.py Tue Sep 20 23:48:08 2016 +
+++ b/mercurial/obsolete.py Tue Sep 20 23:48:19 2016 +
@@ -1236,7 +1236,7 @@
 if not prec.mutable():
 raise error.Abort(_("cannot obsolete public changeset: %s")
  % prec,
- hint='see "hg help phases" for details')
+ hint="see 'hg help phases' for details")
 nprec = prec.node()
 nsucs = tuple(s.node() for s in sucs)
 npare = None
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 13 of 17] localrepo: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415288 0
#  Tue Sep 20 23:48:08 2016 +
# Node ID 745cb8e2928b177706cfee03f298ed0873c9d538
# Parent  07753ca55667d0079f2418084dbf4ebab523cb35
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
745cb8e2928b
localrepo: use single quotes in use warning

diff -r 07753ca55667 -r 745cb8e2928b mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Sep 20 23:47:46 2016 +
+++ b/mercurial/localrepo.pyTue Sep 20 23:48:08 2016 +
@@ -1626,7 +1626,7 @@
 
 if list(ms.unresolved()):
 raise error.Abort(_('unresolved merge conflicts '
-'(see "hg help resolve")'))
+"(see 'hg help resolve')"))
 if ms.mdstate() != 's' or list(ms.driverresolved()):
 raise error.Abort(_('driver-resolved merge conflicts'),
   hint=_('run "hg resolve --all" to resolve'))
diff -r 07753ca55667 -r 745cb8e2928b tests/test-commit-unresolved.t
--- a/tests/test-commit-unresolved.tTue Sep 20 23:47:46 2016 +
+++ b/tests/test-commit-unresolved.tTue Sep 20 23:48:08 2016 +
@@ -34,7 +34,7 @@
 
   $ echo "ABCD" > A
   $ hg commit -m "Merged"
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   [255]
 
 Mark the conflict as resolved and commit
@@ -56,7 +56,7 @@
   [1]
   $ hg rm --force A
   $ hg commit -m merged
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   [255]
 
   $ hg resolve -ma
diff -r 07753ca55667 -r 745cb8e2928b tests/test-graft.t
--- a/tests/test-graft.tTue Sep 20 23:47:46 2016 +
+++ b/tests/test-graft.tTue Sep 20 23:48:08 2016 +
@@ -253,7 +253,7 @@
 
   $ hg graft -c
   grafting 4:9c233e8e184d "4"
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   [255]
 
 Fix up:
diff -r 07753ca55667 -r 745cb8e2928b tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t Tue Sep 20 23:47:46 2016 +
+++ b/tests/test-rebase-conflicts.t Tue Sep 20 23:48:08 2016 +
@@ -75,7 +75,7 @@
   $ hg rebase --continue
   already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
   rebasing 4:46f0b057b5c0 "L2"
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   [255]
 
 Conclude rebase:
diff -r 07753ca55667 -r 745cb8e2928b tests/test-rename-merge2.t
--- a/tests/test-rename-merge2.tTue Sep 20 23:47:46 2016 +
+++ b/tests/test-rename-merge2.tTue Sep 20 23:48:08 2016 +
@@ -719,7 +719,7 @@
   --
   M a
   M b
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   --
   
   $ tm "up a b" "nm a b" "  " "19 merge b no ancestor, prompt remove a"
@@ -764,7 +764,7 @@
   --
   M b
   C a
-  abort: unresolved merge conflicts (see "hg help resolve")
+  abort: unresolved merge conflicts (see 'hg help resolve')
   --
   
   $ tm "up a  " "um a b" "  " "20 merge a and b to b, remove a"
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 15 of 17] util: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415310 0
#  Tue Sep 20 23:48:30 2016 +
# Node ID 91d602cb454e0f5a7133e8302fa0cf1d86c7bfbe
# Parent  7deb4156b10a2dc83fc0278fb5f9fcb42eb17f25
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
91d602cb454e
util: use single quotes in use warning

diff -r 7deb4156b10a -r 91d602cb454e mercurial/util.py
--- a/mercurial/util.py Tue Sep 20 23:48:19 2016 +
+++ b/mercurial/util.py Tue Sep 20 23:48:30 2016 +
@@ -1953,7 +1953,7 @@
 except ValueError:
 raise Abort(_("invalid day spec: %s") % date[1:])
 if days < 0:
-raise Abort(_('%s must be nonnegative (see "hg help dates")')
+raise Abort(_("%s must be nonnegative (see 'hg help dates')")
 % date[1:])
 when = makedate()[0] - days * 3600 * 24
 return lambda x: x >= when
diff -r 7deb4156b10a -r 91d602cb454e tests/test-parse-date.t
--- a/tests/test-parse-date.t   Tue Sep 20 23:48:19 2016 +
+++ b/tests/test-parse-date.t   Tue Sep 20 23:48:30 2016 +
@@ -102,7 +102,7 @@
 Negative range
 
   $ hg log -d "--2"
-  abort: -2 must be nonnegative (see "hg help dates")
+  abort: -2 must be nonnegative (see 'hg help dates')
   [255]
 
 Whitespace only
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 16 of 17] samplehgrcs: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415340 0
#  Tue Sep 20 23:49:00 2016 +
# Node ID 0f8eca5689fad5be2cef54141c8185b8bd5639f3
# Parent  91d602cb454e0f5a7133e8302fa0cf1d86c7bfbe
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
0f8eca5689fa
samplehgrcs: use single quotes in use warning

diff -r 91d602cb454e -r 0f8eca5689fa mercurial/ui.py
--- a/mercurial/ui.py   Tue Sep 20 23:48:30 2016 +
+++ b/mercurial/ui.py   Tue Sep 20 23:49:00 2016 +
@@ -33,7 +33,7 @@
 
 samplehgrcs = {
 'user':
-"""# example user config (see "hg help config" for more info)
+"""# example user config (see 'hg help config' for more info)
 [ui]
 # name and email, e.g.
 # username = Jane Doe 
@@ -41,18 +41,18 @@
 
 [extensions]
 # uncomment these lines to enable some popular extensions
-# (see "hg help extensions" for more info)
+# (see 'hg help extensions' for more info)
 #
 # pager =
 # color =""",
 
 'cloned':
-"""# example repository config (see "hg help config" for more info)
+"""# example repository config (see 'hg help config' for more info)
 [paths]
 default = %s
 
 # path aliases to other clones of this repo in URLs or filesystem paths
-# (see "hg help config.paths" for more info)
+# (see 'hg help config.paths' for more info)
 #
 # default-push = ssh://j...@example.net/hg/jdoes-fork
 # my-fork  = ssh://j...@example.net/hg/jdoes-fork
@@ -64,10 +64,10 @@
 """,
 
 'local':
-"""# example repository config (see "hg help config" for more info)
+"""# example repository config (see 'hg help config' for more info)
 [paths]
 # path aliases to other clones of this repo in URLs or filesystem paths
-# (see "hg help config.paths" for more info)
+# (see 'hg help config.paths' for more info)
 #
 # default  = http://example.com/hg/example-repo
 # default-push = ssh://j...@example.net/hg/jdoes-fork
@@ -80,11 +80,11 @@
 """,
 
 'global':
-"""# example system-wide hg config (see "hg help config" for more info)
+"""# example system-wide hg config (see 'hg help config' for more info)
 
 [extensions]
 # uncomment these lines to enable some popular extensions
-# (see "hg help extensions" for more info)
+# (see 'hg help extensions' for more info)
 #
 # blackbox =
 # color =
diff -r 91d602cb454e -r 0f8eca5689fa tests/test-hgrc.t
--- a/tests/test-hgrc.t Tue Sep 20 23:48:30 2016 +
+++ b/tests/test-hgrc.t Tue Sep 20 23:49:00 2016 +
@@ -28,12 +28,12 @@
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd foobar
   $ cat .hg/hgrc
-  # example repository config (see "hg help config" for more info)
+  # example repository config (see 'hg help config' for more info)
   [paths]
   default = $TESTTMP/foo%bar (glob)
   
   # path aliases to other clones of this repo in URLs or filesystem paths
-  # (see "hg help config.paths" for more info)
+  # (see 'hg help config.paths' for more info)
   #
   # default-push = ssh://j...@example.net/hg/jdoes-fork
   # my-fork  = ssh://j...@example.net/hg/jdoes-fork
diff -r 91d602cb454e -r 0f8eca5689fa tests/test-pull-http.t
--- a/tests/test-pull-http.tTue Sep 20 23:48:30 2016 +
+++ b/tests/test-pull-http.tTue Sep 20 23:49:00 2016 +
@@ -26,12 +26,12 @@
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cat test3/.hg/hgrc
-  # example repository config (see "hg help config" for more info)
+  # example repository config (see 'hg help config' for more info)
   [paths]
   default = http://foo@localhost:$HGPORT/
   
   # path aliases to other clones of this repo in URLs or filesystem paths
-  # (see "hg help config.paths" for more info)
+  # (see 'hg help config.paths' for more info)
   #
   # default-push = ssh://j...@example.net/hg/jdoes-fork
   # my-fork  = ssh://j...@example.net/hg/jdoes-fork
diff -r 91d602cb454e -r 0f8eca5689fa tests/test-revset-outgoing.t
--- a/tests/test-revset-outgoing.t  Tue Sep 20 23:48:30 2016 +
+++ b/tests/test-revset-outgoing.t  Tue Sep 20 23:49:00 2016 +
@@ -36,12 +36,12 @@
 
   $ cd b
   $ cat .hg/hgrc
-  # example repository config (see "hg help config" for more info)
+  # example repository config (see 'hg help config' for more info)
   [paths]
   default = $TESTTMP/a#stable (glob)
   
   # path aliases to other clones of this repo in URLs or filesystem paths
-  # (see "hg help config.paths" for more info)
+  # (see 'hg help config.paths' for more info)
   #
   # default-push = ssh://j...@example.net/hg/jdoes-fork
   # my-fork  = ssh://j...@example.net/hg/jdoes-fork
@@ -88,12 +88,12 @@
   $ echo "green = ../a#default" >> .hg/hgrc
 
   $ cat .hg/hgrc
-  # example repository config (see "hg help config" for more info)
+  # example repository config (see 'hg help config' for more info)
   [paths]
   default = $TESTTMP/a#stable (glob)
   
   # path aliases to other clones of this repo in URLs or 

[PATCH 12 of 17] help: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415266 0
#  Tue Sep 20 23:47:46 2016 +
# Node ID 07753ca55667d0079f2418084dbf4ebab523cb35
# Parent  b9f5707703a6167686435348dc095a94c22b44b5
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
07753ca55667
help: use single quotes in use warning

diff -r b9f5707703a6 -r 07753ca55667 mercurial/help.py
--- a/mercurial/help.py Tue Sep 20 23:47:30 2016 +
+++ b/mercurial/help.py Tue Sep 20 23:47:46 2016 +
@@ -358,7 +358,7 @@
 mod = extensions.find(name)
 doc = gettext(mod.__doc__) or ''
 if '\n' in doc.strip():
-msg = _('(use "hg help -e %s" to show help for '
+msg = _("(use 'hg help -e %s' to show help for "
 'the %s extension)') % (name, name)
 rst.append('\n%s\n' % msg)
 except KeyError:
@@ -374,7 +374,7 @@
 
 if not ui.verbose:
 if not full:
-rst.append(_('\n(use "hg %s -h" to show more help)\n')
+rst.append(_("\n(use 'hg %s -h' to show more help)\n")
% name)
 elif not ui.quiet:
 rst.append(_('\n(some details hidden, use --verbose '
@@ -450,20 +450,20 @@
 rst.append('\n%s\n' % optrst(_("global options"),
  commands.globalopts, ui.verbose))
 if name == 'shortlist':
-rst.append(_('\n(use "hg help" for the full list '
+rst.append(_("\n(use 'hg help' for the full list "
  'of commands)\n'))
 else:
 if name == 'shortlist':
-rst.append(_('\n(use "hg help" for the full list of commands '
+rst.append(_("\n(use 'hg help' for the full list of commands "
  'or "hg -v" for details)\n'))
 elif name and not full:
-rst.append(_('\n(use "hg help %s" to show the full help '
+rst.append(_("\n(use 'hg help %s' to show the full help "
  'text)\n') % name)
 elif name and cmds and name in cmds.keys():
-rst.append(_('\n(use "hg help -v -e %s" to show built-in '
+rst.append(_("\n(use 'hg help -v -e %s' to show built-in "
  'aliases and global options)\n') % name)
 else:
-rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
+rst.append(_("\n(use 'hg help -v%s' to show built-in aliases "
  'and global options)\n')
% (name and " " + name or ""))
 return rst
@@ -498,7 +498,7 @@
 
 try:
 cmdutil.findcmd(name, commands.table)
-rst.append(_('\nuse "hg help -c %s" to see help for '
+rst.append(_("\nuse 'hg help -c %s' to see help for "
'the %s command\n') % (name, name))
 except error.UnknownCommand:
 pass
@@ -536,7 +536,7 @@
 modcmds = set([c.partition('|')[0] for c in ct])
 rst.extend(helplist(modcmds.__contains__))
 else:
-rst.append(_('(use "hg help extensions" for information on 
enabling'
+rst.append(_("(use 'hg help extensions' for information on 
enabling"
' extensions)\n'))
 return rst
 
@@ -549,7 +549,7 @@
   "extension:") % cmd, {ext: doc}, indent=4,
showdeprecated=True)
 rst.append('\n')
-rst.append(_('(use "hg help extensions" for information on enabling '
+rst.append(_("(use 'hg help extensions' for information on enabling "
'extensions)\n'))
 return rst
 
@@ -575,7 +575,7 @@
 rst.append('\n')
 if not rst:
 msg = _('no matches')
-hint = _('try "hg help" for a list of topics')
+hint = _("try 'hg help' for a list of topics")
 raise error.Abort(msg, hint=hint)
 elif name and name != 'shortlist':
 queries = []
@@ -598,7 +598,7 @@
 raise error.UnknownCommand(name)
 else:
 msg = _('no such help topic: %s') % name
-hint = _('try "hg help --keyword %s"') % name
+hint = _("try 'hg help --keyword %s'") % name
 raise error.Abort(msg, hint=hint)
 else:
 # program name
diff -r b9f5707703a6 -r 07753ca55667 tests/test-alias.t
--- a/tests/test-alias.tTue Sep 20 23:47:30 2016 +
+++ b/tests/test-alias.tTue Sep 20 23:47:46 2016 +
@@ -99,7 +99,7 @@
   
   patchbomb command to send changesets as (a series of) patch emails
   
-  (use "hg help extensions" for information on enabling extensions)
+  (use 'hg help 

[PATCH 05 of 17] pager: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415089 0
#  Tue Sep 20 23:44:49 2016 +
# Node ID 8086d07155c64bd12d28437eb0e403601293be9a
# Parent  0ce8fb6cabe0657d1da7f741870bf9050f32fd9c
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
8086d07155c6
pager: use single quotes in use warning

diff -r 0ce8fb6cabe0 -r 8086d07155c6 hgext/pager.py
--- a/hgext/pager.pyTue Sep 20 23:44:28 2016 +
+++ b/hgext/pager.pyTue Sep 20 23:44:49 2016 +
@@ -10,7 +10,7 @@
 #   [extension]
 #   pager =
 #
-# Run "hg help pager" to get info on configuration.
+# Run 'hg help pager' to get info on configuration.
 
 '''browse command output with an external pager
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 17] histedit: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415125 0
#  Tue Sep 20 23:45:25 2016 +
# Node ID 912436c3e806e4715a7a9f7af78895f91a3e6c32
# Parent  45ccea8f0646176c5e9801113f91df201bd9be31
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
912436c3e806
histedit: use single quotes in use warning

diff -r 45ccea8f0646 -r 912436c3e806 hgext/histedit.py
--- a/hgext/histedit.py Tue Sep 20 23:45:15 2016 +
+++ b/hgext/histedit.py Tue Sep 20 23:45:25 2016 +
@@ -854,7 +854,7 @@
 roots = list(repo.revs("roots(%ln)", outgoing.missing))
 if 1 < len(roots):
 msg = _('there are ambiguous outgoing revisions')
-hint = _('see "hg help histedit" for more detail')
+hint = _("see 'hg help histedit' for more detail")
 raise error.Abort(msg, hint=hint)
 return repo.lookup(roots[0])
 
@@ -1290,7 +1290,7 @@
 root = ctxs[0] # list is already sorted by repo.set
 if not root.mutable():
 raise error.Abort(_('cannot edit public changeset: %s') % root,
- hint=_('see "hg help phases" for details'))
+ hint=_("see 'hg help phases' for details"))
 return [c.node() for c in ctxs]
 
 def ruleeditor(repo, ui, actions, editcomment=""):
@@ -1402,7 +1402,7 @@
 raise error.ParseError(_('missing rules for changeset %s') %
 node.short(missing[0]),
 hint=_('use "drop %s" to discard, see also: '
-   '"hg help -e histedit.config"')
+   "'hg help -e histedit.config'")
% node.short(missing[0]))
 
 def adjustreplacementsfrommarkers(repo, oldreplacements):
diff -r 45ccea8f0646 -r 912436c3e806 tests/test-histedit-arguments.t
--- a/tests/test-histedit-arguments.t   Tue Sep 20 23:45:15 2016 +
+++ b/tests/test-histedit-arguments.t   Tue Sep 20 23:45:25 2016 +
@@ -169,7 +169,7 @@
   > pick 08d98a8350f3 4 five
   > EOF
   hg: parse error: missing rules for changeset c8e68270e35a
-  (use "drop c8e68270e35a" to discard, see also: "hg help -e histedit.config")
+  (use "drop c8e68270e35a" to discard, see also: 'hg help -e histedit.config')
   [255]
 
 Test that extra revisions are detected
diff -r 45ccea8f0646 -r 912436c3e806 tests/test-histedit-drop.t
--- a/tests/test-histedit-drop.tTue Sep 20 23:45:15 2016 +
+++ b/tests/test-histedit-drop.tTue Sep 20 23:45:25 2016 +
@@ -151,7 +151,7 @@
   > pick ee283cb5f2d5 e
   > EOF
   hg: parse error: missing rules for changeset a4f7421b80f7
-  (use "drop a4f7421b80f7" to discard, see also: "hg help -e histedit.config")
+  (use "drop a4f7421b80f7" to discard, see also: 'hg help -e histedit.config')
   $ hg --config histedit.dropmissing=True histedit  cb9a9f314b8b --commands - 
2>&1 << EOF | fixbundle
   > EOF
   hg: parse error: no rules provided
diff -r 45ccea8f0646 -r 912436c3e806 tests/test-histedit-obsolete.t
--- a/tests/test-histedit-obsolete.tTue Sep 20 23:45:15 2016 +
+++ b/tests/test-histedit-obsolete.tTue Sep 20 23:45:25 2016 +
@@ -299,7 +299,7 @@
   
   $ hg histedit -r '.~2'
   abort: cannot edit public changeset: cb9a9f314b8b
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
 
 
diff -r 45ccea8f0646 -r 912436c3e806 tests/test-histedit-outgoing.t
--- a/tests/test-histedit-outgoing.tTue Sep 20 23:45:15 2016 +
+++ b/tests/test-histedit-outgoing.tTue Sep 20 23:45:25 2016 +
@@ -130,7 +130,7 @@
   
   $ HGEDITOR=cat hg -q histedit --outgoing '../r'
   abort: there are ambiguous outgoing revisions
-  (see "hg help histedit" for more detail)
+  (see 'hg help histedit' for more detail)
   [255]
 
   $ hg -q update -C 2
@@ -147,7 +147,7 @@
   
   $ HGEDITOR=cat hg -q histedit --outgoing '../r#default'
   abort: there are ambiguous outgoing revisions
-  (see "hg help histedit" for more detail)
+  (see 'hg help histedit' for more detail)
   [255]
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 17] mq: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415099 0
#  Tue Sep 20 23:44:59 2016 +
# Node ID 2da79d8f58abd0b83dd605e65d26b16c31aab5ff
# Parent  8086d07155c64bd12d28437eb0e403601293be9a
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
2da79d8f58ab
mq: use single quotes in use warning

diff -r 8086d07155c6 -r 2da79d8f58ab hgext/mq.py
--- a/hgext/mq.py   Tue Sep 20 23:44:49 2016 +
+++ b/hgext/mq.py   Tue Sep 20 23:44:59 2016 +
@@ -1562,7 +1562,7 @@
 if not repo[self.applied[-1].node].mutable():
 raise error.Abort(
 _("popping would remove a public revision"),
-hint=_('see "hg help phases" for details'))
+hint=_("see 'hg help phases' for details"))
 
 # we know there are no local changes, so we can make a simplified
 # form of hg.update.
@@ -1631,7 +1631,7 @@
 raise error.Abort(_("cannot qrefresh a revision with 
children"))
 if not repo[top].mutable():
 raise error.Abort(_("cannot qrefresh public revision"),
- hint=_('see "hg help phases" for details'))
+ hint=_("see 'hg help phases' for details"))
 
 cparents = repo.changelog.parents(top)
 patchparent = self.qparents(repo, top)
@@ -2117,7 +2117,7 @@
 for r in rev:
 if not repo[r].mutable():
 raise error.Abort(_('revision %d is not mutable') % r,
- hint=_('see "hg help phases" '
+ hint=_("see 'hg help phases' "
 'for details'))
 p1, p2 = repo.changelog.parentrevs(r)
 n = repo.changelog.node(r)
diff -r 8086d07155c6 -r 2da79d8f58ab tests/test-mq-qimport-fail-cleanup.t
--- a/tests/test-mq-qimport-fail-cleanup.t  Tue Sep 20 23:44:49 2016 +
+++ b/tests/test-mq-qimport-fail-cleanup.t  Tue Sep 20 23:44:59 2016 +
@@ -36,7 +36,7 @@
   $ hg pull -q -r 0 . # update phase
   $ hg qimport -r 0
   abort: revision 0 is not mutable
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
 
   $ cd ..
diff -r 8086d07155c6 -r 2da79d8f58ab tests/test-mq-qimport.t
--- a/tests/test-mq-qimport.t   Tue Sep 20 23:44:49 2016 +
+++ b/tests/test-mq-qimport.t   Tue Sep 20 23:44:59 2016 +
@@ -40,7 +40,7 @@
 
   $ hg qimport -r null
   abort: revision -1 is not mutable
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
   $ hg qseries
 
diff -r 8086d07155c6 -r 2da79d8f58ab tests/test-mq-safety.t
--- a/tests/test-mq-safety.tTue Sep 20 23:44:49 2016 +
+++ b/tests/test-mq-safety.tTue Sep 20 23:44:59 2016 +
@@ -26,17 +26,17 @@
   $ echo babar >> foo
   $ hg qref
   abort: cannot qrefresh public revision
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
   $ hg revert -a
   reverting foo
   $ hg qpop
   abort: popping would remove a public revision
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
   $ hg qfold bar
   abort: cannot qrefresh public revision
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
   $ hg revert -a
   reverting foo
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 17] rebase: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415068 0
#  Tue Sep 20 23:44:28 2016 +
# Node ID 0ce8fb6cabe0657d1da7f741870bf9050f32fd9c
# Parent  ca073d2379d406e610450b957a955bf05ebf64f3
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
0ce8fb6cabe0
rebase: use single quotes in use warning

diff -r ca073d2379d4 -r 0ce8fb6cabe0 hgext/rebase.py
--- a/hgext/rebase.py   Tue Sep 20 20:12:38 2016 +
+++ b/hgext/rebase.py   Tue Sep 20 23:44:28 2016 +
@@ -296,7 +296,7 @@
 if not self.keepf and not self.repo[root].mutable():
 raise error.Abort(_("can't rebase public changeset %s")
  % self.repo[root],
- hint=_('see "hg help phases" for details'))
+ hint=_("see 'hg help phases' for details"))
 
 (self.originalwd, self.target, self.state) = result
 if self.collapsef:
@@ -1128,7 +1128,7 @@
 if immutable:
 repo.ui.warn(_("warning: can't clean up public changesets %s\n")
 % ', '.join(str(repo[r]) for r in immutable),
-hint=_('see "hg help phases" for details'))
+hint=_("see 'hg help phases' for details"))
 cleanup = False
 
 descendants = set()
diff -r ca073d2379d4 -r 0ce8fb6cabe0 tests/test-rebase-scenario-global.t
--- a/tests/test-rebase-scenario-global.t   Tue Sep 20 20:12:38 2016 +
+++ b/tests/test-rebase-scenario-global.t   Tue Sep 20 23:44:28 2016 +
@@ -326,7 +326,7 @@
   [1]
   $ hg rebase -d 5 -b 6
   abort: can't rebase public changeset e1c4361dd923
-  (see "hg help phases" for details)
+  (see 'hg help phases' for details)
   [255]
 
   $ hg rebase -d 5 -b 6 --keep
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 17] serve: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474415222 0
#  Tue Sep 20 23:47:02 2016 +
# Node ID 2134ed21fb04e4f1d0585ca46896b2698bd3cf70
# Parent  3f18ad2b5443cad55dd5e720a16ff03638e1878f
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
2134ed21fb04
serve: use single quotes in use warning

diff -r 3f18ad2b5443 -r 2134ed21fb04 mercurial/commands.py
--- a/mercurial/commands.py Tue Sep 20 23:46:15 2016 +
+++ b/mercurial/commands.py Tue Sep 20 23:47:02 2016 +
@@ -6543,7 +6543,7 @@
 ('n', 'name', '',
  _('name to show in web pages (default: working directory)'), _('NAME')),
 ('', 'web-conf', '',
- _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
+ _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
  _('FILE')),
 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 17] remove: specify hg in added warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1472852760 0
#  Fri Sep 02 21:46:00 2016 +
# Node ID 31e48b2f0db6a01c6c7f64a54d12719c48033eed
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
31e48b2f0db6
remove: specify hg in added warning

diff -r 285a8c3e53f2 -r 31e48b2f0db6 mercurial/cmdutil.py
--- a/mercurial/cmdutil.py  Tue May 03 13:36:12 2016 +0900
+++ b/mercurial/cmdutil.py  Fri Sep 02 21:46:00 2016 +
@@ -2519,7 +2519,7 @@
 count += 1
 ui.progress(_('skipping'), count, total=total, unit=_('files'))
 warnings.append(_('not removing %s: file has been marked for add'
-  ' (use forget to undo)\n') % m.rel(f))
+  " (use 'hg forget' to undo add)\n") % m.rel(f))
 ret = 1
 ui.progress(_('skipping'), None)
 
diff -r 285a8c3e53f2 -r 31e48b2f0db6 tests/test-largefiles.t
--- a/tests/test-largefiles.t   Tue May 03 13:36:12 2016 +0900
+++ b/tests/test-largefiles.t   Fri Sep 02 21:46:00 2016 +
@@ -112,7 +112,7 @@
   normalnew already tracked!
   $ hg remove normalnew largenew
   not removing largenew: file is untracked
-  not removing normalnew: file has been marked for add (use forget to undo)
+  not removing normalnew: file has been marked for add (use 'hg forget' to 
undo add)
   [1]
   $ rm normalnew largenew
   $ hg up -Cq
diff -r 285a8c3e53f2 -r 31e48b2f0db6 tests/test-remove.t
--- a/tests/test-remove.t   Tue May 03 13:36:12 2016 +0900
+++ b/tests/test-remove.t   Fri Sep 02 21:46:00 2016 +
@@ -50,7 +50,7 @@
   \r (no-eol) (esc)
   skipping [===>] 1/1\r (no-eol) (esc)
   \r (no-eol) (esc)
-  not removing bar: file has been marked for add (use forget to undo)
+  not removing bar: file has been marked for add (use 'hg forget' to undo add)
   exit code: 1
   A bar
   ./bar
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 17] update: use single quotes in use warning

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1472852973 0
#  Fri Sep 02 21:49:33 2016 +
# Node ID 00192f6bab14f19bfd58738b732ea1a2d24317ea
# Parent  31e48b2f0db6a01c6c7f64a54d12719c48033eed
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
00192f6bab14
update: use single quotes in use warning

diff -r 31e48b2f0db6 -r 00192f6bab14 mercurial/destutil.py
--- a/mercurial/destutil.py Fri Sep 02 21:46:00 2016 +
+++ b/mercurial/destutil.py Fri Sep 02 21:49:33 2016 +
@@ -417,7 +417,7 @@
   (currentbranch))
 if otherheads:
 ui.warn(_('(committing will reopen the head, '
-'use `hg heads .` to see %i other heads)\n') %
+"use 'hg heads .' to see %i other heads)\n") %
   (len(otherheads)))
 else:
 ui.warn(_('(committing will reopen branch "%s")\n') %
diff -r 31e48b2f0db6 -r 00192f6bab14 tests/test-update-branches.t
--- a/tests/test-update-branches.t  Fri Sep 02 21:46:00 2016 +
+++ b/tests/test-update-branches.t  Fri Sep 02 21:49:33 2016 +
@@ -195,7 +195,7 @@
   $ norevtest "on closed branch head" clean 6
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   no open descendant heads on branch "default", updating to a closed head
-  (committing will reopen the head, use `hg heads .` to see 1 other heads)
+  (committing will reopen the head, use 'hg heads .' to see 1 other heads)
   parent=6
 
 if descendant non-closed branch head exists, and it is only one branch head:
@@ -214,7 +214,7 @@
   $ norevtest "all descendant branch heads are closed" clean 3
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   no open descendant heads on branch "default", updating to a closed head
-  (committing will reopen the head, use `hg heads .` to see 1 other heads)
+  (committing will reopen the head, use 'hg heads .' to see 1 other heads)
   parent=6
 
 Test updating if all branch heads are closed
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 17] push: update help hint to point to config.paths section

2016-09-20 Thread timeless
# HG changeset patch
# User timeless 
# Date 1474402358 0
#  Tue Sep 20 20:12:38 2016 +
# Node ID ca073d2379d406e610450b957a955bf05ebf64f3
# Parent  00192f6bab14f19bfd58738b732ea1a2d24317ea
# Available At https://bitbucket.org/timeless/mercurial-crew
#  hg pull https://bitbucket.org/timeless/mercurial-crew -r 
ca073d2379d4
push: update help hint to point to config.paths section

diff -r 00192f6bab14 -r ca073d2379d4 mercurial/commands.py
--- a/mercurial/commands.py Fri Sep 02 21:49:33 2016 +
+++ b/mercurial/commands.py Tue Sep 20 20:12:38 2016 +
@@ -6020,7 +6020,7 @@
 path = ui.paths.getpath(dest, default=('default-push', 'default'))
 if not path:
 raise error.Abort(_('default repository not configured!'),
- hint=_('see the "path" section in "hg help config"'))
+ hint=_("see 'hg help config.paths'"))
 dest = path.pushloc or path.loc
 branches = (path.branch, opts.get('branch') or [])
 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
diff -r 00192f6bab14 -r ca073d2379d4 tests/test-default-push.t
--- a/tests/test-default-push.t Fri Sep 02 21:49:33 2016 +
+++ b/tests/test-default-push.t Tue Sep 20 20:12:38 2016 +
@@ -19,7 +19,7 @@
   $ cd c
   $ hg push --config paths.default=
   abort: default repository not configured!
-  (see the "path" section in "hg help config")
+  (see 'hg help config.paths')
   [255]
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 9 V4] manifest: change manifestlog mancache to be directory based

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474415164 25200
#  Tue Sep 20 16:46:04 2016 -0700
# Node ID 69b91c12d904f329eff6618ac43f5cfef631e8dc
# Parent  52a206d772021194ab4356aeba2c73650851a624
manifest: change manifestlog mancache to be directory based

In the last patch we added a get() function that allows fetching directory level
treemanifestctxs. It didn't handle caching at directory level though, so we 
need to
change our mancache to support multiple directories.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1021,9 +1021,16 @@ class manifestlog(object):
 usetreemanifest = opts.get('treemanifest', usetreemanifest)
 self._treeinmem = usetreemanifest
 
+# A dictionary containing the cache for each directory
+self._dirmancache = {}
+
 # We'll separate this into it's own cache once oldmanifest is no longer
 # used
-self._mancache = repo.manifest._mancache
+self._dirmancache[''] = repo.manifest._mancache
+
+# A future patch makes this use the same config value as the existing
+# mancache
+self.cachesize = 4
 
 @property
 def _revlog(self):
@@ -1039,6 +1046,14 @@ class manifestlog(object):
 """Retrieves the manifest instance for the given node. Throws a 
KeyError
 if not found.
 """
+if node in self._dirmancache.get(dir, ()):
+cachemf = self._dirmancache[dir][node]
+# The old manifest may put non-ctx manifests in the cache, so
+# skip those since they don't implement the full api.
+if (isinstance(cachemf, manifestctx) or
+isinstance(cachemf, treemanifestctx)):
+return cachemf
+
 if dir:
 if self._revlog._treeondisk:
 m = treemanifestctx(self._revlog.dirlog(dir), dir, node)
@@ -1047,20 +1062,17 @@ class manifestlog(object):
 _("cannot ask for manifest directory '%s' in a flat "
   "manifest") % dir)
 else:
-if node in self._mancache:
-cachemf = self._mancache[node]
-# The old manifest may put non-ctx manifests in the cache, so
-# skip those since they don't implement the full api.
-if (isinstance(cachemf, manifestctx) or
-isinstance(cachemf, treemanifestctx)):
-return cachemf
-
 if self._treeinmem:
 m = treemanifestctx(self._revlog, '', node)
 else:
 m = manifestctx(self._revlog, node)
-if node != revlog.nullid:
-self._mancache[node] = m
+
+if node != revlog.nullid:
+mancache = self._dirmancache.get(dir)
+if not mancache:
+mancache = util.lrucachedict(self.cachesize)
+self._dirmancache[dir] = mancache
+mancache[node] = m
 return m
 
 def add(self, m, transaction, link, p1, p2, added, removed):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9 V4] manifest: add shallow option to treemanifestctx.readdelta and readfast

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 561681e7a16fa33aa8a40e4c9a31ff395a115e4c
# Parent  69b91c12d904f329eff6618ac43f5cfef631e8dc
manifest: add shallow option to treemanifestctx.readdelta and readfast

The old manifest had different functions for performing shallow reads, shallow
readdeltas, and shallow readfasts. Since a lot of the code is duplicate (and
since those functions don't make sense on a normal manifestctx), let's unify
them into flags on the existing readdelta and readfast functions.

A future diff will change consumers of these functions to use the manifestctx
versions and will delete the old apis.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1109,7 +1109,7 @@ class manifestctx(object):
 self._data = manifestdict(text)
 return self._data
 
-def readfast(self):
+def readfast(self, shallow=False):
 rl = self._revlog
 r = rl.rev(self._node)
 deltaparent = rl.deltaparent(r)
@@ -1117,7 +1117,7 @@ class manifestctx(object):
 return self.readdelta()
 return self.read()
 
-def readdelta(self):
+def readdelta(self, shallow=False):
 revlog = self._revlog
 if revlog._usemanifestv2:
 # Need to perform a slow delta
@@ -1176,27 +1176,40 @@ class treemanifestctx(object):
 def node(self):
 return self._node
 
-def readdelta(self):
-# Need to perform a slow delta
+def readdelta(self, shallow=False):
 revlog = self._revlog
-r0 = revlog.deltaparent(revlog.rev(self._node))
-m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
-m1 = self.read()
-md = treemanifest(dir=self._dir)
-for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
-if n1:
-md[f] = n1
-if fl1:
-md.setflag(f, fl1)
-return md
+if shallow and revlog._treeondisk and not revlog._usemanifestv2:
+if revlog._usemanifestv2:
+raise error.Abort(
+_("shallow readdelta() not implemented for manifestv2"))
+r = revlog.rev(self._node)
+d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
+return manifestdict(d)
+else:
+# Need to perform a slow delta
+r0 = revlog.deltaparent(revlog.rev(self._node))
+m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
+m1 = self.read()
+md = treemanifest(dir=self._dir)
+for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
+if n1:
+md[f] = n1
+if fl1:
+md.setflag(f, fl1)
+return md
 
-def readfast(self):
+def readfast(self, shallow=False):
 rl = self._revlog
 r = rl.rev(self._node)
 deltaparent = rl.deltaparent(r)
-if deltaparent != revlog.nullrev and deltaparent in rl.parentrevs(r):
-return self.readdelta()
-return self.read()
+if (deltaparent != revlog.nullrev and
+deltaparent in rl.parentrevs(r)):
+return self.readdelta(shallow=shallow)
+
+if shallow:
+return manifestdict(rl.revision(self._node))
+else:
+return self.read()
 
 class manifest(manifestrevlog):
 def __init__(self, opener, dir='', dirlogcache=None):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 9 V4] manifest: add manifestlog.get to obtain subdirectory instances

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 52a206d772021194ab4356aeba2c73650851a624
# Parent  8cf5f24c100e58ece712703d0e4bb0746bc3087e
manifest: add manifestlog.get to obtain subdirectory instances

Previously manifestlog only allowed obtaining root level manifests. Future
patches will need direct access to subdirectory manifests as part of changegroup
creation, so let's add a get() function that knows how to deal with
subdirectories.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1033,20 +1033,34 @@ class manifestlog(object):
 """Retrieves the manifest instance for the given node. Throws a 
KeyError
 if not found.
 """
-if node in self._mancache:
-cachemf = self._mancache[node]
-# The old manifest may put non-ctx manifests in the cache, so skip
-# those since they don't implement the full api.
-if (isinstance(cachemf, manifestctx) or
-isinstance(cachemf, treemanifestctx)):
-return cachemf
+return self.get('', node)
 
-if self._treeinmem:
-m = treemanifestctx(self._revlog, '', node)
+def get(self, dir, node):
+"""Retrieves the manifest instance for the given node. Throws a 
KeyError
+if not found.
+"""
+if dir:
+if self._revlog._treeondisk:
+m = treemanifestctx(self._revlog.dirlog(dir), dir, node)
+else:
+raise error.Abort(
+_("cannot ask for manifest directory '%s' in a flat "
+  "manifest") % dir)
 else:
-m = manifestctx(self._revlog, node)
-if node != revlog.nullid:
-self._mancache[node] = m
+if node in self._mancache:
+cachemf = self._mancache[node]
+# The old manifest may put non-ctx manifests in the cache, so
+# skip those since they don't implement the full api.
+if (isinstance(cachemf, manifestctx) or
+isinstance(cachemf, treemanifestctx)):
+return cachemf
+
+if self._treeinmem:
+m = treemanifestctx(self._revlog, '', node)
+else:
+m = manifestctx(self._revlog, node)
+if node != revlog.nullid:
+self._mancache[node] = m
 return m
 
 def add(self, m, transaction, link, p1, p2, added, removed):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9 V4] manifest: move manifest.add onto manifestrevlog

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 7df972d2d43fe655ffcfdef9e2efedda8a684af8
# Parent  4226fad2f4df52579581bab6cc6111e243b8000d
manifest: move manifest.add onto manifestrevlog

This moves add and _addtree onto manifestrevlog. manifestrevlog is responsible
for all serialization decisions, so therefore the add function should live on
it. This will allow us to call add() from manifestlog, which let's us further
break our dependency on manifest.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -946,6 +946,63 @@ class manifestrevlog(revlog.revlog):
 self._dirlogcache)
 return self._dirlogcache[dir]
 
+def add(self, m, transaction, link, p1, p2, added, removed):
+if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
+and not self._usemanifestv2):
+# If our first parent is in the manifest cache, we can
+# compute a delta here using properties we know about the
+# manifest up-front, which may save time later for the
+# revlog layer.
+
+_checkforbidden(added)
+# combine the changed lists into one sorted iterator
+work = heapq.merge([(x, False) for x in added],
+   [(x, True) for x in removed])
+
+arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
+cachedelta = self.rev(p1), deltatext
+text = util.buffer(arraytext)
+n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
+else:
+# The first parent manifest isn't already loaded, so we'll
+# just encode a fulltext of the manifest and pass that
+# through to the revlog layer, and let it handle the delta
+# process.
+if self._treeondisk:
+m1 = self.read(p1)
+m2 = self.read(p2)
+n = self._addtree(m, transaction, link, m1, m2)
+arraytext = None
+else:
+text = m.text(self._usemanifestv2)
+n = self.addrevision(text, transaction, link, p1, p2)
+arraytext = array.array('c', text)
+
+self.fulltextcache[n] = arraytext
+
+return n
+
+def _addtree(self, m, transaction, link, m1, m2):
+# If the manifest is unchanged compared to one parent,
+# don't write a new revision
+if m.unmodifiedsince(m1) or m.unmodifiedsince(m2):
+return m.node()
+def writesubtree(subm, subp1, subp2):
+sublog = self.dirlog(subm.dir())
+sublog.add(subm, transaction, link, subp1, subp2, None, None)
+m.writesubtrees(m1, m2, writesubtree)
+text = m.dirtext(self._usemanifestv2)
+# Double-check whether contents are unchanged to one parent
+if text == m1.dirtext(self._usemanifestv2):
+n = m1.node()
+elif text == m2.dirtext(self._usemanifestv2):
+n = m2.node()
+else:
+n = self.addrevision(text, transaction, link, m1.node(), m2.node())
+# Save nodeid so parent manifest can calculate its nodeid
+m.setnode(n)
+return n
+
 class manifestlog(object):
 """A collection class representing the collection of manifest snapshots
 referenced by commits in the repository.
@@ -1233,64 +1290,6 @@ class manifest(manifestrevlog):
 except KeyError:
 return None, None
 
-def add(self, m, transaction, link, p1, p2, added, removed):
-if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
-and not self._usemanifestv2):
-# If our first parent is in the manifest cache, we can
-# compute a delta here using properties we know about the
-# manifest up-front, which may save time later for the
-# revlog layer.
-
-_checkforbidden(added)
-# combine the changed lists into one sorted iterator
-work = heapq.merge([(x, False) for x in added],
-   [(x, True) for x in removed])
-
-arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
-cachedelta = self.rev(p1), deltatext
-text = util.buffer(arraytext)
-n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
-else:
-# The first parent manifest isn't already loaded, so we'll
-# just encode a fulltext of the manifest and pass that
-# through to the revlog layer, and let it handle the delta
-# process.
-if self._treeondisk:
-m1 = self.read(p1)
-m2 = self.read(p2)
-n = self._addtree(m, transaction, link, m1, m2)
-arraytext 

[PATCH 4 of 9 V4] manifest: add manifestlog.add

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 8cf5f24c100e58ece712703d0e4bb0746bc3087e
# Parent  7df972d2d43fe655ffcfdef9e2efedda8a684af8
manifest: add manifestlog.add

This adds a simple add() function to manifestlog. This let's us convert more
uses of repo.manifest to use repo.manifestlog, so we can further break our
dependency on the manifest class.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1732,9 +1732,9 @@ class localrepository(object):
 drop = [f for f in removed if f in m]
 for f in drop:
 del m[f]
-mn = self.manifest.add(m, trp, linkrev,
-   p1.manifestnode(), p2.manifestnode(),
-   added, drop)
+mn = self.manifestlog.add(m, trp, linkrev,
+  p1.manifestnode(), p2.manifestnode(),
+  added, drop)
 files = changed + removed
 else:
 mn = p1.manifestnode()
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1049,6 +1049,9 @@ class manifestlog(object):
 self._mancache[node] = m
 return m
 
+def add(self, m, transaction, link, p1, p2, added, removed):
+return self._revlog.add(m, transaction, link, p1, p2, added, removed)
+
 class manifestctx(object):
 """A class representing a single revision of a manifest, including its
 contents, its parent revs, and its linkrev.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 9 V4] manifest: remove dependency on treeinmem from manifest.add

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 4226fad2f4df52579581bab6cc6111e243b8000d
# Parent  952e434dd3b51dfdfbfd370dfa85f66929757be0
manifest: remove dependency on treeinmem from manifest.add

Currently manifest.add uses the treeinmem option to know if it can call
fastdelta on the given manifest instance. In a future patch we will be moving
add() to be on the manifestrevlog, so it won't have access to the treeinmem
option anymore. Instead, let's have it actually check if the given manifest
instance supports the fastdelta operation.

This also means that if treemanifest or any implementation eventually implements
fastdelta(), it will automatically benefit from this code path.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1234,7 +1234,7 @@ class manifest(manifestrevlog):
 return None, None
 
 def add(self, m, transaction, link, p1, p2, added, removed):
-if (p1 in self.fulltextcache and not self._treeinmem
+if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
 and not self._usemanifestv2):
 # If our first parent is in the manifest cache, we can
 # compute a delta here using properties we know about the
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9 V4] manifest: move treeinmem onto manifestlog

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 952e434dd3b51dfdfbfd370dfa85f66929757be0
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
manifest: move treeinmem onto manifestlog

A previous patched moved all the serialization related options onto
manifestrevlog (since it is responsible for serialization). Let's move the
treeinmem option on manifestlog, since it is responsible for materialization
decisions. This reduces the number of dependencies manifestlog has on the old
manifest type as well, so we can eventually make them completely independent of
each other.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -957,6 +957,13 @@ class manifestlog(object):
 def __init__(self, opener, repo):
 self._repo = repo
 
+usetreemanifest = False
+
+opts = getattr(opener, 'options', None)
+if opts is not None:
+usetreemanifest = opts.get('treemanifest', usetreemanifest)
+self._treeinmem = usetreemanifest
+
 # We'll separate this into it's own cache once oldmanifest is no longer
 # used
 self._mancache = repo.manifest._mancache
@@ -965,13 +972,6 @@ class manifestlog(object):
 def _revlog(self):
 return self._repo.manifest
 
-@property
-def _oldmanifest(self):
-# _revlog is the same as _oldmanifest right now, but we eventually want
-# to delete _oldmanifest while still allowing manifestlog to access the
-# revlog specific apis.
-return self._repo.manifest
-
 def __getitem__(self, node):
 """Retrieves the manifest instance for the given node. Throws a 
KeyError
 if not found.
@@ -984,7 +984,7 @@ class manifestlog(object):
 isinstance(cachemf, treemanifestctx)):
 return cachemf
 
-if self._oldmanifest._treeinmem:
+if self._treeinmem:
 m = treemanifestctx(self._revlog, '', node)
 else:
 m = manifestctx(self._revlog, node)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 6 of 9 V3] manifest: change manifestlog mancache to be directory based

2016-09-20 Thread Durham Goode
Woops, this patch didn't change manifestlog.get() to actually use the 
directory cache in the treemanifest code path.  Will resend with that fixed.



On 9/20/16 12:36 PM, Durham Goode wrote:

# HG changeset patch
# User Durham Goode 
# Date 1474400113 25200
#  Tue Sep 20 12:35:13 2016 -0700
# Node ID 22915866409350cbb5302289c05bb65bc1bfd308
# Parent  52a206d772021194ab4356aeba2c73650851a624
manifest: change manifestlog mancache to be directory based

In the last patch we added a get() function that allows fetching directory level
treemanifestctxs. It didn't handle caching at directory level though, so we 
need to
change our mancache to support multiple directories.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1021,9 +1021,16 @@ class manifestlog(object):
  usetreemanifest = opts.get('treemanifest', usetreemanifest)
  self._treeinmem = usetreemanifest
  
+# A dictionary containing the cache for each directory

+self._dirmancache = {}
+
  # We'll separate this into it's own cache once oldmanifest is no 
longer
  # used
-self._mancache = repo.manifest._mancache
+self._dirmancache[''] = repo.manifest._mancache
+
+# A future patch makes this use the same config value as the existing
+# mancache
+self.cachesize = 4
  
  @property

  def _revlog(self):
@@ -1047,8 +1054,8 @@ class manifestlog(object):
  _("cannot ask for manifest directory '%s' in a flat "
"manifest") % dir)
  else:
-if node in self._mancache:
-cachemf = self._mancache[node]
+if node in self._dirmancache.get(dir, ()):
+cachemf = self._dirmancache[dir][node]
  # The old manifest may put non-ctx manifests in the cache, so
  # skip those since they don't implement the full api.
  if (isinstance(cachemf, manifestctx) or
@@ -1059,8 +1066,13 @@ class manifestlog(object):
  m = treemanifestctx(self._revlog, '', node)
  else:
  m = manifestctx(self._revlog, node)
-if node != revlog.nullid:
-self._mancache[node] = m
+
+if node != revlog.nullid:
+mancache = self._dirmancache.get(dir)
+if not mancache:
+mancache = util.lrucachedict(self.cachesize)
+self._dirmancache[dir] = mancache
+mancache[node] = m
  return m
  
  def add(self, m, transaction, link, p1, p2, added, removed):

___
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=DQIGaQ=5VD0RTtNlTh3ycd41b3MUw=nuarHzhP1wi1T9iURRCj1A=VLB2IFCfd1hwkNj48uX3kSd5dnDqItOdYqexb8hkHao=aJp4DUf7hp6QQ0EuIT3P_I_LQ9qrcccsIM9km8X18o8=


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


[PATCH 3 of 3 v3] dispatch: make hg --profile wrap reposetup

2016-09-20 Thread Arun Kulshreshtha
# HG changeset patch
# User Arun Kulshreshtha 
# Date 1474318006 25200
#  Mon Sep 19 13:46:46 2016 -0700
# Node ID f157d9becfe724d624e0f3328febe58c5694d950
# Parent  0bb030bb1ce94c5514b671a3900ba207ebb19269
dispatch: make hg --profile wrap reposetup

Add profiling to _dispatch so that reposetup is included in the profiler
output. All existing usage of the profiling context manager has been preserved,
so the existing behavior of profiling enabled after reposetup will not be
affected.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -844,7 +844,7 @@
 elif not cmd:
 return commands.help_(ui, 'shortlist')
 
-if True:
+with profiling.maybeprofile(ui):
 repo = None
 cmdpats = args[:]
 if not _cmdattr(ui, cmd, func, 'norepo'):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 v3] profiling: allow nested usage of profile context manager

2016-09-20 Thread Arun Kulshreshtha
# HG changeset patch
# User Arun Kulshreshtha 
# Date 1474402733 25200
#  Tue Sep 20 13:18:53 2016 -0700
# Node ID 69499ec91691f952a8a28092c361a0e3daccc429
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
profiling: allow nested usage of profile context manager

Add a check to the profile context manager to ensure that profiling
is only enabled once in nested invocations of this context manager.
The flag to guard against nesting is stored in thead-local storage,
so this only prevents nested usage within the same thread. (i.e.,
if a thread is spawned while profiling is active, the child thread
is also able to enable profiling.)

diff --git a/mercurial/profiling.py b/mercurial/profiling.py
--- a/mercurial/profiling.py
+++ b/mercurial/profiling.py
@@ -10,6 +10,7 @@
 import contextlib
 import os
 import sys
+import threading
 import time
 
 from .i18n import _
@@ -108,6 +109,22 @@
 Profiling is active when the context manager is active. When the context
 manager exits, profiling results will be written to the configured output.
 """
+
+# Initialize thread-local storage for profiling.
+if not util.safehasattr(profile, 'threadlocal'):
+profile.threadlocal = threading.local()
+
+# Flag attribute will be re-initialized in each new thread.
+if not util.safehasattr(profile.threadlocal, 'started'):
+profile.threadlocal.started = False
+
+# Guard against nested invocations of this context manager within
+# the same thread. Only the outermost invocation will run.
+if profile.threadlocal.started:
+yield
+return
+profile.threadlocal.started = True
+
 profiler = os.getenv('HGPROF')
 if profiler is None:
 profiler = ui.config('profiling', 'type', default='ls')
@@ -145,6 +162,7 @@
 val = val.replace('%', '%%')
 ui.log('profile', val)
 fp.close()
+profile.threadlocal.started = False
 
 @contextlib.contextmanager
 def maybeprofile(ui):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 v3] dispatch: change indentation level in _dispatch()

2016-09-20 Thread Arun Kulshreshtha
# HG changeset patch
# User Arun Kulshreshtha 
# Date 1474324457 25200
#  Mon Sep 19 15:34:17 2016 -0700
# Node ID 0bb030bb1ce94c5514b671a3900ba207ebb19269
# Parent  69499ec91691f952a8a28092c361a0e3daccc429
dispatch: change indentation level in _dispatch()

Add an if True: placeholder for a profiling context manager that
will be added in the next commit, for the purpose of reducing size
of the diff due to trivial indentation changes.

This change should be a no-op.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -844,60 +844,63 @@
 elif not cmd:
 return commands.help_(ui, 'shortlist')
 
-repo = None
-cmdpats = args[:]
-if not _cmdattr(ui, cmd, func, 'norepo'):
-# use the repo from the request only if we don't have -R
-if not rpath and not cwd:
-repo = req.repo
+if True:
+repo = None
+cmdpats = args[:]
+if not _cmdattr(ui, cmd, func, 'norepo'):
+# use the repo from the request only if we don't have -R
+if not rpath and not cwd:
+repo = req.repo
 
-if repo:
-# set the descriptors of the repo ui to those of ui
-repo.ui.fin = ui.fin
-repo.ui.fout = ui.fout
-repo.ui.ferr = ui.ferr
-else:
-try:
-repo = hg.repository(ui, path=path)
-if not repo.local():
-raise error.Abort(_("repository '%s' is not local") % path)
-repo.ui.setconfig("bundle", "mainreporoot", repo.root, 'repo')
-except error.RequirementError:
-raise
-except error.RepoError:
-if rpath and rpath[-1]: # invalid -R path
+if repo:
+# set the descriptors of the repo ui to those of ui
+repo.ui.fin = ui.fin
+repo.ui.fout = ui.fout
+repo.ui.ferr = ui.ferr
+else:
+try:
+repo = hg.repository(ui, path=path)
+if not repo.local():
+raise error.Abort(_("repository '%s' is not local")
+% path)
+repo.ui.setconfig("bundle", "mainreporoot", repo.root,
+  'repo')
+except error.RequirementError:
 raise
-if not _cmdattr(ui, cmd, func, 'optionalrepo'):
-if (_cmdattr(ui, cmd, func, 'inferrepo') and
-args and not path):
-# try to infer -R from command args
-repos = map(cmdutil.findrepo, args)
-guess = repos[0]
-if guess and repos.count(guess) == len(repos):
-req.args = ['--repository', guess] + fullargs
-return _dispatch(req)
-if not path:
-raise error.RepoError(_("no repository found in '%s'"
-" (.hg not found)")
-  % os.getcwd())
-raise
-if repo:
-ui = repo.ui
-if options['hidden']:
-repo = repo.unfiltered()
-args.insert(0, repo)
-elif rpath:
-ui.warn(_("warning: --repository ignored\n"))
+except error.RepoError:
+if rpath and rpath[-1]: # invalid -R path
+raise
+if not _cmdattr(ui, cmd, func, 'optionalrepo'):
+if (_cmdattr(ui, cmd, func, 'inferrepo') and
+args and not path):
+# try to infer -R from command args
+repos = map(cmdutil.findrepo, args)
+guess = repos[0]
+if guess and repos.count(guess) == len(repos):
+req.args = ['--repository', guess] + fullargs
+return _dispatch(req)
+if not path:
+raise error.RepoError(_("no repository found in"
+" '%s' (.hg not found)")
+  % os.getcwd())
+raise
+if repo:
+ui = repo.ui
+if options['hidden']:
+repo = repo.unfiltered()
+args.insert(0, repo)
+elif rpath:
+ui.warn(_("warning: --repository ignored\n"))
 
-msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
-ui.log("command", '%s\n', msg)
-d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
-try:
-return runcommand(lui, repo, cmd, 

[Bug 5374] New: revsets: add around(set, depth) and extend ancestors(set[, depth]) / descendants(set[, depth])

2016-09-20 Thread bugzilla
https://bz.mercurial-scm.org/show_bug.cgi?id=5374

Bug ID: 5374
   Summary: revsets: add around(set, depth) and extend
ancestors(set[, depth]) / descendants(set[, depth])
   Product: Mercurial
   Version: unspecified
  Hardware: PC
OS: Windows
Status: UNCONFIRMED
  Severity: feature
  Priority: wish
 Component: Mercurial
  Assignee: bugzi...@selenic.com
  Reporter: timel...@gmail.com
CC: mercurial-de...@selenic.com

When investigating (hg log -G, hg bisect, ...) it's common to have a sense of
what an interesting commit is, but want to see what's around it (ancestors to
some depth, descendants to some depth).

We propose to add:
around(set, depth) -- which will include all* changesets which are
ancestors/descendants of a changeset in set

and add an optional argument depth to ancestors(set) and descendants(set) as:
ancestors(set[, depth]) -- will include depth levels of ancestors of changesets
in set
descendants(set[, depth]) -- will include depth levels of descendants of
changesets in set

ancestors(set, 0) == set
descendants(set, 0) == set
around(set, 0) == set
around(set, 1) = ancestors(set, 1) + descendants(set, 1)

-- 
You are receiving this mail because:
You are on the CC list for the bug.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9 V3] manifest: add shallow option to treemanifestctx.readdelta and readfast

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID f778e735327d24c3ced233c206acb11f65f55ea0
# Parent  22915866409350cbb5302289c05bb65bc1bfd308
manifest: add shallow option to treemanifestctx.readdelta and readfast

The old manifest had different functions for performing shallow reads, shallow
readdeltas, and shallow readfasts. Since a lot of the code is duplicate (and
since those functions don't make sense on a normal manifestctx), let's unify
them into flags on the existing readdelta and readfast functions.

A future diff will change consumers of these functions to use the manifestctx
versions and will delete the old apis.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1109,7 +1109,7 @@ class manifestctx(object):
 self._data = manifestdict(text)
 return self._data
 
-def readfast(self):
+def readfast(self, shallow=False):
 rl = self._revlog
 r = rl.rev(self._node)
 deltaparent = rl.deltaparent(r)
@@ -1117,7 +1117,7 @@ class manifestctx(object):
 return self.readdelta()
 return self.read()
 
-def readdelta(self):
+def readdelta(self, shallow=False):
 revlog = self._revlog
 if revlog._usemanifestv2:
 # Need to perform a slow delta
@@ -1176,27 +1176,40 @@ class treemanifestctx(object):
 def node(self):
 return self._node
 
-def readdelta(self):
-# Need to perform a slow delta
+def readdelta(self, shallow=False):
 revlog = self._revlog
-r0 = revlog.deltaparent(revlog.rev(self._node))
-m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
-m1 = self.read()
-md = treemanifest(dir=self._dir)
-for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
-if n1:
-md[f] = n1
-if fl1:
-md.setflag(f, fl1)
-return md
+if shallow and revlog._treeondisk and not revlog._usemanifestv2:
+if revlog._usemanifestv2:
+raise error.Abort(
+_("shallow readdelta() not implemented for manifestv2"))
+r = revlog.rev(self._node)
+d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
+return manifestdict(d)
+else:
+# Need to perform a slow delta
+r0 = revlog.deltaparent(revlog.rev(self._node))
+m0 = treemanifestctx(revlog, revlog.node(r0), dir=self._dir).read()
+m1 = self.read()
+md = treemanifest(dir=self._dir)
+for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
+if n1:
+md[f] = n1
+if fl1:
+md.setflag(f, fl1)
+return md
 
-def readfast(self):
+def readfast(self, shallow=False):
 rl = self._revlog
 r = rl.rev(self._node)
 deltaparent = rl.deltaparent(r)
-if deltaparent != revlog.nullrev and deltaparent in rl.parentrevs(r):
-return self.readdelta()
-return self.read()
+if (deltaparent != revlog.nullrev and
+deltaparent in rl.parentrevs(r)):
+return self.readdelta(shallow=shallow)
+
+if shallow:
+return manifestdict(rl.revision(self._node))
+else:
+return self.read()
 
 class manifest(manifestrevlog):
 def __init__(self, opener, dir='', dirlogcache=None):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 9 V3] manifest: get rid of manifest.readshallowfast

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 779f5d98d41c0deac2bc6fe679896344e1dd04e9
# Parent  f778e735327d24c3ced233c206acb11f65f55ea0
manifest: get rid of manifest.readshallowfast

This removes manifest.readshallowfast and converts it's one user to use
manifestlog instead.

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -674,7 +674,8 @@ class cg1packer(object):
 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
   fnodes):
 repo = self._repo
-dirlog = repo.manifest.dirlog
+mfl = repo.manifestlog
+dirlog = mfl._revlog.dirlog
 tmfnodes = {'': mfs}
 
 # Callback for the manifest, used to collect linkrevs for filelog
@@ -702,7 +703,7 @@ class cg1packer(object):
 treemanifests to send.
 """
 clnode = tmfnodes[dir][x]
-mdata = dirlog(dir).readshallowfast(x)
+mdata = mfl.get(dir, x).readfast(shallow=True)
 for p, n, fl in mdata.iterentries():
 if fl == 't': # subdirectory manifest
 subdir = dir + p + '/'
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1281,15 +1281,6 @@ class manifest(manifestrevlog):
 d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
 return manifestdict(d)
 
-def readshallowfast(self, node):
-'''like readfast(), but calls readshallowdelta() instead of readdelta()
-'''
-r = self.rev(node)
-deltaparent = self.deltaparent(r)
-if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r):
-return self.readshallowdelta(node)
-return self.readshallow(node)
-
 def read(self, node):
 if node == revlog.nullid:
 return self._newmanifest() # don't upset local cache
@@ -1316,13 +1307,6 @@ class manifest(manifestrevlog):
 self.fulltextcache[node] = arraytext
 return m
 
-def readshallow(self, node):
-'''Reads the manifest in this directory. When using flat manifests,
-this manifest will generally have files in subdirectories in it. Does
-not cache the manifest as the callers generally do not read the same
-version twice.'''
-return manifestdict(self.revision(node))
-
 def find(self, node, f):
 '''look up entry for a single file efficiently.
 return (node, flags) pair if found, (None, None) if not.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 9 V3] manifest: add manifestlog.get to obtain subdirectory instances

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 52a206d772021194ab4356aeba2c73650851a624
# Parent  8cf5f24c100e58ece712703d0e4bb0746bc3087e
manifest: add manifestlog.get to obtain subdirectory instances

Previously manifestlog only allowed obtaining root level manifests. Future
patches will need direct access to subdirectory manifests as part of changegroup
creation, so let's add a get() function that knows how to deal with
subdirectories.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1033,20 +1033,34 @@ class manifestlog(object):
 """Retrieves the manifest instance for the given node. Throws a 
KeyError
 if not found.
 """
-if node in self._mancache:
-cachemf = self._mancache[node]
-# The old manifest may put non-ctx manifests in the cache, so skip
-# those since they don't implement the full api.
-if (isinstance(cachemf, manifestctx) or
-isinstance(cachemf, treemanifestctx)):
-return cachemf
+return self.get('', node)
 
-if self._treeinmem:
-m = treemanifestctx(self._revlog, '', node)
+def get(self, dir, node):
+"""Retrieves the manifest instance for the given node. Throws a 
KeyError
+if not found.
+"""
+if dir:
+if self._revlog._treeondisk:
+m = treemanifestctx(self._revlog.dirlog(dir), dir, node)
+else:
+raise error.Abort(
+_("cannot ask for manifest directory '%s' in a flat "
+  "manifest") % dir)
 else:
-m = manifestctx(self._revlog, node)
-if node != revlog.nullid:
-self._mancache[node] = m
+if node in self._mancache:
+cachemf = self._mancache[node]
+# The old manifest may put non-ctx manifests in the cache, so
+# skip those since they don't implement the full api.
+if (isinstance(cachemf, manifestctx) or
+isinstance(cachemf, treemanifestctx)):
+return cachemf
+
+if self._treeinmem:
+m = treemanifestctx(self._revlog, '', node)
+else:
+m = manifestctx(self._revlog, node)
+if node != revlog.nullid:
+self._mancache[node] = m
 return m
 
 def add(self, m, transaction, link, p1, p2, added, removed):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9 V3] manifest: move treeinmem onto manifestlog

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 952e434dd3b51dfdfbfd370dfa85f66929757be0
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
manifest: move treeinmem onto manifestlog

A previous patched moved all the serialization related options onto
manifestrevlog (since it is responsible for serialization). Let's move the
treeinmem option on manifestlog, since it is responsible for materialization
decisions. This reduces the number of dependencies manifestlog has on the old
manifest type as well, so we can eventually make them completely independent of
each other.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -957,6 +957,13 @@ class manifestlog(object):
 def __init__(self, opener, repo):
 self._repo = repo
 
+usetreemanifest = False
+
+opts = getattr(opener, 'options', None)
+if opts is not None:
+usetreemanifest = opts.get('treemanifest', usetreemanifest)
+self._treeinmem = usetreemanifest
+
 # We'll separate this into it's own cache once oldmanifest is no longer
 # used
 self._mancache = repo.manifest._mancache
@@ -965,13 +972,6 @@ class manifestlog(object):
 def _revlog(self):
 return self._repo.manifest
 
-@property
-def _oldmanifest(self):
-# _revlog is the same as _oldmanifest right now, but we eventually want
-# to delete _oldmanifest while still allowing manifestlog to access the
-# revlog specific apis.
-return self._repo.manifest
-
 def __getitem__(self, node):
 """Retrieves the manifest instance for the given node. Throws a 
KeyError
 if not found.
@@ -984,7 +984,7 @@ class manifestlog(object):
 isinstance(cachemf, treemanifestctx)):
 return cachemf
 
-if self._oldmanifest._treeinmem:
+if self._treeinmem:
 m = treemanifestctx(self._revlog, '', node)
 else:
 m = manifestctx(self._revlog, node)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 9 of 9 V3] manifest: remove manifest.readshallowdelta

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 664a74404b3dc01e53e72a26023ab5c74b265f75
# Parent  779f5d98d41c0deac2bc6fe679896344e1dd04e9
manifest: remove manifest.readshallowdelta

This removes manifest.readshallowdelta and converts its one consumer to use
manifestlog instead.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1246,41 +1246,6 @@ class manifest(manifestrevlog):
   self._dirlogcache)
 return self._dirlogcache[dir]
 
-def _slowreaddelta(self, node):
-r0 = self.deltaparent(self.rev(node))
-m0 = self.read(self.node(r0))
-m1 = self.read(node)
-md = self._newmanifest()
-for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
-if n1:
-md[f] = n1
-if fl1:
-md.setflag(f, fl1)
-return md
-
-def readdelta(self, node):
-if self._usemanifestv2 or self._treeondisk:
-return self._slowreaddelta(node)
-r = self.rev(node)
-d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
-return self._newmanifest(d)
-
-def readshallowdelta(self, node):
-'''For flat manifests, this is the same as readdelta(). For
-treemanifests, this will read the delta for this revlog's directory,
-without recursively reading subdirectory manifests. Instead, any
-subdirectory entry will be reported as it appears in the manifests, 
i.e.
-the subdirectory will be reported among files and distinguished only by
-its 't' flag.'''
-if not self._treeondisk:
-return self.readdelta(node)
-if self._usemanifestv2:
-raise error.Abort(
-_("readshallowdelta() not implemented for manifestv2"))
-r = self.rev(node)
-d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
-return manifestdict(d)
-
 def read(self, node):
 if node == revlog.nullid:
 return self._newmanifest() # don't upset local cache
diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -201,7 +201,8 @@ class verifier(object):
 progress=None):
 repo = self.repo
 ui = self.ui
-mf = self.repo.manifest.dirlog(dir)
+mf = self.repo.manifestlog._revlog.dirlog(dir)
+mfl = self.repo.manifestlog
 
 if not dir:
 self.ui.status(_("checking manifests\n"))
@@ -235,7 +236,8 @@ class verifier(object):
 self.err(lr, _("%s not in changesets") % short(n), label)
 
 try:
-for f, fn, fl in mf.readshallowdelta(n).iterentries():
+mfdelta = mfl.get(dir, n).readdelta(shallow=True)
+for f, fn, fl in mfdelta.iterentries():
 if not f:
 self.err(lr, _("entry without name in manifest"))
 elif f == "/dev/null":  # ignore this in very old repos
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9 V3] manifest: move manifest.add onto manifestrevlog

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 7df972d2d43fe655ffcfdef9e2efedda8a684af8
# Parent  4226fad2f4df52579581bab6cc6111e243b8000d
manifest: move manifest.add onto manifestrevlog

This moves add and _addtree onto manifestrevlog. manifestrevlog is responsible
for all serialization decisions, so therefore the add function should live on
it. This will allow us to call add() from manifestlog, which let's us further
break our dependency on manifest.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -946,6 +946,63 @@ class manifestrevlog(revlog.revlog):
 self._dirlogcache)
 return self._dirlogcache[dir]
 
+def add(self, m, transaction, link, p1, p2, added, removed):
+if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
+and not self._usemanifestv2):
+# If our first parent is in the manifest cache, we can
+# compute a delta here using properties we know about the
+# manifest up-front, which may save time later for the
+# revlog layer.
+
+_checkforbidden(added)
+# combine the changed lists into one sorted iterator
+work = heapq.merge([(x, False) for x in added],
+   [(x, True) for x in removed])
+
+arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
+cachedelta = self.rev(p1), deltatext
+text = util.buffer(arraytext)
+n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
+else:
+# The first parent manifest isn't already loaded, so we'll
+# just encode a fulltext of the manifest and pass that
+# through to the revlog layer, and let it handle the delta
+# process.
+if self._treeondisk:
+m1 = self.read(p1)
+m2 = self.read(p2)
+n = self._addtree(m, transaction, link, m1, m2)
+arraytext = None
+else:
+text = m.text(self._usemanifestv2)
+n = self.addrevision(text, transaction, link, p1, p2)
+arraytext = array.array('c', text)
+
+self.fulltextcache[n] = arraytext
+
+return n
+
+def _addtree(self, m, transaction, link, m1, m2):
+# If the manifest is unchanged compared to one parent,
+# don't write a new revision
+if m.unmodifiedsince(m1) or m.unmodifiedsince(m2):
+return m.node()
+def writesubtree(subm, subp1, subp2):
+sublog = self.dirlog(subm.dir())
+sublog.add(subm, transaction, link, subp1, subp2, None, None)
+m.writesubtrees(m1, m2, writesubtree)
+text = m.dirtext(self._usemanifestv2)
+# Double-check whether contents are unchanged to one parent
+if text == m1.dirtext(self._usemanifestv2):
+n = m1.node()
+elif text == m2.dirtext(self._usemanifestv2):
+n = m2.node()
+else:
+n = self.addrevision(text, transaction, link, m1.node(), m2.node())
+# Save nodeid so parent manifest can calculate its nodeid
+m.setnode(n)
+return n
+
 class manifestlog(object):
 """A collection class representing the collection of manifest snapshots
 referenced by commits in the repository.
@@ -1233,64 +1290,6 @@ class manifest(manifestrevlog):
 except KeyError:
 return None, None
 
-def add(self, m, transaction, link, p1, p2, added, removed):
-if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
-and not self._usemanifestv2):
-# If our first parent is in the manifest cache, we can
-# compute a delta here using properties we know about the
-# manifest up-front, which may save time later for the
-# revlog layer.
-
-_checkforbidden(added)
-# combine the changed lists into one sorted iterator
-work = heapq.merge([(x, False) for x in added],
-   [(x, True) for x in removed])
-
-arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
-cachedelta = self.rev(p1), deltatext
-text = util.buffer(arraytext)
-n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
-else:
-# The first parent manifest isn't already loaded, so we'll
-# just encode a fulltext of the manifest and pass that
-# through to the revlog layer, and let it handle the delta
-# process.
-if self._treeondisk:
-m1 = self.read(p1)
-m2 = self.read(p2)
-n = self._addtree(m, transaction, link, m1, m2)
-arraytext 

[PATCH 4 of 9 V3] manifest: add manifestlog.add

2016-09-20 Thread Durham Goode
# HG changeset patch
# User Durham Goode 
# Date 1474399441 25200
#  Tue Sep 20 12:24:01 2016 -0700
# Node ID 8cf5f24c100e58ece712703d0e4bb0746bc3087e
# Parent  7df972d2d43fe655ffcfdef9e2efedda8a684af8
manifest: add manifestlog.add

This adds a simple add() function to manifestlog. This let's us convert more
uses of repo.manifest to use repo.manifestlog, so we can further break our
dependency on the manifest class.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1732,9 +1732,9 @@ class localrepository(object):
 drop = [f for f in removed if f in m]
 for f in drop:
 del m[f]
-mn = self.manifest.add(m, trp, linkrev,
-   p1.manifestnode(), p2.manifestnode(),
-   added, drop)
+mn = self.manifestlog.add(m, trp, linkrev,
+  p1.manifestnode(), p2.manifestnode(),
+  added, drop)
 files = changed + removed
 else:
 mn = p1.manifestnode()
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1049,6 +1049,9 @@ class manifestlog(object):
 self._mancache[node] = m
 return m
 
+def add(self, m, transaction, link, p1, p2, added, removed):
+return self._revlog.add(m, transaction, link, p1, p2, added, removed)
+
 class manifestctx(object):
 """A class representing a single revision of a manifest, including its
 contents, its parent revs, and its linkrev.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 5 of 8] manifest: add manifestlog.get to obtain subdirectory instances

2016-09-20 Thread Durham Goode



On 9/15/16 11:23 AM, Martin von Zweigbergk wrote:

On Wed, Sep 14, 2016 at 4:04 PM, Durham Goode  wrote:

# HG changeset patch
# User Durham Goode 
# Date 1473893509 25200
#  Wed Sep 14 15:51:49 2016 -0700
# Node ID 33a7df42b989c555972280f6b84e2fac38babf7b
# Parent  d41da1522f8efb5bf5aa75a51f0093b1129b6b5a
manifest: add manifestlog.get to obtain subdirectory instances

Previously manifestlog only allowed obtaining root level manifests. Future
patches will need direct access to subdirectory manifests as part of changegroup
creation, so let's add a get() function that knows how to deal with
subdirectories.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -1040,20 +1040,34 @@ class manifestlog(object):
  """Retrieves the manifest instance for the given node. Throws a 
KeyError
  if not found.
  """
-if node in self._mancache:
-cachemf = self._mancache[node]
-# The old manifest may put non-ctx manifests in the cache, so skip
-# those since they don't implement the full api.
-if (isinstance(cachemf, manifestctx) or
-isinstance(cachemf, treemanifestctx)):
-return cachemf
+return self.get('', node)

-if self._treeinmem:
-m = treemanifestctx(self._revlog, '', node)
+def get(self, dir, node):
+"""Retrieves the manifest instance for the given node. Throws a 
KeyError
+if not found.
+"""
+if dir:
+if self._treeinmem:
+m = treemanifestctx(self._revlog.dirlog(dir), dir, node)

This does not use the _mancache and there doesn't seem to be a
_mancache on the revlog either. I've forgotten whether or not you plan
to have one manifestlog per repo or per directory, but I think you
said per repo. So it seems like only the root directory manifests will
be cached at this point. Am I reading that right? Perhaps you're
fixing that later, but even then it seems like an unfortunate
transitional step to lose it here.

You are right.  I'll send a new series with a patch (immediately after 
this patch) that changes the manifestlog's cache to have an entry per tree.

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


Re: [PATCH 3 of 3 v2] dispatch: make hg --profile wrap reposetup

2016-09-20 Thread Arun Kulshreshtha



On 9/20/16, 6:01 AM, "Yuya Nishihara"  wrote:

On Mon, 19 Sep 2016 16:13:58 -0700, Arun Kulshreshtha wrote:
> # HG changeset patch
> # User Arun Kulshreshtha 
> # Date 1474318006 25200
> #  Mon Sep 19 13:46:46 2016 -0700
> # Node ID 20af15cac045b249aece42cb71b671302b6c314c
> # Parent  6f33cc84cdd6c9ab38d32784505b6fb53bf3eba9
> dispatch: make hg --profile wrap reposetup
> 
> Add profiling to _dispatch so that reposetup is included in the profiler
> output. All existing usage of the profiling context manager has been 
preserved,
> so the existing behavior of profiling enabled after reposetup will not be
> affected.
> 
> diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
> --- a/mercurial/dispatch.py
> +++ b/mercurial/dispatch.py
> @@ -844,7 +844,7 @@
>  elif not cmd:
>  return commands.help_(ui, 'shortlist')
>  
> -if True:
> +with profiling.maybeprofile(ui):
>  repo = None
>  cmdpats = args[:]
>  if not _cmdattr(ui, cmd, func, 'norepo'):

Any reason to not remove maybeprofile() from _runcommand() ? Can it be 
enabled
after reposetup() ?

Yes, if it is configured in the repo-specific settings (.hg/hgrc), for example, 
then it would be missed if
maybeprofile were removed from _runcommand(). Additionally, we’d need to wrap 
other callsites of
_runcommand(), such as _checkshellalias(), to maintain the existing behavior.

(Resending this because I didn’t CC the list; sorry for the duplicate message.)



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


Re: [PATCH] rebase: rebase changesets with branch grouped

2016-09-20 Thread Pierre-Yves David



On 09/17/2016 09:11 AM, Xidorn Quan wrote:

# HG changeset patch
# User Xidorn Quan 
# Date 1474095776 -36000
#  Sat Sep 17 17:02:56 2016 +1000
# Node ID 88184dc23ccacfc8ae450abc5d574b8b028bca79
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
rebase: rebase changesets with branch grouped


This description good get a bit better

- reference the issue you create on the tacker by adding "(issue###)" to 
the first line,
- add a "(BC)" flag, even if this is small and useful change, this is a 
change to backward compatibility.
- explain why this change is a good idea. Your rational in the bug 
report was good, just include them there.




diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -330,18 +330,38 @@ class rebaseruntime(object):
inclusive=True)

 # Keep track of the current bookmarks in order to reset them later
 self.currentbookmarks = repo._bookmarks.copy()
 self.activebookmark = self.activebookmark or repo._activebookmark
 if self.activebookmark:
 bookmarks.deactivate(repo)

-sortedrevs = sorted(self.state)
+# Sort revisions with branches grouped
 cands = [k for k, v in self.state.iteritems() if v == revtodo]
+remainrevs = set(self.state.iterkeys())
+sortedrevs = []
+# Sort based on candidates and put their ancestors with them
+for cand in util.branchsorted(repo, cands):
+ancestors = [cand]
+remainrevs.remove(cand)
+i = 0
+while i < len(ancestors):
+ctx = repo[ancestors[i]]
+for p in ctx.parents():
+prev = p.rev()
+if prev in remainrevs:
+remainrevs.remove(prev)
+ancestors.append(prev)
+i += 1
+ancestors.reverse()
+sortedrevs.extend(ancestors)
+# Finally, descendents which are not rebased
+sortedrevs.extend(sorted(remainrevs))
+


As Martin pointed, we have already have topological function in core. 
The "official" way to access it is through revset. Something like the 
following line should do (might need adjustment)


sortedrevs = repo.revs("reverse(sort( %ld, "topo"))", revs)


 total = len(cands)
 pos = 0
 for rev in sortedrevs:
 ctx = repo[rev]
 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
ctx.description().split('\n', 1)[0])
 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
 if names:
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -2897,8 +2897,33 @@ decompressors = {None: lambda fh: fh,
  'BZ': _makedecompressor(lambda: bz2.BZ2Decompressor()),
  'GZ': _makedecompressor(lambda: zlib.decompressobj()),
  }
 # also support the old form by courtesies
 decompressors['UN'] = decompressors[None]

 # convenient shortcut
 dst = debugstacktrace
+
+def branchsorted(repo, revs, sortrevs=None):
+'''Returns a sorted list of revisions in a order that branches are
+grouped together.'''
+remainrevs = set(revs)
+stack = [sorted(revs, reverse=True)]
+result = []
+while stack:
+stacktop = stack[-1]
+if not stacktop:
+stack.pop()
+continue
+nextrev = stacktop.pop()
+if nextrev not in remainrevs:
+continue
+ctx = repo[nextrev]
+# If any of its parents is still in remainrevs, we can not put
+# the changeset into result. We would traverse to it again when
+# we resolve all its parents.
+if any(p.rev() in remainrevs for p in ctx.parents()):
+continue
+remainrevs.remove(nextrev)
+result.append(nextrev)
+stack.append(sorted((c.rev() for c in ctx.children()), reverse=True))
+return result
diff --git a/tests/test-rebase-branch-order.t b/tests/test-rebase-branch-order.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-branch-order.t


Please do not introduce a new test file for such a small extra test 
(each test file have a slight overhead). Find and existing rebase test 
file where it would make sense to add the extra bits to tests this.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 7] manifest: use specific opener to avoid file stat ambiguity around truncation

2016-09-20 Thread Pierre-Yves David



On 09/16/2016 10:51 PM, FUJIWARA Katsunori wrote:

# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1474057496 -32400
#  Sat Sep 17 05:24:56 2016 +0900
# Node ID 55bd90d63ad3a76fd4d27d5eabb3fe9a7fa0642b
# Parent  71b6b49f8a7ab6c894028b9153290f4bbf0f54f6
manifest: use specific opener to avoid file stat ambiguity around truncation

If steps below occurs at "the same time in sec", all of mtime, ctime
and size are same between (1) and (3).

  1. append data to 00manifest.i (and close transaction)
  2. discard appended data by truncation (strip or rollback)
  3. append same size but different data to 00manifest.i again

Therefore, cache validation doesn't work after (3) as expected.

To avoid such file stat ambiguity around truncation, this patch uses
specific opener, which forces checkambig=True at writing 00manifest.i
changes out.

Hooking vfs.__call__() is the only way to centralize changes into
manifest.py, because all logic to actually write in-memory changes out
is implemented in revlog layer.

In fact, reusing already wrapped self.opener for dirlogcache entries
like as below is a little redundant, because storecache-ed properties
of localrepository doesn't refer file stat of non-root 00manifest.i
files (= ambiguity of such files doesn't cause any issue).

if dir not in self._dirlogcache:
self._dirlogcache[dir] = manifestrevlog(self.opener, dir,
self._dirlogcache)

But wrapped opener never checks ambiguity of file stat for non-root
00manifest.i files, because "path == '00manifest.i'" condition in
wrapper.__call__() is always False for such files. Therefore, this
patch simply reuses wrapped self.opener for non-root 00manifest.i
files.

Even after this patch, avoiding file stat ambiguity of 00manifest.i
around truncation isn't yet completed, because truncation side isn't
aware of this issue.

This is a part of ExactCacheValidationPlan.

https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -892,6 +892,28 @@ class treemanifest(object):
 subp1, subp2 = subp2, subp1
 writesubtree(subm, subp1, subp2)

+def _checkambigopener(opener):
+"""build an opener to add checkambig=True at changing 00manifest.i
+"""
+class wrapper(opener.__class__):
+def __call__(self, path, mode="r", text=False, atomictemp=False,
+ notindexed=False, backgroundclose=False, checkambig=False,
+  **kwargs):
+if path == '00manifest.i' and mode not in ('r', 'rb'):
+# check file stat ambiguity at closing forcibly
+checkambig = True
+supercall = super(wrapper, self).__call__
+return supercall(path, mode,
+ text=text,
+ atomictemp=atomictemp,
+ notindexed=notindexed,
+ backgroundclose=backgroundclose,
+ checkambig=checkambig,
+ **kwargs)
+opener.__class__ = wrapper


This wrapper logic is a bit scary here. Could we  had the necessary 
minimal hooks in revlog to allow manifest and changelog to hooks in ? 
That would seems more robust/clean than wrapping core from core.



+
+return opener
+
 class manifestrevlog(revlog.revlog):
 '''A revlog that stores manifest texts. This is responsible for caching the
 full-text manifest contents.
@@ -927,6 +949,13 @@ class manifestrevlog(revlog.revlog):
 else:
 self._dirlogcache = {'': self}

+# If "dir" isn't empty, this "opener" is reused one via
+# "self.opener" of another manifestrevlog. Therefore,
+# wrapping opener is needed only at once for root
+# 00manifest.i file, to avoid multiple (= redundant)
+# wrapping.
+opener = _checkambigopener(opener)
+
 super(manifestrevlog, self).__init__(opener, indexfile)

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



--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 7] vfs: use checkambigatclosing in checkambig=True but atomictemp=False case

2016-09-20 Thread Pierre-Yves David



On 09/16/2016 10:51 PM, FUJIWARA Katsunori wrote:

# HG changeset patch
# User FUJIWARA Katsunori 
# Date 1474057495 -32400
#  Sat Sep 17 05:24:55 2016 +0900
# Node ID 71b6b49f8a7ab6c894028b9153290f4bbf0f54f6
# Parent  ad999fb789fcb86b11c98334ab98b31a17ee2d25
vfs: use checkambigatclosing in checkambig=True but atomictemp=False case

In Mercurial source tree, opening a file in "a"/"a+" mode like below
doesn't specify atomictemp=True for vfs, and this avoids file stat
ambiguity check by atomictempfile.

  - writing changes out in revlog layer uses "a+" mode
  - truncation in repair.strip() uses "a" mode
  - truncation in transaction._playback() uses "a" mode

If steps below occurs at "the same time in sec", all of mtime, ctime
and size are same between (1) and (3).

  1. append data to revlog-style file (and close transaction)
  2. discard appended data by truncation (strip or rollback)
  3. append same size but different data to revlog-style file again

Therefore, cache validation doesn't work after (3) as expected.

This patch uses checkambigatclosing in checkambig=True but
atomictemp=False case, to check (and get rid of) file stat ambiguity
at closing.

This is a part of ExactCacheValidationPlan.

https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -587,6 +587,10 @@ class vfs(abstractvfs):
 if nlink == 0:
 self._fixfilemode(f)

+if checkambig:
+assert mode not in ('r', 'rb'), "valid only at writing"
+fp = checkambigatclosing(fp)


It sound a bit too much like a real logic check with assert. Instead we 
should probably either:

- have a hard check with an abort.
- ignore the bad state with a devel warning (probably the best).

Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] templates: add built-in fileset() function

2016-09-20 Thread Hannes Oldenburg
# HG changeset patch
# User Hannes Oldenburg 
# Date 1474379333 0
#  Tue Sep 20 13:48:53 2016 +
# Node ID cf2156395bff0e3fc4a6604b8aa45b5b7829ba98
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
templates: add built-in fileset() function

We already support multiple primitive for listing files, which were
affected by the current changeset.
This patch adds fileset() which runs a fileset query with the current
changeset.

diff -r 285a8c3e53f2 -r cf2156395bff mercurial/help/templates.txt
--- a/mercurial/help/templates.txt  Tue May 03 13:36:12 2016 +0900
+++ b/mercurial/help/templates.txt  Tue Sep 20 13:48:53 2016 +
@@ -95,6 +95,10 @@
 
$ hg log -r 0 --template "files: {join(files, ', ')}\n"
 
+- Join the list of files with .py ending Filesets
+
+   $ hg log -r 0 --template "pythonfiles: {join(fileset('**.py'), ', ')}\n"
+
 - Separate non-empty arguments by a " "::
 
$ hg log -r 0 --template "{separate(' ', node, bookmarks, tags}\n"
diff -r 285a8c3e53f2 -r cf2156395bff mercurial/templater.py
--- a/mercurial/templater.pyTue May 03 13:36:12 2016 +0900
+++ b/mercurial/templater.pyTue Sep 20 13:48:53 2016 +
@@ -699,6 +699,24 @@
 tzoffset = util.makedate()[1]
 return (date[0], tzoffset)
 
+@templatefunc('fileset(query)')
+def fileset(context, mapping, args):
+"""Execute a fileset set query with the current changeset. See
+:hg:`help fileset`."""
+if not len(args) == 1:
+# i18n: "revset" is a keyword
+raise error.ParseError(_("fileset expects no arguments"))
+
+raw = evalstring(context, mapping, args[0])
+ctx = mapping['ctx']
+filesetcache = mapping['cache'].setdefault("filesetcache", {})
+if raw in filesetcache:
+files  = filesetcache[raw]
+else:
+files = ctx.getfileset(raw)
+filesetcache[raw] = files
+return templatekw.showlist("file", files, **mapping)
+
 @templatefunc('revset(query[, formatargs...])')
 def revset(context, mapping, args):
 """Execute a revision set query. See
diff -r 285a8c3e53f2 -r cf2156395bff tests/test-command-template.t
--- a/tests/test-command-template.t Tue May 03 13:36:12 2016 +0900
+++ b/tests/test-command-template.t Tue Sep 20 13:48:53 2016 +
@@ -3501,6 +3501,12 @@
   5:13207e5a10d9fd28ec424934298e176197f2c67f,
   4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
 
+Test fileset function
+
+  $ hg log -r 0 -T "{rev}\n{join(fileset('*'), '\n')}\n"
+  0
+  a
+
 Test active bookmark templating
 
   $ hg book foo
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] copy: document current behavior of 'hg cp --after'

2016-09-20 Thread Pierre-Yves David



On 09/20/2016 01:24 AM, Augie Fackler wrote:

# HG changeset patch
# User Augie Fackler 
# Date 1474319683 14400
#  Mon Sep 19 17:14:43 2016 -0400
# Node ID 0ee023b61175e76d51726a51c09af6fccf1e8846
# Parent  e40343ce9c4c4819ea5669abb3447d5c031a8270
copy: document current behavior of 'hg cp --after'

I'm about to propose an output change here, but the existing behavior
was untested!


I've pushed that one as obviously correct, the reference to amend in the 
next changesets confuses me a bit and I'll have a closer look at it later.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH v5] crecord: add an event that scrolls the selected line to the top of the screen

2016-09-20 Thread Pierre-Yves David



On 09/20/2016 05:04 PM, Nathan Goldbaum wrote:

# HG changeset patch
# User Nathan Goldbaum 
# Date 1474383830 18000
#  Tue Sep 20 10:03:50 2016 -0500
# Node ID da914962b6c3f55c3f14cd7b82a4c0204c2d6a0d
# Parent  769aee32fae0f7eb8768ea2e90780af4e9a92761
crecord: add an event that scrolls the selected line to the top of the screen

Using ctrl-l for this purpose seems to be a fairly widely used practice,
presumably following emacs. This doesn't scroll the selected line all
the way to the top of the window, instead it leaves a 3 line buffer for
context. Use curses.unctrl() to resolve keypressed to '^L' to avoid
hard-coding hexadecimal key codes.



Pushed, thanks.

I've dropped the first hunk with the new empty line.


diff -r 769aee32fae0 -r da914962b6c3 mercurial/crecord.py
--- a/mercurial/crecord.py  Mon Sep 19 09:14:35 2016 -0700
+++ b/mercurial/crecord.py  Tue Sep 20 10:03:50 2016 -0500
@@ -715,6 +715,7 @@ class curseschunkselector(object):

 self.currentselecteditem = currentitem

+
 def updatescroll(self):
 "scroll the screen to fully show the currently-selected"
 selstart = self.selecteditemstartline
@@ -1338,6 +1339,7 @@ the following are valid keystrokes:
  shift-left-arrow   [H] : go to parent header / fold selected header
   f : fold / unfold item, hiding/revealing its children
   F : fold / unfold parent item and all of its ancestors
+ ctrl-l : scroll the selected line to the top of the screen
   m : edit / resume editing the commit message
   e : edit the currently selected hunk
   a : toggle amend mode, only with commit -i
@@ -1582,6 +1584,9 @@ are you sure you want to review/edit and
 self.helpwindow()
 self.stdscr.clear()
 self.stdscr.refresh()
+elif curses.unctrl(keypressed) in ["^L"]:
+# scroll the current line to the top of the screen
+self.scrolllines(self.selecteditemstartline)

 def main(self, stdscr):
 """
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel



--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] log: drop hack to fix order of revset (issue5100)

2016-09-20 Thread Pierre-Yves David



On 09/17/2016 12:17 PM, Yuya Nishihara wrote:

# HG changeset patch
# User Yuya Nishihara 
# Date 1462253040 -32400
#  Tue May 03 14:24:00 2016 +0900
# Node ID f99625523f84eaaedf48897322d5c9f6dce64bd9
# Parent  961b53cbadd0e17b1e5e745d0e3cc582cbf6603f
# EXP-Topic revsetflag
log: drop hack to fix order of revset (issue5100)

Specify ordered=True instead.


Pushed (I've fixed the message in flight)


This patch effectively backs out c407583cf5f6. revs.sort(reverse=True)
is replaced by revs.reverse() because the matcher should no longer reorder
revisions.


Given that most expensive matching is now lazy, (so actually happening 
after the actual match call, should we drop the double reverse all entirely?


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH v5] crecord: add an event that scrolls the selected line to the top of the screen

2016-09-20 Thread Nathan Goldbaum
# HG changeset patch
# User Nathan Goldbaum 
# Date 1474383830 18000
#  Tue Sep 20 10:03:50 2016 -0500
# Node ID da914962b6c3f55c3f14cd7b82a4c0204c2d6a0d
# Parent  769aee32fae0f7eb8768ea2e90780af4e9a92761
crecord: add an event that scrolls the selected line to the top of the screen

Using ctrl-l for this purpose seems to be a fairly widely used practice,
presumably following emacs. This doesn't scroll the selected line all
the way to the top of the window, instead it leaves a 3 line buffer for
context. Use curses.unctrl() to resolve keypressed to '^L' to avoid
hard-coding hexadecimal key codes.

diff -r 769aee32fae0 -r da914962b6c3 mercurial/crecord.py
--- a/mercurial/crecord.py  Mon Sep 19 09:14:35 2016 -0700
+++ b/mercurial/crecord.py  Tue Sep 20 10:03:50 2016 -0500
@@ -715,6 +715,7 @@ class curseschunkselector(object):
 
 self.currentselecteditem = currentitem
 
+
 def updatescroll(self):
 "scroll the screen to fully show the currently-selected"
 selstart = self.selecteditemstartline
@@ -1338,6 +1339,7 @@ the following are valid keystrokes:
  shift-left-arrow   [H] : go to parent header / fold selected header
   f : fold / unfold item, hiding/revealing its children
   F : fold / unfold parent item and all of its ancestors
+ ctrl-l : scroll the selected line to the top of the screen
   m : edit / resume editing the commit message
   e : edit the currently selected hunk
   a : toggle amend mode, only with commit -i
@@ -1582,6 +1584,9 @@ are you sure you want to review/edit and
 self.helpwindow()
 self.stdscr.clear()
 self.stdscr.refresh()
+elif curses.unctrl(keypressed) in ["^L"]:
+# scroll the current line to the top of the screen
+self.scrolllines(self.selecteditemstartline)
 
 def main(self, stdscr):
 """
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH v2] lazymanifest: write a more efficient, pypy friendly version of lazymanifest

2016-09-20 Thread Augie Fackler
On Sat, Sep 17, 2016 at 08:23:36PM +0200, Maciej Fijalkowski wrote:
> This should fix the issues presented.
>
> There is one problem which is that the hash in test-rebase-detach
> changes. The way I see it is just an RNG phase-shift, but it might be
> a real bug. Some actual input will be appreciated.

It's not possibly RNG related - there's no RNG that goes into the sha1
of a node. I've added --debug to the failure in test-rebase-detach and
compared them between cpython and pypy:

cpython:
@@ -366,11 +366,24 @@


   $ hg log --rev tip --debug
-  changeset:   8:9472f4b1d736
+  changeset:   8:9472f4b1d7366902d0098aa1401e3f17cc56
   tag: tip
+  phase:   draft
+  parent:  7:02de42196ebee42ef284b6780a87cdc96e8eaab6
+  parent:  -1:
+  manifest:8:8dbdcf066a97239fde2d0dba19fcb1e699fa66d2
   user:test
   date:Thu Jan 01 00:00:00 1970 +
-  summary: Collapsed revision
+  files:   F
+  files+:  E
+  extra:   branch=default
+  extra:   rebase_source=9427d4d5af81c393e6b630129712cde8cdad5605
+  description:
+  Collapsed revision
+  * I
+  * Merge
+  * J
+


pypy:
@@ -366,11 +366,24 @@


   $ hg log --rev tip --debug
-  changeset:   8:9472f4b1d736
+  changeset:   8:122ceff3b303b13e5ca323742a8ebe589b9f8066
   tag: tip
+  phase:   draft
+  parent:  7:02de42196ebee42ef284b6780a87cdc96e8eaab6
+  parent:  -1:
+  manifest:8:09f1dc369d2667dcaeb9cf828b0fcb76bda29f33
   user:test
   date:Thu Jan 01 00:00:00 1970 +
-  summary: Collapsed revision
+  files:   F
+  files+:  E
+  extra:   branch=default
+  extra:   rebase_source=9427d4d5af81c393e6b630129712cde8cdad5605
+  description:
+  Collapsed revision
+  * I
+  * Merge
+  * J
+

Which means the manifest is hashing out differently. That suggests
there's a subtle bug in how the manifest is hashing out in the pypy
version. Adding a `hg debugdata -m 8` (which prints raw manifest
data), and this is what I get on cpython:

   $ hg debugdata -m 8
+  A\x0045f17b21388f07b8939b22052e5f3776e5246388 (esc)
+  E\x00c3b9643004a8d1c7f39b0025cefab53dc8f7dc12 (esc)
+  F\x00293a00dc38ac20f042c67ba8534eedc1b6a7ae15 (esc)
+  H\x008500189e74a9e0475e822093bc7db0d631aeb0b4 (esc)

on pypy:
   $ hg debugdata -m 8
+  A\x0045f17b21388f07b8939b22052e5f3776e5246388 (esc)
+  F\x0022bfcfd62a21a3287edbd4d656218d0f525ed76a (esc)
+  E\x00c3b9643004a8d1c7f39b0025cefab53dc8f7dc12 (esc)
+  F\x00293a00dc38ac20f042c67ba8534eedc1b6a7ae15 (esc)
+  H\x008500189e74a9e0475e822093bc7db0d631aeb0b4 (esc)


So you've got a subtle bug here where the compaction of the
lazymanifest isn't working right - probably around merging manifests
somehow. Does this give you enough to get started?

(I'd probably start debugging this by littering _lazymanifest._compact
and _lazymanifest.text with asserts until I managed to trip over the
un-sorted lines, and then backtrack from there to figure out how they
managed to survive.)

>
>
>
> On Sat, Sep 17, 2016 at 8:22 PM, Maciej Fijalkowski  wrote:
> > # HG changeset patch
> > # User Maciej Fijalkowski 
> > # Date 1473680234 -7200
> > #  Mon Sep 12 13:37:14 2016 +0200
> > # Node ID 7551f1e60b2155462d89a9571eec065e9f67debc
> > # Parent  df05c43bd1e64f1620d0b2e502f4603c1e5a8341
> > lazymanifest: write a more efficient, pypy friendly version of lazymanifest
> >
> > diff --git a/mercurial/manifest.py b/mercurial/manifest.py
> > --- a/mercurial/manifest.py
> > +++ b/mercurial/manifest.py
> > @@ -104,69 +104,297 @@
> >  _checkforbidden(files)
> >  return ''.join(lines)
> >
> > -class _lazymanifest(dict):
> > -"""This is the pure implementation of lazymanifest.
> > -
> > -It has not been optimized *at all* and is not lazy.
> > -"""
> > -
> > -def __init__(self, data):
> > -dict.__init__(self)
> > -for f, n, fl in _parse(data):
> > -self[f] = n, fl
> > -
> > -def __setitem__(self, k, v):
> > -node, flag = v
> > -assert node is not None
> > -if len(node) > 21:
> > -node = node[:21] # match c implementation behavior
> > -dict.__setitem__(self, k, (node, flag))
> > +class lazymanifestiter(object):
> > +def __init__(self, lm):
> > +self.pos = 0
> > +self.lm = lm
> >
> >  def __iter__(self):
> > -return iter(sorted(dict.keys(self)))
> > +return self
> >
> > -def iterkeys(self):
> > -return iter(sorted(dict.keys(self)))
> > +def next(self):
> > +try:
> > +data, pos = self.lm._get(self.pos)
> > +except IndexError:
> > +raise StopIteration
> > +if pos == -1:
> > +self.pos += 1
> > +return data[0]
> > +self.pos += 1
> > +zeropos = data.find('\x00', pos)
> > +return data[pos:zeropos]
> >
> > -def iterentries(self):

Re: news from the topic experiment

2016-09-20 Thread David Demelier
2016-09-20 15:39 GMT+02:00 Pierre-Yves David :
> At this point, reference to non-publishing repository implies evolution
> support. At some point evolution will stop being experimental and turned on
> by default.



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


Re: [PATCH 2 of 2 v3] crecord: add an event that scrolls the selected line to the top of the screen

2016-09-20 Thread Nathan Goldbaum
On Tuesday, September 20, 2016, Pierre-Yves David <
pierre-yves.da...@ens-lyon.org> wrote:

>
>
> On 09/20/2016 12:23 AM, Nathan Goldbaum wrote:
>
>> # HG changeset patch
>> # User Nathan Goldbaum 
>> # Date 1474321033 18000
>> #  Mon Sep 19 16:37:13 2016 -0500
>> # Node ID 94afc22065e475ab1a61f68012be44f6dbbd0d64
>> # Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
>> crecord: add an event that scrolls the selected line to the top of the
>> screen
>>
>> Using ctrl-l for this purpose seems to be a fairly widely used practice,
>> presumably following emacs. This doesn't scroll the selected line all
>> the way to the top of the window, instead it leaves a 3 line buffer for
>> context. Use curses.unctrl() to resolve keypressed to '^L' to avoid
>> hard-coding hexadecimal key codes.
>>
>> diff -r 285a8c3e53f2 -r 94afc22065e4 mercurial/crecord.py
>> --- a/mercurial/crecord.py  Tue May 03 13:36:12 2016 +0900
>> +++ b/mercurial/crecord.py  Mon Sep 19 16:37:13 2016 -0500
>> @@ -715,6 +715,10 @@ class curseschunkselector(object):
>>
>>  self.currentselecteditem = currentitem
>>
>> +def topscroll(self):
>> +"scroll so the currently selected line is at the top of the
>> screen"
>> +self.scrolllines(self.selecteditemstartline)
>> +
>>  def updatescroll(self):
>>  "scroll the screen to fully show the currently-selected"
>>  selstart = self.selecteditemstartline
>> @@ -1338,6 +1342,7 @@ the following are valid keystrokes:
>>   shift-left-arrow   [H] : go to parent header / fold selected header
>>f : fold / unfold item, hiding/revealing its
>> children
>>F : fold / unfold parent item and all of its
>> ancestors
>> + ctrl-l : scroll the selected line to the top of the
>> screen
>>m : edit / resume editing the commit message
>>e : edit the currently selected hunk
>>a : toggle amend mode, only with commit -i
>> @@ -1582,6 +1587,8 @@ are you sure you want to review/edit and
>>  self.helpwindow()
>>  self.stdscr.clear()
>>  self.stdscr.refresh()
>> +elif curses.unctrl(keypressed) in ["^L"]:
>> +self.topscroll()
>>
>
> any reason why we use 'in' instead of "==" here?


Following the other branches of the if/elif block in this function.


>
> Also, I'm not sure if the 'topscroll' method is that useful as it a
> one-liner. Should just call that code in the if clause?


Sure, I can send a v5


>
> Cheers,
>
> --
> Pierre-Yves David
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 3 of 4] strip: clarify that user action is required to recover temp bundle

2016-09-20 Thread Yuya Nishihara
On Mon, 19 Sep 2016 10:30:23 -0700, Martin von Zweigbergk via Mercurial-devel 
wrote:
> # HG changeset patch
> # User Martin von Zweigbergk 
> # Date 1474301672 25200
> #  Mon Sep 19 09:14:32 2016 -0700
> # Node ID 00910394ea13a94631ea1ba35bedb954e18451dc
> # Parent  83d10fef08a4f93da5bc4002cba6f610af66227a
> strip: clarify that user action is required to recover temp bundle

> +  (fix the problem, then recover the changesets with "hg unbundle 
> '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)

Nit: 'hg unbundle "..."' would be better since Windows cmd.exe doesn't take
single quotes.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH v4] crecord: add an event that scrolls the selected line to the top of the screen

2016-09-20 Thread Pierre-Yves David



On 09/20/2016 12:23 AM, Nathan Goldbaum wrote:

# HG changeset patch
# User Nathan Goldbaum 
# Date 1474321033 18000
#  Mon Sep 19 16:37:13 2016 -0500
# Node ID 94afc22065e475ab1a61f68012be44f6dbbd0d64
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
crecord: add an event that scrolls the selected line to the top of the screen

Using ctrl-l for this purpose seems to be a fairly widely used practice,
presumably following emacs. This doesn't scroll the selected line all
the way to the top of the window, instead it leaves a 3 line buffer for
context. Use curses.unctrl() to resolve keypressed to '^L' to avoid
hard-coding hexadecimal key codes.

diff -r 285a8c3e53f2 -r 94afc22065e4 mercurial/crecord.py
--- a/mercurial/crecord.py  Tue May 03 13:36:12 2016 +0900
+++ b/mercurial/crecord.py  Mon Sep 19 16:37:13 2016 -0500
@@ -715,6 +715,10 @@ class curseschunkselector(object):

 self.currentselecteditem = currentitem

+def topscroll(self):
+"scroll so the currently selected line is at the top of the screen"
+self.scrolllines(self.selecteditemstartline)
+
 def updatescroll(self):
 "scroll the screen to fully show the currently-selected"
 selstart = self.selecteditemstartline
@@ -1338,6 +1342,7 @@ the following are valid keystrokes:
  shift-left-arrow   [H] : go to parent header / fold selected header
   f : fold / unfold item, hiding/revealing its children
   F : fold / unfold parent item and all of its ancestors
+ ctrl-l : scroll the selected line to the top of the screen
   m : edit / resume editing the commit message
   e : edit the currently selected hunk
   a : toggle amend mode, only with commit -i
@@ -1582,6 +1587,8 @@ are you sure you want to review/edit and
 self.helpwindow()
 self.stdscr.clear()
 self.stdscr.refresh()
+elif curses.unctrl(keypressed) in ["^L"]:
+self.topscroll()


any reason why we use 'in' instead of "==" here?

Also, I'm not sure if the 'topscroll' method is that useful as it a 
one-liner. Should just call that code in the if clause?


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: news from the topic experiment

2016-09-20 Thread Pierre-Yves David



On 09/17/2016 08:21 AM, David Demelier wrote:

2016-09-16 18:35 GMT+02:00 Pierre-Yves David :

This is a very valid feedback. The start of the topic experiments come from
the finding that after 5 years of struggle trying to make bookmarks viable,
they seems too alien to other Mercurial concept to ever work in a
satisfactory way.


Okay so now I assume bookmarks no longer exist.

First, I've seen a hg stack function, I would suggest naming it
'topics' so it more meaningful and more appropriate since some
commands have plural forms (e.g. tag/tags, branch/branches).


- If you work on multiple feature at the same time (ie: have multiple
anonymous/bookmarked heads, you can use topic locally to organize them,


Okay, so to my point of view, local topics seem to work pretty fine
and looks like a good idea. My major disappointment with bookmarks is
the combination of "default" and "@", with topics, you will just need
to hg up default or the-topic. no more @, default and
featured-bookmarks :-)


- If you do advanced code review and use non-publishing review to exchange
draft with other people. You can use topics to organize these.



This is exactly what I dislike.

You need to use a non-publishing server to share topics. This means I
can rewrite history, delete revisions on the remote when using topics.
Thus, breaking any basic users who just do some hg pull and build.
Those users will not understand why their local repositories are
cluttered with many revisions that does not exist anymore. Probably we
should mix evolve features + topics so that we can use on
non-publishing server?

Personally, I will probably use topics only locally if it will still
requires only draft changesets and do code review with a pre-push
manner using some additional workflow (reviewboard, mailing lists,
etc...)


At this point, reference to non-publishing repository implies evolution 
support. At some point evolution will stop being experimental and turned 
on by default.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] formatter: introduce isplain() to replace (the inverse of) __nonzero__()

2016-09-20 Thread Yuya Nishihara
On Mon, 19 Sep 2016 09:14:41 -0500, Mathias De Maré wrote:
> # HG changeset patch
> # User Mathias De Maré 
> # Date 1472483949 -7200
> #  Mon Aug 29 17:19:09 2016 +0200
> # Node ID 084ca55ce77a5fe77bc93db26346cc71211a0070
> # Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
> formatter: introduce isplain() to replace (the inverse of) __nonzero__()

You have one more "if fm:". Fixed as follows and queued this, thanks. Also
flagged as (API).

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4442,10 +4442,10 @@ def grep(ui, repo, pattern, *pats, **opt
 
 def display(fm, fn, ctx, pstates, states):
 rev = ctx.rev()
-if fm:
+if fm.isplain():
+formatuser = ui.shortuser
+else:
 formatuser = str
-else:
-formatuser = ui.shortuser
 if ui.quiet:
 datefmt = '%Y-%m-%d'
 else:
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -141,8 +141,6 @@ class plainformatter(baseformatter):
 self.hexfunc = hex
 else:
 self.hexfunc = short
-def __nonzero__(self):
-return False
 def startitem(self):
 pass
 def data(self, **data):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] commands: add template support for config

2016-09-20 Thread Yuya Nishihara
On Mon, 19 Sep 2016 09:14:42 -0500, Mathias De Maré wrote:
> # HG changeset patch
> # User Mathias De Maré 
> # Date 1472447235 -7200
> #  Mon Aug 29 07:07:15 2016 +0200
> # Node ID c037f0fbd6374b5855373a82056015289910fe69
> # Parent  084ca55ce77a5fe77bc93db26346cc71211a0070
> commands: add template support for config

Queued this, thanks.

>   Note: I'm not quite sure about the best approach to handling
>   the 'print the full config' case.
>   For me, it printed the 'ui.promptecho' key at the end.
>   I went with globs there as that at least tests the json display reliably.

Maybe we can switch HGRCPATH to get cleaner result? IIRC, the order of
ui.walkconfig() is deterministic.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3 v2] profiling: allow nested usage of maybeprofile

2016-09-20 Thread Yuya Nishihara
On Mon, 19 Sep 2016 16:13:56 -0700, Arun Kulshreshtha wrote:
> # HG changeset patch
> # User Arun Kulshreshtha 
> # Date 1474324901 25200
> #  Mon Sep 19 15:41:41 2016 -0700
> # Node ID 679c90104cc1fc92099ede6bd359f6ab5b10640d
> # Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110
> profiling: allow nested usage of maybeprofile
> 
> Add a check to the maybeprofile context manager to ensure that profiling
> is only enabled once in nested invocations of this context manager.
> 
> Updated in v2 of this patch to reset itself once the root invocation
> has exited. While not currently used, this ensures that maybeprofile
> can be used in multiple (non-nested) places in a single run.
> 
> diff --git a/mercurial/profiling.py b/mercurial/profiling.py
> --- a/mercurial/profiling.py
> +++ b/mercurial/profiling.py
> @@ -157,8 +157,15 @@
>  just use a single code path for calling into code you may want to profile
>  and this function determines whether to start profiling.
>  """
> -if ui.configbool('profiling', 'enabled'):
> +
> +# Guard against nested invocations of this context manager.
> +# Profiling should only be started in the outermost invocation.
> +alreadyenabled = getattr(maybeprofile, 'enabled', False)
> +
> +if ui.configbool('profiling', 'enabled') and not alreadyenabled:
> +maybeprofile.enabled = True
>  with profile(ui):
>  yield
> +maybeprofile.enabled = False

maybeprofile() can be called in threads. If we need to prevent nesting, we'll
have to save the flag in TLS.

Also, I think that should be managed by profile() or (ls|flame|stat)profile().
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel