Re: [PATCH 9 of 9] template: use template-engine for obsfate

2017-07-11 Thread Boris Feld
On Fri, 2017-07-07 at 21:09 +0900, Yuya Nishihara wrote:
> On Thu, 06 Jul 2017 23:50:17 +0200, Boris Feld wrote:
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499085172 -7200
> > #  Mon Jul 03 14:32:52 2017 +0200
> > # Node ID e18d8e61b7260e246a82727c8cde01f936692cff
> > # Parent  098585d4fbc88dc54513e12fa306d0e52ea2b323
> > # EXP-Topic obsfatetemplate
> > template: use template-engine for obsfate
> > 
> > Try to replace the obsfateprinter part by "sub-templates".
> > 
> > The code is hacky, I've tried to use at maximum the template engine
> > but the
> > raw data-structure doesn't seems well supported:
> > 
> > [{'markers': [{}, {}, ...], 'successors': [A, ...], 'verb': '',
> > ...}, ...]
> > 
> > I've put this changeset at the end so the beginning of the serie
> > might be
> > accepted without it. Even without this changeset, we already have
> > good tests
> > and the right structure for the computation of obsfate data.
> > 
> > diff -r 098585d4fbc8 -r e18d8e61b726 mercurial/templatekw.py
> > --- a/mercurial/templatekw.py   Mon Jul 03 17:38:56 2017 +0200
> > +++ b/mercurial/templatekw.py   Mon Jul 03 14:32:52 2017 +0200
> > @@ -699,6 +699,32 @@
> >  
> >  return "; ".join(lines)
> >  
> > +def obsfatedefaulttempl(ui):
> > +""" Returns a dict with the default templates for obs fate
> > +"""
> > +# Prepare templates
> > +verbtempl = '{verb}'
> > +usertempl = '{if(users, " by {join(users, ", ")}")}'
> > +succtempl = '{if(successors, " as ")}{successors}' # Bypass if
> > limitation
> > +datetempleq = ' (at {min_date|isodate})'
> > +datetemplnoteq = ' (between {min_date|isodate} and
> > {max_date|isodate})'
> > +
> > +datetempl = '{if(max_date, "{ifeq(min_date, max_date, "%s",
> > "%s")}")}'
> > +datetempl = datetempl % (datetempleq, datetemplnoteq)
> > +
> > +optionalusertempl = usertempl
> > +username = _getusername(ui)
> > +if username is not None:
> > +optionalusertempl = ('{ifeq(join(users, "\0"), "%s", "",
> > "%s")}'
> > + % (username, usertempl))
> > +
> > +# Assemble them
> > +return {
> > +'obsfate_quiet': verbtempl + succtempl,
> > +'obsfate': verbtempl + optionalusertempl + succtempl,
> > +'obsfate_verbose': verbtempl + usertempl + succtempl +
> > datetempl,
> > +}
> 
> This makes me feel you're doing things in wrong layer. In principle,
> template
> keywords provide primitive data, which are pretty-printed by using
> user/stock
> templates (e.g. templates/map-cmdline.default.)

Definitely, I should have made it more explicit that this one patch is
in RFC state.

Obsfate has a difficult task: summarize the obsolescence history
(potentially spanning multiple obs-markers), aggregating the different
values and all of this in multiple dimensions when there's a
divergence.

This template seems quite complex, it felt complex during
implementation using templates. I tried finding an existing template
that was close to this complexity, successorssets was close but obsfate
adds one more layer of nesting, so I didn't find a good example to
mimic.

I'm pretty sure that implementing obsfate cleanly with the template
engine can be done, but after spending several days, I'm afraid I won't
be able to do it on my own. For example, I wasn't able to successfully
format the users list using templates, I tried doing this:

hg log -G -T '{obsfate % "obsolete: {get(obsfate, "verb")} by
{join(get(obsfate, "users"), ', ')}\n"}'

Lately, I was thinking about sending a V2 that, instead of returning
the formatted string, would returns an _hybrid object:

-return _obsfateprinter(values, repo, repo.ui)
+gen = _obsfateprinter(values, repo, repo.ui)
+return _hybrid(gen, values, None, None)

This way people would be able to start customizing it (with template
function "get") and we would be able to improve the implementation with
potential syntactic sugar addition in the template engine.

What do you think? Could you provide me with some direction to move
forward?

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


Re: [PATCH 12 of 14] vfs: add the possibility to have a "ward" to check vfs usage

2017-07-11 Thread Boris Feld
On Sat, 2017-07-08 at 16:36 +0900, Yuya Nishihara wrote:
> On Fri, 07 Jul 2017 18:48:44 +0200, Boris Feld wrote:
> > On Fri, 2017-07-07 at 21:48 +0900, Yuya Nishihara wrote:
> > > On Thu, 06 Jul 2017 20:53:50 +0200, Boris Feld wrote:
> > > > On Wed, 2017-07-05 at 23:55 +0900, Yuya Nishihara wrote:
> > > > > On Sun, 02 Jul 2017 04:56:37 +0200, Pierre-Yves David wrote:
> > > > > > # HG changeset patch
> > > > > > # User Pierre-Yves David 
> > > > > > # Date 1470323266 -7200
> > > > > > #  Thu Aug 04 17:07:46 2016 +0200
> > > > > > # Node ID ebf81efdd6d7ff15c64683933635616c00475688
> > > > > > # Parent  34b8be7f0420b07d0f7b71379c6055e5b26223d5
> > > > > > # EXP-Topic vfs.ward
> > > > > > # Available At https://www.mercurial-scm.org/repo/users/mar
> > > > > > mout
> > > > > > e/me
> > > > > > rcurial/
> > > > > > #  hg pull https://www.mercurial-scm.org/repo/u
> > > > > > sers
> > > > > > /mar
> > > > > > moute/mercurial/ -r ebf81efdd6d7
> > > > > > vfs: add the possibility to have a "ward" to check vfs
> > > > > > usage
> > > > > > The feature has some similarity with the 'pathauditor', but
> > > > > > further
> > > > > > digging
> > > > > > show it make more sense to keep them separated. The path
> > > > > > auditor is
> > > > > > fairly
> > > > > > autonomous (create from vfs.__init__ without any extra
> > > > > > information), and check
> > > > > > very generic details. On the other hand, the wards will
> > > > > > have
> > > > > > deeper
> > > > > > knownledge
> > > > > > of the Mercurial logic and is created at the local
> > > > > > repository
> > > > > > level. Mixing the
> > > > > > two would add much complexity for no real gains.
> > > > > 
> > > > > My gut feeling is that vfs isn't the right place if they
> > > > > require
> > > > > deeper
> > > > > knowledge of repository/dirstate logic. And the whole weakref
> > > > > business
> > > > > floating around wards, hooks and transaction seems like just
> > > > > getting
> > > > > around
> > > > > layering violation.
> > > > 
> > > > We pondered on this choice a long time and couldn't find any
> > > > other
> > > > layer that is used by both Mercurial core and the extensions to
> > > > access
> > > > the file system. It seems to be the highest abstraction layer
> > > > we
> > > > could
> > > > hook into without introducing a new one and updating all
> > > > callers.
> > > > 
> > > > Our reflexion is, as the vfs classes comes from the scmutil
> > > > file,
> > > > it
> > > > seems okay to have scm related logic in that layer.
> > > 
> > > IIRC, one possible alternative was to move lock itself to a vfs
> > > as
> > > the
> > > whole vfs is theoretically covered by the lock.
> > 
> > The practice divert a bit from the theory. For example, the
> > ".hg/bookmark" file is in theory covered by the 'wlock'. In
> > practice it
> > is now covered by the transaction and therefor the 'lock'. On the
> > other
> > hand there are multiple files handled by the vfs ('hgrc',
> > 'dirstate',
> > 'store/', etc) that are not covered by the wlock.
> > 
> > Right now, all these exceptions are stored on the repository, and
> > extension can update them. To us, the repository layers seems the
> > right
> > layer for logic regarding individual file semantic. We also want to
> > add
> > some logic regarding open transaction to the ward, something
> > unrelated
> > to the vfs.
> > 
> > The initial motivation for this series (beside catching bug) is to
> > make
> > it safer to introduce new vfs. For example, the share extensions
> > suffers from lack of cache sharing, each share has its own
> > '.hg/cache/'
> > directory. Introducing a 'repo.cvfs' dedicated to cache could fix
> > that,
> > but we wants t

[PATCH 1 of 3 V2] vfs: allow to pass more argument to audit

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Octobus 
# Date 1499768878 -7200
#  Tue Jul 11 12:27:58 2017 +0200
# Node ID b780af8186e280e459365533133ea6bbad5c6ae2
# Parent  4672db164c986da4442bd864cd044512d975c3f2
# EXP-Topic vfs.ward
vfs: allow to pass more argument to audit

We want to be able to do more precise check when auditing a path depending of
the intend of the file access (eg read versus write). So we now pass the 'mode'
and 'atomictemp' value to 'audit' and update the audit function to accept them.

This will be put to use in the next changeset.

diff -r 4672db164c98 -r b780af8186e2 mercurial/pathutil.py
--- a/mercurial/pathutil.py Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/pathutil.py Tue Jul 11 12:27:58 2017 +0200
@@ -46,7 +46,7 @@
 else:
 self.normcase = lambda x: x
 
-def __call__(self, path):
+def __call__(self, path, mode=None, atomictemp=None):
 '''Check the relative path.
 path may contain a pattern (e.g. foodir/**.txt)'''
 
diff -r 4672db164c98 -r b780af8186e2 mercurial/vfs.py
--- a/mercurial/vfs.py  Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/vfs.py  Tue Jul 11 12:27:58 2017 +0200
@@ -306,7 +306,7 @@
 if audit:
 self.audit = pathutil.pathauditor(self.base)
 else:
-self.audit = util.always
+self.audit =  (lambda path, mode=None, atomictemp=None: True)
 self.createmode = None
 self._trustnlink = None
 
@@ -360,7 +360,7 @@
 r = util.checkosfilename(path)
 if r:
 raise error.Abort("%s: %r" % (r, path))
-self.audit(path)
+self.audit(path, mode=mode, atomictemp=atomictemp)
 f = self.join(path)
 
 if not text and "b" not in mode:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 V2] repovfs: add a ward to check if locks are properly taken

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Octobus 
# Date 1499769497 -7200
#  Tue Jul 11 12:38:17 2017 +0200
# Node ID a630c1dfccedff6a47d16bda8c47082caf24b24c
# Parent  b780af8186e280e459365533133ea6bbad5c6ae2
# EXP-Topic vfs.ward
repovfs: add a ward to check if locks are properly taken


When the appropriate developer warning are enabled, We wrap 'repo.vfs.audit' to
check for locks when accessing file in '.hg' for writing. Another changeset will
add a 'ward' for the store vfs (svfs).

This check system have caught a handful of locking issues that  has been fixed
in previous series (mostly in 4.0). I expect another batch to be caught in third
party extensions.

We introduces two real exceptions from extensions 'blackbox.log' (because a lot 
of
read-only operations add entry to it), and 'last-email.txt' (because 'hg email'
is currently a read only operation and there is value to keep it this way).

In addition we are currently allowing bisect to operate outside of the lock
because the current code is a bit hard to get properly locked for now. Multiple
clean up have been made but there is still a couple of them to do and the freeze
is coming.

diff -r b780af8186e2 -r a630c1dfcced hgext/blackbox.py
--- a/hgext/blackbox.py Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/blackbox.py Tue Jul 11 12:38:17 2017 +0200
@@ -236,6 +236,7 @@
 
 if util.safehasattr(ui, 'setrepo'):
 ui.setrepo(repo)
+repo._wlockfreeprefix.add('blackbox.log')
 
 @command('^blackbox',
 [('l', 'limit', 10, _('the number of events to show')),
diff -r b780af8186e2 -r a630c1dfcced hgext/journal.py
--- a/hgext/journal.py  Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/journal.py  Tue Jul 11 12:38:17 2017 +0200
@@ -69,6 +69,7 @@
 def reposetup(ui, repo):
 if repo.local():
 repo.journal = journalstorage(repo)
+repo._wlockfreeprefix.add('namejournal')
 
 def runcommand(orig, lui, repo, cmd, fullargs, *args):
 """Track the command line options for recording in the journal"""
diff -r b780af8186e2 -r a630c1dfcced hgext/patchbomb.py
--- a/hgext/patchbomb.pyTue Jul 11 12:27:58 2017 +0200
+++ b/hgext/patchbomb.pyTue Jul 11 12:38:17 2017 +0200
@@ -122,6 +122,10 @@
 cmdutil.extraexport.append('pullurl')
 cmdutil.extraexportmap['pullurl'] = _addpullheader
 
+def reposetup(ui, repo):
+if not repo.local():
+return
+repo._wlockfreeprefix.add('last-email.txt')
 
 def prompt(ui, prompt, default=None, rest=':'):
 if default:
diff -r b780af8186e2 -r a630c1dfcced mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:27:58 2017 +0200
+++ b/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
@@ -289,6 +289,25 @@
 # only functions defined in module of enabled extensions are invoked
 featuresetupfuncs = set()
 
+# list of prefix for file which can be written without 'wlock'
+# Extensions should extend this list when needed
+_wlockfreeprefix = set([# We migh consider requiring 'wlock' for the next
+# two, but pretty much all the existing code assume
+# wlock is not needed so we keep them excluded for
+# now.
+'hgrc',
+'requires',
+# XXX cache is a complicatged business someone
+# should investigate this in depth at some point
+'cache/',
+# XXX shouldn't be dirstate covered by the wlock?
+'dirstate',
+# XXX bisect was still a bit too messy at the time
+# this changeset was introduced. Someone should fix
+# the remainig bit and drop this line
+'bisect.state',
+])
+
 def __init__(self, baseui, path, create=False):
 self.requirements = set()
 self.filtername = None
@@ -308,10 +327,13 @@
 self.auditor = pathutil.pathauditor(self.root, self._checknested)
 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
 realfs=False)
-self.vfs = vfsmod.vfs(self.path)
 self.baseui = baseui
 self.ui = baseui.copy()
 self.ui.copy = baseui.copy # prevent copying repo configuration
+self.vfs = vfsmod.vfs(self.path)
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+self.vfs.audit = self._getvfsward(self.vfs.audit)
 # A list of callback to shape the phase if no data were found.
 # Callback are in the form: func(repo, roots) --> processed root.
 # This list it to be filled by extension during repo setup
@@ -427,6 +449,38 @@
 # Signature to cached matcher instance.
 self._sparsematchercache = {}
 
+def _getvfswa

[PATCH 3 of 3 V2] reposvfs: add a ward to check if locks are properly taken

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Octobus 
# Date 1470672882 -7200
#  Mon Aug 08 18:14:42 2016 +0200
# Node ID 443e188172a87eb4700a84cdfc16bd60ca3d4989
# Parent  a630c1dfccedff6a47d16bda8c47082caf24b24c
# EXP-Topic vfs.ward
reposvfs: add a ward to check if locks are properly taken

we wrap 'repo.svfs.audit' to check for the store lock when accessing file in
'.hg/store' for writing. This caught a couple of instance where the transaction
was released after the lock, we should probably have a dedicated checker for
that case.

diff -r a630c1dfcced -r 443e188172a8 mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
+++ b/mercurial/localrepo.pyMon Aug 08 18:14:42 2016 +0200
@@ -411,6 +411,12 @@
 self.svfs = self.store.vfs
 self.sjoin = self.store.join
 self.vfs.createmode = self.store.createmode
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
+self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
+else: # standard vfs
+self.svfs.audit = self._getsvfsward(self.svfs.audit)
 self._applyopenerreqs()
 if create:
 self._writerequirements()
@@ -481,6 +487,25 @@
 return ret
 return checkvfs
 
+def _getsvfsward(self, origfunc):
+"""build a ward for self.svfs"""
+rref = weakref.ref(self)
+def checksvfs(path, mode=None, atomictemp=None):
+ret = origfunc(path, mode=mode, atomictemp=atomictemp)
+repo = rref()
+if repo is None or not util.safehasattr(repo, '_lockref'):
+return
+if mode in (None, 'r', 'rb'):
+return
+if path.startswith(repo.sharedpath):
+# truncate name relative to the repository (.hg)
+path = path[len(repo.sharedpath) + 1:]
+if repo._currentlock(repo._lockref) is None:
+repo.ui.develwarn('write with no lock: "%s"' % path,
+  stacklevel=3)
+return ret
+return checksvfs
+
 def close(self):
 self._writecaches()
 
diff -r a630c1dfcced -r 443e188172a8 tests/test-devel-warnings.t
--- a/tests/test-devel-warnings.t   Tue Jul 11 12:38:17 2017 +0200
+++ b/tests/test-devel-warnings.t   Mon Aug 08 18:14:42 2016 +0200
@@ -49,6 +49,11 @@
   > with repo.vfs(b'branch', 'a'):
   > pass
   > 
+  > @command(b'no-lock-write', [], '')
+  > def nolockwrite(ui, repo):
+  > with repo.svfs(b'fncache', 'a'):
+  > pass
+  > 
   > @command(b'stripintr', [], '')
   > def stripintr(ui, repo):
   > lo = repo.lock()
@@ -114,6 +119,9 @@
   $ hg no-wlock-write
   devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* 
(nowlockwrite) (glob)
 
+  $ hg no-lock-write
+  devel-warn: write with no lock: "fncache" at: $TESTTMP/buggylocking.py:* 
(nolockwrite) (glob)
+
 Stripping from a transaction
 
   $ echo a > a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 V3] vfs: allow to pass more argument to audit

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499768878 -7200
#  Tue Jul 11 12:27:58 2017 +0200
# Node ID 9addf65400ec8e6052a399c1586320988d73a321
# Parent  4672db164c986da4442bd864cd044512d975c3f2
# EXP-Topic vfs.ward
vfs: allow to pass more argument to audit

We want to be able to do more precise check when auditing a path depending of
the intend of the file access (eg read versus write). So we now pass the 'mode'
and 'atomictemp' value to 'audit' and update the audit function to accept them.

This will be put to use in the next changeset.

diff -r 4672db164c98 -r 9addf65400ec mercurial/pathutil.py
--- a/mercurial/pathutil.py Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/pathutil.py Tue Jul 11 12:27:58 2017 +0200
@@ -46,7 +46,7 @@
 else:
 self.normcase = lambda x: x
 
-def __call__(self, path):
+def __call__(self, path, mode=None, atomictemp=None):
 '''Check the relative path.
 path may contain a pattern (e.g. foodir/**.txt)'''
 
diff -r 4672db164c98 -r 9addf65400ec mercurial/vfs.py
--- a/mercurial/vfs.py  Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/vfs.py  Tue Jul 11 12:27:58 2017 +0200
@@ -306,7 +306,7 @@
 if audit:
 self.audit = pathutil.pathauditor(self.base)
 else:
-self.audit = util.always
+self.audit =  (lambda path, mode=None, atomictemp=None: True)
 self.createmode = None
 self._trustnlink = None
 
@@ -360,7 +360,7 @@
 r = util.checkosfilename(path)
 if r:
 raise error.Abort("%s: %r" % (r, path))
-self.audit(path)
+self.audit(path, mode=mode, atomictemp=atomictemp)
 f = self.join(path)
 
 if not text and "b" not in mode:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 V3] repovfs: add a ward to check if locks are properly taken

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499769497 -7200
#  Tue Jul 11 12:38:17 2017 +0200
# Node ID aacbe5f5ce3b41c0cf2332d05bf732e265c834a2
# Parent  9addf65400ec8e6052a399c1586320988d73a321
# EXP-Topic vfs.ward
repovfs: add a ward to check if locks are properly taken


When the appropriate developer warning are enabled, We wrap 'repo.vfs.audit' to
check for locks when accessing file in '.hg' for writing. Another changeset will
add a 'ward' for the store vfs (svfs).

This check system have caught a handful of locking issues that  has been fixed
in previous series (mostly in 4.0). I expect another batch to be caught in third
party extensions.

We introduces two real exceptions from extensions 'blackbox.log' (because a lot 
of
read-only operations add entry to it), and 'last-email.txt' (because 'hg email'
is currently a read only operation and there is value to keep it this way).

In addition we are currently allowing bisect to operate outside of the lock
because the current code is a bit hard to get properly locked for now. Multiple
clean up have been made but there is still a couple of them to do and the freeze
is coming.

diff -r 9addf65400ec -r aacbe5f5ce3b hgext/blackbox.py
--- a/hgext/blackbox.py Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/blackbox.py Tue Jul 11 12:38:17 2017 +0200
@@ -236,6 +236,7 @@
 
 if util.safehasattr(ui, 'setrepo'):
 ui.setrepo(repo)
+repo._wlockfreeprefix.add('blackbox.log')
 
 @command('^blackbox',
 [('l', 'limit', 10, _('the number of events to show')),
diff -r 9addf65400ec -r aacbe5f5ce3b hgext/journal.py
--- a/hgext/journal.py  Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/journal.py  Tue Jul 11 12:38:17 2017 +0200
@@ -69,6 +69,7 @@
 def reposetup(ui, repo):
 if repo.local():
 repo.journal = journalstorage(repo)
+repo._wlockfreeprefix.add('namejournal')
 
 def runcommand(orig, lui, repo, cmd, fullargs, *args):
 """Track the command line options for recording in the journal"""
diff -r 9addf65400ec -r aacbe5f5ce3b hgext/patchbomb.py
--- a/hgext/patchbomb.pyTue Jul 11 12:27:58 2017 +0200
+++ b/hgext/patchbomb.pyTue Jul 11 12:38:17 2017 +0200
@@ -122,6 +122,10 @@
 cmdutil.extraexport.append('pullurl')
 cmdutil.extraexportmap['pullurl'] = _addpullheader
 
+def reposetup(ui, repo):
+if not repo.local():
+return
+repo._wlockfreeprefix.add('last-email.txt')
 
 def prompt(ui, prompt, default=None, rest=':'):
 if default:
diff -r 9addf65400ec -r aacbe5f5ce3b mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:27:58 2017 +0200
+++ b/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
@@ -289,6 +289,25 @@
 # only functions defined in module of enabled extensions are invoked
 featuresetupfuncs = set()
 
+# list of prefix for file which can be written without 'wlock'
+# Extensions should extend this list when needed
+_wlockfreeprefix = set([# We migh consider requiring 'wlock' for the next
+# two, but pretty much all the existing code assume
+# wlock is not needed so we keep them excluded for
+# now.
+'hgrc',
+'requires',
+# XXX cache is a complicatged business someone
+# should investigate this in depth at some point
+'cache/',
+# XXX shouldn't be dirstate covered by the wlock?
+'dirstate',
+# XXX bisect was still a bit too messy at the time
+# this changeset was introduced. Someone should fix
+# the remainig bit and drop this line
+'bisect.state',
+])
+
 def __init__(self, baseui, path, create=False):
 self.requirements = set()
 self.filtername = None
@@ -308,10 +327,13 @@
 self.auditor = pathutil.pathauditor(self.root, self._checknested)
 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
 realfs=False)
-self.vfs = vfsmod.vfs(self.path)
 self.baseui = baseui
 self.ui = baseui.copy()
 self.ui.copy = baseui.copy # prevent copying repo configuration
+self.vfs = vfsmod.vfs(self.path)
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+self.vfs.audit = self._getvfsward(self.vfs.audit)
 # A list o

[PATCH 3 of 3 V3] reposvfs: add a ward to check if locks are properly taken

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1470672882 -7200
#  Mon Aug 08 18:14:42 2016 +0200
# Node ID 9856ed393ddd28ee570486e495bb9fd9762b3c9f
# Parent  aacbe5f5ce3b41c0cf2332d05bf732e265c834a2
# EXP-Topic vfs.ward
reposvfs: add a ward to check if locks are properly taken

we wrap 'repo.svfs.audit' to check for the store lock when accessing file in
'.hg/store' for writing. This caught a couple of instance where the transaction
was released after the lock, we should probably have a dedicated checker for
that case.

diff -r aacbe5f5ce3b -r 9856ed393ddd mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
+++ b/mercurial/localrepo.pyMon Aug 08 18:14:42 2016 +0200
@@ -411,6 +411,12 @@
 self.svfs = self.store.vfs
 self.sjoin = self.store.join
 self.vfs.createmode = self.store.createmode
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
+self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
+else: # standard vfs
+self.svfs.audit = self._getsvfsward(self.svfs.audit)
 self._applyopenerreqs()
 if create:
 self._writerequirements()
@@ -481,6 +487,25 @@
 return ret
 return checkvfs
 
+def _getsvfsward(self, origfunc):
+"""build a ward for self.svfs"""
+rref = weakref.ref(self)
+def checksvfs(path, mode=None, atomictemp=None):
+ret = origfunc(path, mode=mode, atomictemp=atomictemp)
+repo = rref()
+if repo is None or not util.safehasattr(repo, '_lockref'):
+return
+if mode in (None, 'r', 'rb'):
+return
+if path.startswith(repo.sharedpath):
+# truncate name relative to the repository (.hg)
+path = path[len(repo.sharedpath) + 1:]
+if repo._currentlock(repo._lockref) is None:
+repo.ui.develwarn('write with no lock: "%s"' % path,
+  stacklevel=3)
+return ret
+return checksvfs
+
 def close(self):
 self._writecaches()
 
diff -r aacbe5f5ce3b -r 9856ed393ddd tests/test-devel-warnings.t
--- a/tests/test-devel-warnings.t   Tue Jul 11 12:38:17 2017 +0200
+++ b/tests/test-devel-warnings.t   Mon Aug 08 18:14:42 2016 +0200
@@ -49,6 +49,11 @@
   > with repo.vfs(b'branch', 'a'):
   > pass
   > 
+  > @command(b'no-lock-write', [], '')
+  > def nolockwrite(ui, repo):
+  > with repo.svfs(b'fncache', 'a'):
+  > pass
+  > 
   > @command(b'stripintr', [], '')
   > def stripintr(ui, repo):
   > lo = repo.lock()
@@ -114,6 +119,9 @@
   $ hg no-wlock-write
   devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* 
(nowlockwrite) (glob)
 
+  $ hg no-lock-write
+  devel-warn: write with no lock: "fncache" at: $TESTTMP/buggylocking.py:* 
(nolockwrite) (glob)
+
 Stripping from a transaction
 
   $ echo a > a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 10 V2] configitems: register the 'bugzilla.apikey' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414602 -7200
#  Fri Jul 07 10:03:22 2017 +0200
# Node ID 63cf0aae1472ea685e1543472ea722b0ea89784e
# Parent  89796a25d4bb91fb418ad3e70faad2c586902ffb
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.apikey' config

diff -r 89796a25d4bb -r 63cf0aae1472 hgext/bugzilla.py
--- a/hgext/bugzilla.py Mon Jul 03 11:22:00 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:22 2017 +0200
@@ -303,6 +303,7 @@
 cmdutil,
 error,
 mail,
+registrar,
 url,
 util,
 )
@@ -315,6 +316,13 @@
 # leave the attribute unspecified.
 testedwith = 'ships-with-hg-core'
 
+configtable = {}
+configitem = registrar.configitem(configtable)
+
+configitem('bugzilla', 'apikey',
+default='',
+)
+
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
 
@@ -800,7 +808,7 @@
 bz = self.ui.config('bugzilla', 'bzurl',
 'http://localhost/bugzilla/')
 self.bzroot = '/'.join([bz, 'rest'])
-self.apikey = self.ui.config('bugzilla', 'apikey', '')
+self.apikey = self.ui.config('bugzilla', 'apikey')
 self.user = self.ui.config('bugzilla', 'user', 'bugs')
 self.passwd = self.ui.config('bugzilla', 'password')
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 10 V2] configitems: register the 'bugzilla.bzdir' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414604 -7200
#  Fri Jul 07 10:03:24 2017 +0200
# Node ID 3d5a8cdda2a96f147a2542c65aeb8d8addec06f0
# Parent  63cf0aae1472ea685e1543472ea722b0ea89784e
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.bzdir' config

diff -r 63cf0aae1472 -r 3d5a8cdda2a9 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:22 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:24 2017 +0200
@@ -322,6 +322,9 @@
 configitem('bugzilla', 'apikey',
 default='',
 )
+configitem('bugzilla', 'bzdir',
+default='/var/www/html/bugzilla',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -457,8 +460,7 @@
 for id in bugs.keys():
 self.ui.status(_('  bug %s\n') % id)
 cmdfmt = self.ui.config('bugzilla', 'notify', self.default_notify)
-bzdir = self.ui.config('bugzilla', 'bzdir',
-   '/var/www/html/bugzilla')
+bzdir = self.ui.config('bugzilla', 'bzdir')
 try:
 # Backwards-compatible with old notify string, which
 # took one string. This will throw with a new format
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 10 V2] configitems: register the 'bugzilla.bzurl' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414608 -7200
#  Fri Jul 07 10:03:28 2017 +0200
# Node ID b98505c496cf15809cd90e5bdab5165d4731dbd8
# Parent  97aa2edd521c6999219991836ba66abb0aeb2bd9
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.bzurl' config

diff -r 97aa2edd521c -r b98505c496cf hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:26 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:28 2017 +0200
@@ -328,6 +328,9 @@
 configitem('bugzilla', 'bzemail',
 default=None,
 )
+configitem('bugzilla', 'bzurl',
+default='http://localhost/bugzilla/',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -649,8 +652,7 @@
 def __init__(self, ui):
 bzaccess.__init__(self, ui)
 
-bzweb = self.ui.config('bugzilla', 'bzurl',
-   'http://localhost/bugzilla/')
+bzweb = self.ui.config('bugzilla', 'bzurl')
 bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi"
 
 user = self.ui.config('bugzilla', 'user', 'bugs')
@@ -810,8 +812,7 @@
 """
 def __init__(self, ui):
 bzaccess.__init__(self, ui)
-bz = self.ui.config('bugzilla', 'bzurl',
-'http://localhost/bugzilla/')
+bz = self.ui.config('bugzilla', 'bzurl')
 self.bzroot = '/'.join([bz, 'rest'])
 self.apikey = self.ui.config('bugzilla', 'apikey')
 self.user = self.ui.config('bugzilla', 'user', 'bugs')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 10 V2] configitems: register the 'bugzilla.bzemail' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414606 -7200
#  Fri Jul 07 10:03:26 2017 +0200
# Node ID 97aa2edd521c6999219991836ba66abb0aeb2bd9
# Parent  3d5a8cdda2a96f147a2542c65aeb8d8addec06f0
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.bzemail' config

diff -r 3d5a8cdda2a9 -r 97aa2edd521c hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:24 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:26 2017 +0200
@@ -325,6 +325,9 @@
 configitem('bugzilla', 'bzdir',
 default='/var/www/html/bugzilla',
 )
+configitem('bugzilla', 'bzemail',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 10 V2] configitems: register the 'bugzilla.bzuser' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414611 -7200
#  Fri Jul 07 10:03:31 2017 +0200
# Node ID 3d09ecfeedc7f19db069bd2cac8e269c7e561b05
# Parent  b98505c496cf15809cd90e5bdab5165d4731dbd8
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.bzuser' config

diff -r b98505c496cf -r 3d09ecfeedc7 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:28 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:31 2017 +0200
@@ -331,6 +331,9 @@
 configitem('bugzilla', 'bzurl',
 default='http://localhost/bugzilla/',
 )
+configitem('bugzilla', 'bzuser',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 10 V2] configitems: register the 'bugzilla.db' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414614 -7200
#  Fri Jul 07 10:03:34 2017 +0200
# Node ID cdef7e9e6b3cd6785755edb3cb1be3cb9cec2799
# Parent  3d09ecfeedc7f19db069bd2cac8e269c7e561b05
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.db' config

diff -r 3d09ecfeedc7 -r cdef7e9e6b3c hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:31 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:34 2017 +0200
@@ -334,6 +334,9 @@
 configitem('bugzilla', 'bzuser',
 default=None,
 )
+configitem('bugzilla', 'db',
+default='bugs',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -412,7 +415,7 @@
 host = self.ui.config('bugzilla', 'host', 'localhost')
 user = self.ui.config('bugzilla', 'user', 'bugs')
 passwd = self.ui.config('bugzilla', 'password')
-db = self.ui.config('bugzilla', 'db', 'bugs')
+db = self.ui.config('bugzilla', 'db')
 timeout = int(self.ui.config('bugzilla', 'timeout', 5))
 self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
  (host, db, user, '*' * len(passwd)))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 10 V2] configitems: register the 'bugzilla.fixstatus' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414637 -7200
#  Fri Jul 07 10:03:57 2017 +0200
# Node ID b065c6b0905ff4304d5f049e4b56ed55247339c0
# Parent  7899b38ce3e21d04d578f101bc6fc503600ca07b
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.fixstatus' config

diff -r 7899b38ce3e2 -r b065c6b0905f hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:05:40 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:57 2017 +0200
@@ -343,6 +343,9 @@
 configitem('bugzilla', 'fixresolution',
 default='FIXED',
 )
+configitem('bugzilla', 'fixstatus',
+default='RESOLVED',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -670,7 +673,7 @@
 user = self.ui.config('bugzilla', 'user', 'bugs')
 passwd = self.ui.config('bugzilla', 'password')
 
-self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED')
+self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
 self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
 
 self.bzproxy = xmlrpclib.ServerProxy(bzweb, self.transport(bzweb))
@@ -828,7 +831,7 @@
 self.apikey = self.ui.config('bugzilla', 'apikey')
 self.user = self.ui.config('bugzilla', 'user', 'bugs')
 self.passwd = self.ui.config('bugzilla', 'password')
-self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED')
+self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
 self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
 
 def apiurl(self, targets, include_fields=None):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 10 V2] configitems: register the 'bugzilla.fixresolution' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414740 -7200
#  Fri Jul 07 10:05:40 2017 +0200
# Node ID 7899b38ce3e21d04d578f101bc6fc503600ca07b
# Parent  0bb83a78698c7762b4c0a897797f5340cc9d0684
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.fixresolution' config

diff -r 0bb83a78698c -r 7899b38ce3e2 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:36 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:05:40 2017 +0200
@@ -340,6 +340,9 @@
 configitem('bugzilla', 'fixregexp',
 default=lambda: bugzilla._default_fix_re,
 )
+configitem('bugzilla', 'fixresolution',
+default='FIXED',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -668,8 +671,7 @@
 passwd = self.ui.config('bugzilla', 'password')
 
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED')
-self.fixresolution = self.ui.config('bugzilla', 'fixresolution',
-'FIXED')
+self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
 
 self.bzproxy = xmlrpclib.ServerProxy(bzweb, self.transport(bzweb))
 ver = self.bzproxy.Bugzilla.version()['version'].split('.')
@@ -827,8 +829,7 @@
 self.user = self.ui.config('bugzilla', 'user', 'bugs')
 self.passwd = self.ui.config('bugzilla', 'password')
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus', 'RESOLVED')
-self.fixresolution = self.ui.config('bugzilla', 'fixresolution',
-'FIXED')
+self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
 
 def apiurl(self, targets, include_fields=None):
 url = '/'.join([self.bzroot] + [str(t) for t in targets])
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 10 V2] configitems: register the 'bugzilla.fixregexp' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414616 -7200
#  Fri Jul 07 10:03:36 2017 +0200
# Node ID 0bb83a78698c7762b4c0a897797f5340cc9d0684
# Parent  cdef7e9e6b3cd6785755edb3cb1be3cb9cec2799
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.fixregexp' config

diff -r cdef7e9e6b3c -r 0bb83a78698c hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:34 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:03:36 2017 +0200
@@ -337,6 +337,9 @@
 configitem('bugzilla', 'db',
 default='bugs',
 )
+configitem('bugzilla', 'fixregexp',
+default=lambda: bugzilla._default_fix_re,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -975,8 +978,7 @@
 self.ui.config('bugzilla', 'regexp',
bugzilla._default_bug_re), re.IGNORECASE)
 self.fix_re = re.compile(
-self.ui.config('bugzilla', 'fixregexp',
-   bugzilla._default_fix_re), re.IGNORECASE)
+self.ui.config('bugzilla', 'fixregexp'), re.IGNORECASE)
 self.split_re = re.compile(r'\D+')
 
 def find_bugs(self, ctx):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 10 V2] configitems: register the 'bugzilla.host' config

2017-07-11 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414641 -7200
#  Fri Jul 07 10:04:01 2017 +0200
# Node ID 18c26fe8b1863306f3a9ef9b585e69517ba957e3
# Parent  b065c6b0905ff4304d5f049e4b56ed55247339c0
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.host' config

diff -r b065c6b0905f -r 18c26fe8b186 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:03:57 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:01 2017 +0200
@@ -346,6 +346,9 @@
 configitem('bugzilla', 'fixstatus',
 default='RESOLVED',
 )
+configitem('bugzilla', 'host',
+default='localhost',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -421,7 +424,7 @@
 
 bzaccess.__init__(self, ui)
 
-host = self.ui.config('bugzilla', 'host', 'localhost')
+host = self.ui.config('bugzilla', 'host')
 user = self.ui.config('bugzilla', 'user', 'bugs')
 passwd = self.ui.config('bugzilla', 'password')
 db = self.ui.config('bugzilla', 'db')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 10] configitems: register the 'bugzilla.timeout' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414655 -7200
#  Fri Jul 07 10:04:15 2017 +0200
# Node ID 5b67961350d4084c8e50c14826335f69711fa65d
# Parent  a8c4ac38c3d2f0e52653de1814a71fdc8801ee12
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.timeout' config

diff -r a8c4ac38c3d2 -r 5b67961350d4 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:13 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:15 2017 +0200
@@ -364,6 +364,9 @@
 configitem('bugzilla', 'template',
 default=None,
 )
+configitem('bugzilla', 'timeout',
+default=5,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -443,7 +446,7 @@
 user = self.ui.config('bugzilla', 'user', 'bugs')
 passwd = self.ui.config('bugzilla', 'password')
 db = self.ui.config('bugzilla', 'db')
-timeout = int(self.ui.config('bugzilla', 'timeout', 5))
+timeout = int(self.ui.config('bugzilla', 'timeout'))
 self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
  (host, db, user, '*' * len(passwd)))
 self.conn = bzmysql._MySQLdb.connect(host=host,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 10] configitems: register the 'bugzilla.usermap' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414659 -7200
#  Fri Jul 07 10:04:19 2017 +0200
# Node ID 26a2797083007305df1f79cf9edf1675e51745a2
# Parent  b3631f450acf389945b3abd5c68137f7f06e783d
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.usermap' config

diff -r b3631f450acf -r 26a279708300 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:17 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:19 2017 +0200
@@ -370,6 +370,9 @@
 configitem('bugzilla', 'user',
 default='bugs',
 )
+configitem('bugzilla', 'usermap',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 10] configitems: register the 'bugzilla.style' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414651 -7200
#  Fri Jul 07 10:04:11 2017 +0200
# Node ID 60189e1716c6dfd71b10f43aa49f6946d4021b2f
# Parent  69feb1d1d3d3b2d2dee30941cc910b7a1b98b04b
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.style' config

diff -r 69feb1d1d3d3 -r 60189e1716c6 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:09 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:11 2017 +0200
@@ -358,6 +358,9 @@
 configitem('bugzilla', 'strip',
 default=0,
 )
+configitem('bugzilla', 'style',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 10] configitems: register the 'bugzilla.regexp' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414647 -7200
#  Fri Jul 07 10:04:07 2017 +0200
# Node ID 1ca312b6211d3bde677c53972abd95c4be45f8ff
# Parent  f56a5222c189bad35178708eeba73f333691e148
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.regexp' config

diff -r f56a5222c189 -r 1ca312b6211d hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:05 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:07 2017 +0200
@@ -352,6 +352,9 @@
 configitem('bugzilla', 'password',
 default=None,
 )
+configitem('bugzilla', 'regexp',
+default=lambda: bugzilla._default_bug_re,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -985,8 +988,7 @@
 self.bzdriver = bzclass(self.ui)
 
 self.bug_re = re.compile(
-self.ui.config('bugzilla', 'regexp',
-   bugzilla._default_bug_re), re.IGNORECASE)
+self.ui.config('bugzilla', 'regexp'), re.IGNORECASE)
 self.fix_re = re.compile(
 self.ui.config('bugzilla', 'fixregexp'), re.IGNORECASE)
 self.split_re = re.compile(r'\D+')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 10] configitems: register the 'bugzilla.strip' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414649 -7200
#  Fri Jul 07 10:04:09 2017 +0200
# Node ID 69feb1d1d3d3b2d2dee30941cc910b7a1b98b04b
# Parent  1ca312b6211d3bde677c53972abd95c4be45f8ff
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.strip' config

diff -r 1ca312b6211d -r 69feb1d1d3d3 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:07 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:09 2017 +0200
@@ -355,6 +355,9 @@
 configitem('bugzilla', 'regexp',
 default=lambda: bugzilla._default_bug_re,
 )
+configitem('bugzilla', 'strip',
+default=0,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -1057,7 +1060,7 @@
 def webroot(root):
 '''strip leading prefix of repo root and turn into
 url-safe path.'''
-count = int(self.ui.config('bugzilla', 'strip', 0))
+count = int(self.ui.config('bugzilla', 'strip'))
 root = util.pconvert(root)
 while count > 0:
 c = root.find('/')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 10] configitems: register the 'bugzilla.password' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414645 -7200
#  Fri Jul 07 10:04:05 2017 +0200
# Node ID f56a5222c189bad35178708eeba73f333691e148
# Parent  fcb4529a633634e7885ed4b79a62743a52a4a6b3
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.password' config

diff -r fcb4529a6336 -r f56a5222c189 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:03 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:05 2017 +0200
@@ -349,6 +349,9 @@
 configitem('bugzilla', 'host',
 default='localhost',
 )
+configitem('bugzilla', 'password',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 10] configitems: register the 'bugzilla.template' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414653 -7200
#  Fri Jul 07 10:04:13 2017 +0200
# Node ID a8c4ac38c3d2f0e52653de1814a71fdc8801ee12
# Parent  60189e1716c6dfd71b10f43aa49f6946d4021b2f
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.template' config

diff -r 60189e1716c6 -r a8c4ac38c3d2 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:11 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:13 2017 +0200
@@ -361,6 +361,9 @@
 configitem('bugzilla', 'style',
 default=None,
 )
+configitem('bugzilla', 'template',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 10] configitems: register the 'bugzilla.mocklog' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414643 -7200
#  Fri Jul 07 10:04:03 2017 +0200
# Node ID fcb4529a633634e7885ed4b79a62743a52a4a6b3
# Parent  26e4ba058215e536d3827befbea99ff6203d35f8
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.mocklog' config

diff -r 26e4ba058215 -r fcb4529a6336 tests/test-bugzilla.t
--- a/tests/test-bugzilla.t Fri Jul 07 10:04:01 2017 +0200
+++ b/tests/test-bugzilla.t Fri Jul 07 10:04:03 2017 +0200
@@ -3,7 +3,14 @@
   $ cat < bzmock.py
   > from __future__ import absolute_import
   > from mercurial import extensions
+  > from mercurial import registrar
   > 
+  > configtable = {}
+  > configitem = registrar.configitem(configtable)
+  > 
+  > configitem('bugzilla', 'mocklog',
+  > default=None,
+  > )
   > def extsetup(ui):
   > bugzilla = extensions.find('bugzilla')
   > class bzmock(bugzilla.bzaccess):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 10] configitems: register the 'bugzilla.version' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414661 -7200
#  Fri Jul 07 10:04:21 2017 +0200
# Node ID 0ed2de9467f9abc9443bb583e57fcb1ff8703f42
# Parent  26a2797083007305df1f79cf9edf1675e51745a2
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.version' config

diff -r 26a279708300 -r 0ed2de9467f9 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:19 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:21 2017 +0200
@@ -373,6 +373,9 @@
 configitem('bugzilla', 'usermap',
 default=None,
 )
+configitem('bugzilla', 'version',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 10] configitems: register the 'bugzilla.user' config

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414657 -7200
#  Fri Jul 07 10:04:17 2017 +0200
# Node ID b3631f450acf389945b3abd5c68137f7f06e783d
# Parent  5b67961350d4084c8e50c14826335f69711fa65d
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.user' config

diff -r 5b67961350d4 -r b3631f450acf hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:15 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:17 2017 +0200
@@ -367,6 +367,9 @@
 configitem('bugzilla', 'timeout',
 default=5,
 )
+configitem('bugzilla', 'user',
+default='bugs',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -443,7 +446,7 @@
 bzaccess.__init__(self, ui)
 
 host = self.ui.config('bugzilla', 'host')
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 passwd = self.ui.config('bugzilla', 'password')
 db = self.ui.config('bugzilla', 'db')
 timeout = int(self.ui.config('bugzilla', 'timeout'))
@@ -691,7 +694,7 @@
 bzweb = self.ui.config('bugzilla', 'bzurl')
 bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi"
 
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 passwd = self.ui.config('bugzilla', 'password')
 
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
@@ -808,7 +811,7 @@
 matches = self.bzproxy.User.get({'match': [user],
  'token': self.bztoken})
 if not matches['users']:
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 matches = self.bzproxy.User.get({'match': [user],
  'token': self.bztoken})
 if not matches['users']:
@@ -850,7 +853,7 @@
 bz = self.ui.config('bugzilla', 'bzurl')
 self.bzroot = '/'.join([bz, 'rest'])
 self.apikey = self.ui.config('bugzilla', 'apikey')
-self.user = self.ui.config('bugzilla', 'user', 'bugs')
+self.user = self.ui.config('bugzilla', 'user')
 self.passwd = self.ui.config('bugzilla', 'password')
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
 self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 9 of 9] template: use template-engine for obsfate

2017-07-12 Thread Boris Feld
On Wed, 2017-07-12 at 00:06 +0900, Yuya Nishihara wrote:
> On Tue, 11 Jul 2017 11:16:03 +0200, Boris Feld wrote:
> > Obsfate has a difficult task: summarize the obsolescence history
> > (potentially spanning multiple obs-markers), aggregating the
> > different
> > values and all of this in multiple dimensions when there's a
> > divergence.
> > 
> > This template seems quite complex, it felt complex during
> > implementation using templates. I tried finding an existing
> > template
> > that was close to this complexity, successorssets was close but
> > obsfate
> > adds one more layer of nesting, so I didn't find a good example to
> > mimic.
> > 
> > I'm pretty sure that implementing obsfate cleanly with the template
> > engine can be done, but after spending several days, I'm afraid I
> > won't
> > be able to do it on my own. For example, I wasn't able to
> > successfully
> > format the users list using templates, I tried doing this:
> > 
> > hg log -G -T '{obsfate % "obsolete: {get(obsfate, "verb")} by
> > {join(get(obsfate, "users"), ', ')}\n"}'
> > 
> > Lately, I was thinking about sending a V2 that, instead of
> > returning
> > the formatted string, would returns an _hybrid object:
> > 
> > -return _obsfateprinter(values, repo, repo.ui)
> > +gen = _obsfateprinter(values, repo, repo.ui)
> > +return _hybrid(gen, values, None, None)
> > 
> > This way people would be able to start customizing it (with
> > template
> > function "get") and we would be able to improve the implementation
> > with
> > potential syntactic sugar addition in the template engine.
> 
> Well, I don't have expertise in the obsolete thingy, though I'm
> (unfortunately)
> a template expert.
> 
> Guessing from the PATCH 4, which has the following functions,
> 
>   obsfatedata: ctx => [succs, ...] => [(succs, markers), ...]
> 
> maybe we'll want a template function which converts 'succs' to
> 'markers' ?
> Let's call it 'relatedmarkers' here.
> 
>   relatedmarkers: succs => [marker, ...]  (where marker is a _hybrid
> dict)
> 
> Then, a part of {obsfate} could probably be written as:
> 
>   {successorsets % "{relatedmarkers(successorset)
>  % "{get(marker, "verb")} ..."}"}

I hadn't thought about splitting the template into several templates
functions, it's a good idea!.

One small, but important detail: the verb, users list and dates are
computed from the markers list. Something like this might work, what do
you think?

{successorsets % "{obsfateverb(successorset)} by
{obsfateusers(successorset)} as {join(get(successorset, 'successors'),
', ')}"}

Would it be possible to keep the current {obsfate} template? It is easy
to use for users who are OK with the default obsfate output format
(which could be updated of course).

Also I've almost successfully reproduce the obsfate output "by hand"
with:

$ hg log -r 34177 --hidden -v -T "{obsfate}"
rewritten by Boris Feld  as e18d8e61b726 (at
2017-07-06 23:47 +0200)

$ hg log -r 34177 --hidden -T '{obsfate % "{get(obsfate, "verb")} by
{join(get(obsfate, "users"), ", ")} as {get(obsfate, "successors")} (at
{get(obsfate, "min_date")|isodate})\n"}'
rewritten by Boris Feld  as e18d8e61b726 (at
2017-07-06 23:47 +0200)
> 
> I think that's similar to what Jun suggested.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] changegroup: stop treating strip as special when dealing with phases

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499741576 -7200
#  Tue Jul 11 04:52:56 2017 +0200
# Node ID e46f9cabad79aa5429c2e8d80d5c60e42e42abb1
# Parent  4672db164c986da4442bd864cd044512d975c3f2
# EXP-Topic tr.changes.phases
changegroup: stop treating strip as special when dealing with phases

Since 8e3021fd1a44, the strip bundle includes the phases of the stripping
node. Hence we don't need this special case anymore.

Dropping it will helps make the phase behavior more consistent across all
exchanges medium.

diff -r 4672db164c98 -r e46f9cabad79 mercurial/changegroup.py
--- a/mercurial/changegroup.py  Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/changegroup.py  Tue Jul 11 04:52:56 2017 +0200
@@ -372,10 +372,7 @@
 # ignored.
 phases.advanceboundary(repo, tr, phases.draft, cgnodes)
 phases.retractboundary(repo, tr, phases.draft, added)
-elif srctype != 'strip':
-# publishing only alter behavior during push
-#
-# strip should not touch boundary at all
+else:
 phases.retractboundary(repo, tr, targetphase, added)
 
 if changesets > 0:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] bundle2: support the 'targetphase' parameter for the changegroup part

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499742712 -7200
#  Tue Jul 11 05:11:52 2017 +0200
# Node ID a600e69f8de0b75998a11502c3cb868936e6cb4a
# Parent  e46f9cabad79aa5429c2e8d80d5c60e42e42abb1
# EXP-Topic tr.changes.phases
bundle2: support the 'targetphase' parameter for the changegroup part

By default unbundled changesets are drafts. We want to reduce the number of
phases changes during unbundling by giving the possibility to the bundle to
indicate the phase of unbundled changesets.

The longer terms goal is to add phase movement tracking in tr.changes and the
'retractboundary' call is making it more complicated than we want.

diff -r e46f9cabad79 -r a600e69f8de0 mercurial/bundle2.py
--- a/mercurial/bundle2.py  Tue Jul 11 04:52:56 2017 +0200
+++ b/mercurial/bundle2.py  Tue Jul 11 05:11:52 2017 +0200
@@ -1517,7 +1517,8 @@
 result = -1 + changedheads
 return result
 
-@parthandler('changegroup', ('version', 'nbchanges', 'treemanifest'))
+@parthandler('changegroup', ('version', 'nbchanges', 'treemanifest',
+ 'targetphase'))
 def handlechangegroup(op, inpart):
 """apply a changegroup part on the repo
 
@@ -1542,8 +1543,12 @@
 op.repo.requirements.add('treemanifest')
 op.repo._applyopenerreqs()
 op.repo._writerequirements()
+extrakwargs = {}
+targetphase = inpart.params.get('targetphase')
+if targetphase is not None:
+extrakwargs['targetphase'] = int(targetphase)
 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2',
-  expectedtotal=nbchangesets)
+  expectedtotal=nbchangesets, **extrakwargs)
 if op.reply is not None:
 # This is definitely not the final form of this
 # return. But one need to start somewhere.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 4] bundle2: automatically add 'targetphase' parameter in writenewbundle

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499742723 -7200
#  Tue Jul 11 05:12:03 2017 +0200
# Node ID 5a2c6c050e33e4f2a571247f5d1e150a3ef1d295
# Parent  a600e69f8de0b75998a11502c3cb868936e6cb4a
# EXP-Topic tr.changes.phases
bundle2: automatically add 'targetphase' parameter in writenewbundle

If we are bundling secret changeset and the bundle will contain phase, we
request the changegroup to be applied as secret.

It will be useful for next patch as we are now sure that secrets changesets
are applied as secret and not applied as draft then forced to secret.

diff -r a600e69f8de0 -r 5a2c6c050e33 mercurial/bundle2.py
--- a/mercurial/bundle2.py  Tue Jul 11 05:11:52 2017 +0200
+++ b/mercurial/bundle2.py  Tue Jul 11 05:12:03 2017 +0200
@@ -1401,6 +1401,9 @@
 if 'clcount' in cg.extras:
 part.addparam('nbchanges', str(cg.extras['clcount']),
   mandatory=False)
+if opts.get('phases') and repo.revs('%ln and secret()',
+outgoing.missingheads):
+part.addparam('targetphase', '%d' % phases.secret, mandatory=False)
 
 addparttagsfnodescache(repo, bundler, outgoing)
 
diff -r a600e69f8de0 -r 5a2c6c050e33 tests/test-bundle-phases.t
--- a/tests/test-bundle-phases.tTue Jul 11 05:11:52 2017 +0200
+++ b/tests/test-bundle-phases.tTue Jul 11 05:12:03 2017 +0200
@@ -38,7 +38,7 @@
   3 changesets found
   $ hg debugbundle bundle
   Stream params: sortdict([('Compression', 'BZ')])
-  changegroup -- "sortdict([('version', '02'), ('nbchanges', '3')])"
+  changegroup -- "sortdict([('version', '02'), ('nbchanges', '3'), 
('targetphase', '2')])"
   26805aba1e600a82e93661149f2313866a221a7b
   f585351a92f85104bff7c284233c338b10eb1df7
   9bc730a19041f9ec7cb33c626e811aa233efb18c
@@ -227,7 +227,7 @@
   5 changesets found
   $ hg debugbundle bundle
   Stream params: sortdict([('Compression', 'BZ')])
-  changegroup -- "sortdict([('version', '02'), ('nbchanges', '5')])"
+  changegroup -- "sortdict([('version', '02'), ('nbchanges', '5'), 
('targetphase', '2')])"
   426bada5c67598ca65036d57d9e4b64b0c1ce7a0
   112478962961147124edd43549aedd1a335e44bf
   dc0947a82db884575bb76ea10ac97b08536bfa03
@@ -255,7 +255,7 @@
   2 changesets found
   $ hg debugbundle bundle
   Stream params: sortdict([('Compression', 'BZ')])
-  changegroup -- "sortdict([('version', '02'), ('nbchanges', '2')])"
+  changegroup -- "sortdict([('version', '02'), ('nbchanges', '2'), 
('targetphase', '2')])"
   112478962961147124edd43549aedd1a335e44bf
   215e7b0814e1cac8e2614e7284f2a5dc266b4323
   phase-heads -- 'sortdict()'
@@ -265,7 +265,7 @@
   3 changesets found
   $ hg debugbundle bundle
   Stream params: sortdict([('Compression', 'BZ')])
-  changegroup -- "sortdict([('version', '02'), ('nbchanges', '3')])"
+  changegroup -- "sortdict([('version', '02'), ('nbchanges', '3'), 
('targetphase', '2')])"
   112478962961147124edd43549aedd1a335e44bf
   dc0947a82db884575bb76ea10ac97b08536bfa03
   215e7b0814e1cac8e2614e7284f2a5dc266b4323
@@ -277,7 +277,7 @@
   2 changesets found
   $ hg debugbundle bundle
   Stream params: sortdict([('Compression', 'BZ')])
-  changegroup -- "sortdict([('version', '02'), ('nbchanges', '2')])"
+  changegroup -- "sortdict([('version', '02'), ('nbchanges', '2'), 
('targetphase', '2')])"
   215e7b0814e1cac8e2614e7284f2a5dc266b4323
   03ca77807e919db8807c3749086dc36fb478cac0
   phase-heads -- 'sortdict()'
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] bundle2: no longer use 'retractboundary' in updatephases

2017-07-12 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499742361 -7200
#  Tue Jul 11 05:06:01 2017 +0200
# Node ID 002ca6e17d6b53123c5ab4a4a46fb3f5d453e072
# Parent  5a2c6c050e33e4f2a571247f5d1e150a3ef1d295
# EXP-Topic tr.changes.phases
bundle2: no longer use 'retractboundary' in updatephases

The new 'phase-heads' forced all added node to secret before advancing the
boundary to work around the fact changesets were added as draft by default.
This is no longer necessary since the changegroup part can now use the
'targetphase' parameter.

Not doing this retract boundary call has a couple of advantages:

* This makes implementing phases change tracking in the transaction much
  simpler since retract boundary can become a rare case.

* Bundling secret changesets is not the norm. Exchange never does that and
  even for strip, the use-case is not common.Skipping the retract boundary
  will avoid useless work here.

* Sending phase update on push can be simplified since we can rely on the
  behavior of 'cg.apply' for most of it.
  This means less phases update send for example.

* We no longer needs to track and use the addednodes during unbundling. This
  make it possible to have multiple 'changegroup' and 'phase-heads' parts in the
  same bundle without them interfering with each others.

The new part has not been part of any release yet so we do not offer backward
compatibility yet. It is important to update this semantic before the 4.3
freeze happens.

diff -r 5a2c6c050e33 -r 002ca6e17d6b mercurial/phases.py
--- a/mercurial/phases.py   Tue Jul 11 05:12:03 2017 +0200
+++ b/mercurial/phases.py   Tue Jul 11 05:06:01 2017 +0200
@@ -448,10 +448,6 @@
 
 def updatephases(repo, tr, headsbyphase, addednodes):
 """Updates the repo with the given phase heads"""
-# First make all the added revisions secret because changegroup.apply()
-# currently sets the phase to draft.
-retractboundary(repo, tr, secret, addednodes)
-
 # Now advance phase boundaries of all but secret phase
 for phase in allphases[:-1]:
 advanceboundary(repo, tr, phase, headsbyphase[phase])
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Community video chats?

2017-07-13 Thread Boris Feld
On Tue, 2017-07-11 at 16:08 -0400, Augie Fackler wrote:
> > On Jul 11, 2017, at 15:47, Phillip Cohen 
> > wrote:
> > 
> > Great, glad there's interest.
> > 
> > How would Thursday at 10am PST / 1pm EST  / 6pm UTC work? This is
> > early enough for London to join, but not too early that California
> > won't. Friday mornings are less desirable (because that's Friday
> > evening in London) but Monday and Tuesday morning could work as
> > well.
> 
> I can't do 1300-1500 America/New_York on Thursdays. Pretty much any
> other time in the week would work. Maybe shoot for Tuesdays?
> 

I'm also interested, 6pm UTC (5pm or 7pm could works too) on every day
except Tuesdays would works for me with a preference for Thursday.

> > 
> > > I'm happy to try and join. I've considered having VC-available
> > > "office
> > > hours" that people could use to get help on patches, debugging,
> > > whatever. If there's interest in that I can try and pick a time.
> > 
> > +1. Individual office hours are a great idea in their own right.
> > 
> > > perhaps to start with
> > > we could try and reach out to known contributors that might miss
> > > this
> > > kind of thing on the list?
> > 
> > Sure, I'll start a wiki page so it could be sent to non-list-
> > readers.
> > 
> > On Tue, Jul 11, 2017 at 10:44 AM, Sean Farley 
> > wrote:
> > > 
> > > Durham Goode  writes:
> > > 
> > > > On 7/11/17 7:09 AM, Augie Fackler wrote:
> > > > > On Mon, Jul 10, 2017 at 11:42:48PM +, Phil Cohen wrote:
> > > > > > Many of us enjoy the fast-paced collaboration that happens
> > > > > > during Mercurial's sprints. Alas, they only happen twice a
> > > > > > year. In the interim, many of us have used ad-hoc
> > > > > > videoconferencing to whiteboard ideas ahead of code review,
> > > > > > and this has worked pretty well. It'd be great to do even
> > > > > > more here.
> > > > > > 
> > > > > > One thing that was suggested in the last group get-together 
> > > > > > was to establish a regular time for community members to
> > > > > > “hang out” on VC if they're available, and discuss any
> > > > > > technical topics or proposals that come up. The goal is for
> > > > > > this to be informal, replicating the sprint atmosphere as
> > > > > > much as possible, so there'd be no need for a strict agenda
> > > > > > (though we could create one if there's sufficient demand
> > > > > > for topics). If nobody ends up wanting to talk about
> > > > > > anything (a remote scenario, perhaps :) we can always end
> > > > > > early.
> > > > > > 
> > > > > > These video chat sessions should hopefully fill a niche
> > > > > > that's poorly satisfied by IRC or e-mail today: discussing
> > > > > > topics in-depth at high bandwidth before patches hit the
> > > > > > mailing list.
> > > > > > 
> > > > > > Does this sound like something people would want to
> > > > > > participate in? If so, we should hash out a good time
> > > > > > (spitballing: Friday mornings? One problem is between US,
> > > > > > Europe, and Japan, you can only ever pick satisfactory
> > > > > > times for two of the three), frequency (fortnightly?), and
> > > > > > videochat platform (Augie and I have used https://urldefens
> > > > > > e.proofpoint.com/v2/url?u=http-
> > > > > > 3A__appear.in&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=nuarHzhP1
> > > > > > wi1T9iURRCj1A&m=_T5aO7D7rY_Z7ImHZYBM5Fgrqdmamr3GPqHqFthl-
> > > > > > 2A&s=Kafrn1OKTr8b6_4cLyRGdi8rogXB8ypSEfpqjp-LlPU&e=  before
> > > > > > and it seems to work well).
> > > > > 
> > > > > I'm happy to try and join. I've considered having VC-
> > > > > available "office
> > > > > hours" that people could use to get help on patches,
> > > > > debugging,
> > > > > whatever. If there's interest in that I can try and pick a
> > > > > time.
> > > > > 
> > > > > Also happy to just casually hang out on VC once every couple
> > > > > of weeks.
> > > > 
> > > > I'm all for it.  I think it would help keep things unblocked
> > > > and the
> > > > sprint discussions tend to motivate people so perhaps regular
> > > > discussions would help keep the motivation flowing.
> > > > 
> > > > We have plenty of topics going around these days:
> > > > 
> > > > - phabricator
> > > > - sparse
> > > > - obsstore
> > > > - upstreaming other extensions
> > > > 
> > > > to name a few
> > > 
> > > I, too, am all for it. If for nothing else than to help convey
> > > tone /
> > > feeling which text cannot do.
> > > 
> > > I'd be up for helping to get this going as well; perhaps to start
> > > with
> > > we could try and reach out to known contributors that might miss
> > > this
> > > kind of thing on the list?
> > > 
> > > ___
> > > 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/mer

Re: [PATCH 9 of 9] template: use template-engine for obsfate

2017-07-13 Thread Boris Feld
I think there was a misunderstanding about obsfate that I will try to
clarify, this email is a bit long, sorry.

TL;DR:
- hg log is a changeset-centric command
- obsfate template summarize the obs-history between a changeset and
its successors, history that can span several obs-markers
- hg obslog from evolve extensions is a obs-marker centric command that
could gain support for operation

Given this repository:

  @  changeset:   2:256782ab8caa
  |  tag: tip
  |  parent:  0:ea207398892e
  |  user:test
  |  date:Thu Jan 01 00:00:00 1970 +
  |  summary: B
  |
  | o  changeset:   1:2a34000d3544
  |/   user:test
  |date:Thu Jan 01 00:00:00 1970 +
  |summary: A
  |
  o  changeset:   0:ea207398892e
 user:test
 date:Thu Jan 01 00:00:00 1970 +
 summary: ROOT

If you rebase 1 on top of 2, amend it a first time, then amend it a
second time, you will get:


  @  changeset:   5:022e174ded42
  |  tag: tip
  |  parent:  2:256782ab8caa
  |  user:test2
  |  date:Thu Jan 01 00:00:00 1970 +
  |  summary: A"
  |
  o  changeset:   2:256782ab8caa
  |  parent:  0:ea207398892e
  |  user:test
  |  date:Thu Jan 01 00:00:00 1970 +
  |  summary: B
  |
  o  changeset:   0:ea207398892e
 user:test
 date:Thu Jan 01 00:00:00 1970 +
 summary: ROOT

Now for any reason if changeset 1 should be shown (if it's the current
repository parent for example), the output would be:


  o  changeset:   5:022e174ded42
  |  tag: tip
  |  parent:  2:256782ab8caa
  |  user:test2
  |  date:Thu Jan 01 00:00:00 1970 +
  |  files:   A
  |  description:
  |  A"
  |
  |
  o  changeset:   2:256782ab8caa
  |  parent:  0:ea207398892e
  |  user:test
  |  date:Thu Jan 01 00:00:00 1970 +
  |  files:   B
  |  description:
  |  B
  |
  |
  | @  changeset:   1:2a34000d3544
  |/   user:test
  |date:Thu Jan 01 00:00:00 1970 +
  |obsolete:rewritten by test as 022e174ded42 (at 1970-01-01
00:00 +)
  |files:   A
  |description:
  |A
  |
  |
  o  changeset:   0:ea207398892e
 user:test
 date:Thu Jan 01 00:00:00 1970 +
 files:   ROOT
 description:
 ROOT

Obsfate was designed to summarize the obsolescence history for users.
As 'hg log' is a changeset centric command, obsfate tries to output
informations about visible changesets only. That's why obsfate for
2a34000d3544 is "rewritten as 022e174ded42". We have intermediary
changesets but they are not visible here so it would be disturbing to
say to the user "rewritten as 1737d8285b4d".

One side-effect of this summarization is that obsfate needs to
aggregate all the obs-markers from 2a34000d3544 to 022e174ded42, which
in this case is "1->3" (from the rebase), "3->4" (from the first amend)
and "4->5" (from the second amend). Here the range of obs-markers is
short but it could be much more big. That's why obsfate aggregate a
couple of fields to show a human-redable summary of the obs-history:

- Remove users duplicate.
- Compute the range of date, the smaller date of the obs-marker range
and the bigger one.
- Try to compute a verb based on the markers.

All theses computations are quite naive for the moment but the code has
been designed to be easily updated, wrapped by a command or extended.

This example is also quite simple but a real-life example:

  obsolete:split by Boris Feld ,Matthieu
Laneuville  as 008f7cd1fcbe,
b6e50897b94e (between 2017-06-26 17:17 +0200 and 2017-07-02 15:08
+0200)

In this case, obsfate is summarizing 19 obs-markers.


Correct me if I'm wrong, but it looks like you're thinking about a more
obs-marker centric way of displaying history. We have a command like
that in the evolve extension: "obslog": while hg log shows changesets
and parents/descendants, hg obslog shows changesets and
successors/predecessors.

For example, this would be the output of "hg obslog -r 5":

  @  022e174ded42 (5) A"
  |
  x  15900262089a (4) A"
  |rewritten(user) by test (Thu Jan 01 00:00:00 1970 +) as
022e174ded42
  |
  x  1737d8285b4d (3) A
  |rewritten(description) by test (Thu Jan 01 00:00:00 1970 +)
as 15900262089a
  |
  x  2a34000d3544 (1) A
   rewritten(parent) by test (Thu Jan 01 00:00:00 1970 +) as
1737d8285b4d

With this command, one marker is displayed by line, not an aggregate so
it would make sense to add support for operation there. It would be a
nice improvement to use the operation metadata to display a more
accurate verb in this function.

On Wed, 2017-07-12 at 09:28 -0700, Jun Wu wrote:
> As previously discussed in the "operation" thread [1]. I think we
> want to
> use &

[PATCH 3 of 4] configitems: register the 'progress.width' config

2017-07-13 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498787045 -7200
#  Fri Jun 30 03:44:05 2017 +0200
# Node ID 5f2e71c738b41b8a864ae8c7b38eff41985ebd99
# Parent  ad57894ea839e08f6b4f2dd3eb5c779c4746202e
# EXP-Topic config.register.special-case
configitems: register the 'progress.width' config

diff -r ad57894ea839 -r 5f2e71c738b4 mercurial/configitems.py
--- a/mercurial/configitems.py  Wed Jul 12 23:36:28 2017 +0200
+++ b/mercurial/configitems.py  Fri Jun 30 03:44:05 2017 +0200
@@ -163,6 +163,9 @@
 coreconfigitem('progress', 'estimate',
 default=2,
 )
+coreconfigitem('progress', 'width',
+default=dynamicdefault,
+)
 coreconfigitem('server', 'bundle1',
 default=True,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 4] configitems: register the 'color.pagermode' config

2017-07-13 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499895388 -7200
#  Wed Jul 12 23:36:28 2017 +0200
# Node ID ad57894ea839e08f6b4f2dd3eb5c779c4746202e
# Parent  afad2f9ae04d35cef5165b07a2987b0e5604924b
# EXP-Topic config.register.special-case
configitems: register the 'color.pagermode' config

diff -r afad2f9ae04d -r ad57894ea839 mercurial/configitems.py
--- a/mercurial/configitems.py  Wed Jul 12 23:36:10 2017 +0200
+++ b/mercurial/configitems.py  Wed Jul 12 23:36:28 2017 +0200
@@ -79,6 +79,9 @@
 coreconfigitem('color', 'mode',
 default='auto',
 )
+coreconfigitem('color', 'pagermode',
+default=dynamicdefault,
+)
 coreconfigitem('devel', 'all-warnings',
 default=False,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 4] configitems: register the 'worker.backgroundclose' config

2017-07-13 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498787157 -7200
#  Fri Jun 30 03:45:57 2017 +0200
# Node ID f62a1b71aa6959c3be5a88afe574b056b9ebec5a
# Parent  5f2e71c738b41b8a864ae8c7b38eff41985ebd99
# EXP-Topic config.register.special-case
configitems: register the 'worker.backgroundclose' config

diff -r 5f2e71c738b4 -r f62a1b71aa69 mercurial/configitems.py
--- a/mercurial/configitems.py  Fri Jun 30 03:44:05 2017 +0200
+++ b/mercurial/configitems.py  Fri Jun 30 03:45:57 2017 +0200
@@ -208,6 +208,9 @@
 coreconfigitem('ui', 'username',
 alias=[('ui', 'user')]
 )
+coreconfigitem('worker', 'backgroundclose',
+default=dynamicdefault,
+)
 # Windows defaults to a limit of 512 open files. A buffer of 128
 # should give us enough headway.
 coreconfigitem('worker', 'backgroundclosemaxqueue',
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 4] configitems: handle case were the default value is not static

2017-07-13 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499895370 -7200
#  Wed Jul 12 23:36:10 2017 +0200
# Node ID afad2f9ae04d35cef5165b07a2987b0e5604924b
# Parent  68e9762a357b19ec7751683e2fb80266c0d260ce
# EXP-Topic config.register.special-case
configitems: handle case were the default value is not static

In some case, the default of one value is derived from other value. We add a
way to register them anyway and an associated devel-warning.

The registration is very naive for the moment. We might be able to have a
better way for registering each of these cases but it could be done later.

diff -r 68e9762a357b -r afad2f9ae04d mercurial/configitems.py
--- a/mercurial/configitems.py  Mon Jul 10 23:09:52 2017 +0900
+++ b/mercurial/configitems.py  Wed Jul 12 23:36:10 2017 +0200
@@ -51,6 +51,9 @@
 raise error.ProgrammingError(msg % (item.section, item.name))
 section[item.name] = item
 
+# special value for case where the default is derived from other values
+dynamicdefault = object()
+
 # Registering actual config items
 
 def getitemregister(configtable):
diff -r 68e9762a357b -r afad2f9ae04d mercurial/ui.py
--- a/mercurial/ui.py   Mon Jul 10 23:09:52 2017 +0900
+++ b/mercurial/ui.py   Wed Jul 12 23:36:10 2017 +0200
@@ -457,11 +457,17 @@
 if default is _unset:
 if item is None:
 value = default
+elif item.default is configitems.dynamicdefault:
+value = None
+msg = "config item requires an explicit default value: '%s.%s'"
+msg %= (section, name)
+self.develwarn(msg, 2, 'warn-config-default')
 elif callable(item.default):
 value = item.default()
 else:
 value = item.default
-elif item is not None:
+elif (item is not None
+  and item.default is not configitems.dynamicdefault):
 msg = ("specifying a default value for a registered "
"config item: '%s.%s' '%s'")
 msg %= (section, name, default)
diff -r 68e9762a357b -r afad2f9ae04d tests/test-devel-warnings.t
--- a/tests/test-devel-warnings.t   Mon Jul 10 23:09:52 2017 +0900
+++ b/tests/test-devel-warnings.t   Wed Jul 12 23:36:10 2017 +0200
@@ -200,7 +200,7 @@
   $ cat << EOF > ${TESTTMP}/buggyconfig.py
   > """A small extension that tests our developer warnings for config"""
   > 
-  > from mercurial import registrar
+  > from mercurial import registrar, configitems
   > 
   > cmdtable = {}
   > command = registrar.command(cmdtable)
@@ -209,6 +209,7 @@
   > configitem = registrar.configitem(configtable)
   > 
   > configitem('test', 'some', default='foo')
+  > configitem('test', 'dynamic', default=configitems.dynamicdefault)
   > # overwrite a core config
   > configitem('ui', 'quiet', default=False)
   > configitem('ui', 'interactive', default=None)
@@ -218,6 +219,8 @@
   > repo.ui.config('ui', 'quiet', False)
   > repo.ui.config('ui', 'interactive', None)
   > repo.ui.config('test', 'some', 'foo')
+  > repo.ui.config('test', 'dynamic', 'some-required-default')
+  > repo.ui.config('test', 'dynamic')
   > EOF
 
   $ hg --config "extensions.buggyconfig=${TESTTMP}/buggyconfig.py" buggyconfig
@@ -226,5 +229,6 @@
   devel-warn: specifying a default value for a registered config item: 
'ui.quiet' 'False' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob)
   devel-warn: specifying a default value for a registered config item: 
'ui.interactive' 'None' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob)
   devel-warn: specifying a default value for a registered config item: 
'test.some' 'foo' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob)
+  devel-warn: config item requires an explicit default value: 'test.dynamic' 
at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob)
 
   $ cd ..
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3 V3] vfs: allow to pass more argument to audit

2017-07-13 Thread Boris Feld
On Fri, 2017-07-14 at 00:28 +0900, Yuya Nishihara wrote:
> On Tue, 11 Jul 2017 17:55:27 +0200, Boris Feld wrote:
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499768878 -7200
> > #  Tue Jul 11 12:27:58 2017 +0200
> > # Node ID 9addf65400ec8e6052a399c1586320988d73a321
> > # Parent  4672db164c986da4442bd864cd044512d975c3f2
> > # EXP-Topic vfs.ward
> > vfs: allow to pass more argument to audit
> 
> Looks generally good.
> 
> > We want to be able to do more precise check when auditing a path
> > depending of
> > the intend of the file access (eg read versus write). So we now
> > pass the 'mode'
> > and 'atomictemp' value to 'audit' and update the audit function to
> > accept them.
> > 
> > This will be put to use in the next changeset.
> > 
> > diff -r 4672db164c98 -r 9addf65400ec mercurial/pathutil.py
> > --- a/mercurial/pathutil.py Sat Jun 24 15:29:42 2017 -0700
> > +++ b/mercurial/pathutil.py Tue Jul 11 12:27:58 2017 +0200
> > @@ -46,7 +46,7 @@
> >  else:
> >  self.normcase = lambda x: x
> >  
> > -def __call__(self, path):
> > +def __call__(self, path, mode=None, atomictemp=None):
> >  '''Check the relative path.
> >  path may contain a pattern (e.g. foodir/**.txt)'''
> >  
> > diff -r 4672db164c98 -r 9addf65400ec mercurial/vfs.py
> > --- a/mercurial/vfs.py  Sat Jun 24 15:29:42 2017 -0700
> > +++ b/mercurial/vfs.py  Tue Jul 11 12:27:58 2017 +0200
> > @@ -306,7 +306,7 @@
> >  if audit:
> >  self.audit = pathutil.pathauditor(self.base)
> >  else:
> > -self.audit = util.always
> > +self.audit =  (lambda path, mode=None,
> > atomictemp=None: True)
> >  self.createmode = None
> >  self._trustnlink = None
> >  
> > @@ -360,7 +360,7 @@
> >  r = util.checkosfilename(path)
> >  if r:
> >  raise error.Abort("%s: %r" % (r, path))
> > -self.audit(path)
> > +self.audit(path, mode=mode, atomictemp=atomictemp)
> 
> Is 'atomictemp' needed? I don't think 'atomictemp' can be generalized
> well to
> the other vfs operations. And atomictemp=True doesn't mean
> repo.lock/wlock
> is unnecessary.

atomictemp wasn't technically necessary for this series, I included it
for completeness. If people starts wrapping pathauditor, adding
atomictemp later would results in breaking their wraps.

Do you want me to send a V4 to remove the atomictemp?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 11] phase: put retractboundary out of the loop in advanceboundary

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499718162 -7200
#  Mon Jul 10 22:22:42 2017 +0200
# Node ID 8c771f0d6e8d70b088abc2c31dc59be0d58ab9fa
# Parent  50243c975fc2ee605ebac493f4ab18d37117e46a
# EXP-Topic tr.changes.phases
phase: put retractboundary out of the loop in advanceboundary

It seems that we were calling retractboundary for each phases to process.
Putting the retractboundary out of the loop reduce the number of calls,
helping tracking the phases changes.

diff -r 50243c975fc2 -r 8c771f0d6e8d mercurial/phases.py
--- a/mercurial/phases.py   Tue Jul 11 05:06:01 2017 +0200
+++ b/mercurial/phases.py   Mon Jul 10 22:22:42 2017 +0200
@@ -301,9 +301,9 @@
 self._updateroots(phase, roots, tr)
 # some roots may need to be declared for lower phases
 delroots.extend(olds - roots)
-# declare deleted root in the target phase
-if targetphase != 0:
-self.retractboundary(repo, tr, targetphase, delroots)
+# declare deleted root in the target phase
+if targetphase != 0:
+self.retractboundary(repo, tr, targetphase, delroots)
 repo.invalidatevolatilesets()
 
 def retractboundary(self, repo, tr, targetphase, nodes):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 11] phases: track phase movements in 'advanceboundary'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499733592 -7200
#  Tue Jul 11 02:39:52 2017 +0200
# Node ID d578e17d880990375cf64d4c026e927987211fe7
# Parent  936da074fe26e45133672419d670febbfdb447a8
# EXP-Topic tr.changes.phases
phases: track phase movements in 'advanceboundary'

Makes advanceboundary record the phase movement of affected revisions in
tr.changes['phases'].

The tracking is not usable yet because the 'retractboundary' function can also
affect phases.

We'll improve that in the coming changesets.

diff -r 936da074fe26 -r d578e17d8809 mercurial/localrepo.py
--- a/mercurial/localrepo.pyMon Jul 10 22:18:41 2017 +0200
+++ b/mercurial/localrepo.pyTue Jul 11 02:39:52 2017 +0200
@@ -1136,6 +1136,7 @@
  checkambigfiles=_cachedfiles)
 tr.changes['revs'] = set()
 tr.changes['obsmarkers'] = set()
+tr.changes['phases'] = {}
 
 tr.hookargs['txnid'] = txnid
 # note: writing the fncache only during finalize mean that the file is
diff -r 936da074fe26 -r d578e17d8809 mercurial/phases.py
--- a/mercurial/phases.py   Mon Jul 10 22:18:41 2017 +0200
+++ b/mercurial/phases.py   Tue Jul 11 02:39:52 2017 +0200
@@ -154,6 +154,18 @@
 dirty = True
 return roots, dirty
 
+def _trackphasechange(data, rev, old, new):
+"""add a phase move the  dictionnary
+
+If data is None, nothing happens.
+"""
+if data is None:
+return
+existing = data.get(rev)
+if existing is not None:
+old = existing[0]
+data[rev] = (old, new)
+
 class phasecache(object):
 def __init__(self, repo, phasedefaults, _load=True):
 if _load:
@@ -289,8 +301,13 @@
 """
 # Be careful to preserve shallow-copied values: do not update
 # phaseroots values, replace them.
+if tr is None:
+phasetracking = None
+else:
+phasetracking = tr.changes.get('phases')
 
 repo = repo.unfiltered()
+
 delroots = [] # set of root deleted by this path
 for phase in xrange(targetphase + 1, len(allphases)):
 # filter nodes that are not in a compatible phase already
@@ -300,7 +317,11 @@
 break # no roots to move anymore
 
 olds = self.phaseroots[phase]
+
 affected = repo.revs('%ln::%ln', olds, nodes)
+for r in affected:
+_trackphasechange(phasetracking, r, self.phase(repo, r),
+  targetphase)
 
 roots = set(ctx.node() for ctx in repo.set(
 'roots((%ln::) - %ld)', olds, affected))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 11] phases: extract the intermediate set of affected revs

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499717921 -7200
#  Mon Jul 10 22:18:41 2017 +0200
# Node ID 936da074fe26e45133672419d670febbfdb447a8
# Parent  8c771f0d6e8d70b088abc2c31dc59be0d58ab9fa
# EXP-Topic tr.changes.phases
phases: extract the intermediate set of affected revs

When advancing phases, we compute the new roots for the phases above. During
this process, we need to compute all the revisions that change phases (to the
new target phases). Extract these revisions into a separate variable. This
will be useful to record the phase changes in the transaction.

diff -r 8c771f0d6e8d -r 936da074fe26 mercurial/phases.py
--- a/mercurial/phases.py   Mon Jul 10 22:22:42 2017 +0200
+++ b/mercurial/phases.py   Mon Jul 10 22:18:41 2017 +0200
@@ -283,6 +283,10 @@
 tr.hookargs['phases_moved'] = '1'
 
 def advanceboundary(self, repo, tr, targetphase, nodes):
+"""Set all 'nodes' to phase 'targetphase'
+
+Nodes with a phase lower than 'targetphase' are not affected.
+"""
 # Be careful to preserve shallow-copied values: do not update
 # phaseroots values, replace them.
 
@@ -294,9 +298,12 @@
  if self.phase(repo, repo[n].rev()) >= phase]
 if not nodes:
 break # no roots to move anymore
+
 olds = self.phaseroots[phase]
+affected = repo.revs('%ln::%ln', olds, nodes)
+
 roots = set(ctx.node() for ctx in repo.set(
-'roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
+'roots((%ln::) - %ld)', olds, affected))
 if olds != roots:
 self._updateroots(phase, roots, tr)
 # some roots may need to be declared for lower phases
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 11] localrepo: use the 'registernew' function to set the phase of new commit

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499727927 -7200
#  Tue Jul 11 01:05:27 2017 +0200
# Node ID 210688a668f0ff9f8395b2789b29fdb2a1de2c64
# Parent  f700a612e24139e8ee411d208791fc6d4ac9bab3
# EXP-Topic tr.changes.phases
localrepo: use the 'registernew' function to set the phase of new commit

diff -r f700a612e241 -r 210688a668f0 mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 03:47:25 2017 +0200
+++ b/mercurial/localrepo.pyTue Jul 11 01:05:27 2017 +0200
@@ -1872,7 +1872,7 @@
 # be compliant anyway
 #
 # if minimal phase was 0 we don't need to retract anything
-phases.retractboundary(self, tr, targetphase, [n])
+phases.registernew(self, tr, targetphase, [n])
 tr.close()
 return n
 finally:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 11] phases: extract the core of boundary retraction in '_retractboundary'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499723416 -7200
#  Mon Jul 10 23:50:16 2017 +0200
# Node ID 2a23f55b1b3487c7d43c0709efa900c01235b3cf
# Parent  d578e17d880990375cf64d4c026e927987211fe7
# EXP-Topic tr.changes.phases
phases: extract the core of boundary retraction in '_retractboundary'

At the moment the 'retractboundary' function is called for multiple reasons:

First, actually retracting boundaries. There are only two cases for theses:
'hg phase --force' and 'hg qimport'. This will need extra graph computation to
retrieve the phase changes.

Second, setting the phases of newly added changesets. In this case we already
know all the affected nodes and we just needs to register different
information (old phase is None).

Third, when reducing the set of roots when advancing phase. The phase are
already properly tracked so we do not needs anything else in this case.

To deal with this difference in phase tracking, we extract the core logic into
a private method that all three cases can use.

diff -r d578e17d8809 -r 2a23f55b1b34 mercurial/phases.py
--- a/mercurial/phases.py   Tue Jul 11 02:39:52 2017 +0200
+++ b/mercurial/phases.py   Mon Jul 10 23:50:16 2017 +0200
@@ -331,10 +331,14 @@
 delroots.extend(olds - roots)
 # declare deleted root in the target phase
 if targetphase != 0:
-self.retractboundary(repo, tr, targetphase, delroots)
+self._retractboundary(repo, tr, targetphase, delroots)
 repo.invalidatevolatilesets()
 
 def retractboundary(self, repo, tr, targetphase, nodes):
+self._retractboundary(repo, tr, targetphase, nodes)
+repo.invalidatevolatilesets()
+
+def _retractboundary(self, repo, tr, targetphase, nodes):
 # Be careful to preserve shallow-copied values: do not update
 # phaseroots values, replace them.
 
@@ -343,6 +347,7 @@
 newroots = [n for n in nodes
 if self.phase(repo, repo[n].rev()) < targetphase]
 if newroots:
+
 if nullid in newroots:
 raise error.Abort(_('cannot change null revision phase'))
 currentroots = currentroots.copy()
@@ -360,7 +365,6 @@
 finalroots.update(ctx.node() for ctx in updatedroots)
 
 self._updateroots(targetphase, finalroots, tr)
-repo.invalidatevolatilesets()
 
 def filterunknown(self, repo):
 """remove unknown nodes from the phase boundary
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 11] phases: track phase changes from 'retractboundary'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499883060 -7200
#  Wed Jul 12 20:11:00 2017 +0200
# Node ID 14007d8eba4dd21240bb243e45394fa0dc70545b
# Parent  d90b8e445f0f48ebcac362fb1df6f5498f814f90
# EXP-Topic tr.changes.phases
phases: track phase changes from 'retractboundary'

We adds new computation to find and record the revision affected by the
boundary retraction. This add more complication to the function but this seems
fine since it is only used in a couple of rare and explicit cases (`hg phase
--force` and `hg qimport`).

Having strong tracking of phase changes is worth the effort.

diff -r d90b8e445f0f -r 14007d8eba4d mercurial/phases.py
--- a/mercurial/phases.py   Wed Jul 12 23:15:09 2017 +0200
+++ b/mercurial/phases.py   Wed Jul 12 20:11:00 2017 +0200
@@ -348,7 +348,30 @@
 repo.invalidatevolatilesets()
 
 def retractboundary(self, repo, tr, targetphase, nodes):
-self._retractboundary(repo, tr, targetphase, nodes)
+oldroots = self.phaseroots[:targetphase + 1]
+if tr is None:
+phasetracking = None
+else:
+phasetracking = tr.changes.get('phases')
+repo = repo.unfiltered()
+if (self._retractboundary(repo, tr, targetphase, nodes)
+and phasetracking is not None):
+
+# find the affected revisions
+new = self.phaseroots[targetphase]
+old = oldroots[targetphase]
+affected = set(repo.revs('(%ln::) - (%ln::)', new, old))
+
+# find the phase of the affected revision
+for phase in xrange(targetphase, -1, -1):
+if phase:
+roots = oldroots[phase]
+revs = set(repo.revs('%ln::%ld', roots, affected))
+affected -= revs
+else: # public phase
+revs = affected
+for r in revs:
+_trackphasechange(phasetracking, r, phase, targetphase)
 repo.invalidatevolatilesets()
 
 def _retractboundary(self, repo, tr, targetphase, nodes):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 11] phases: add a 'registernew' method to set new phases

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499737645 -7200
#  Tue Jul 11 03:47:25 2017 +0200
# Node ID f700a612e24139e8ee411d208791fc6d4ac9bab3
# Parent  2a23f55b1b3487c7d43c0709efa900c01235b3cf
# EXP-Topic tr.changes.phases
phases: add a 'registernew' method to set new phases

This new function will be used by code that adds new changesets. It ajusts the
phase boundary to make sure added changesets are at least in their target
phase (they end up in an higher phase if their parents are in a higher phase).

Having a dedicated function also simplify the phases tracking. All the new
nodes are passed as argument, so we know that all of them needs to have their
new phase registered. We also know that no other nodes will be affected, so no
extra computation are needed.

This function differ from 'retractboundary' where some nodes might change
phase while some other might not. It can also affect nodes not passed as
parameters.

These simplification also apply to the computation itself. For now we use
'_retractboundary' there by convenience, but we may introduces simpler code
later.

While registering new revisions, we still need to check the actual phases of
the added node because it might be higher than the target phase (eg: target is
draft but parent is secret).

We will migrate users over the next changesets.

diff -r 2a23f55b1b34 -r f700a612e241 mercurial/phases.py
--- a/mercurial/phases.py   Mon Jul 10 23:50:16 2017 +0200
+++ b/mercurial/phases.py   Tue Jul 11 03:47:25 2017 +0200
@@ -294,6 +294,19 @@
 tr.addfilegenerator('phase', ('phaseroots',), self._write)
 tr.hookargs['phases_moved'] = '1'
 
+def registernew(self, repo, tr, targetphase, nodes):
+repo = repo.unfiltered()
+self._retractboundary(repo, tr, targetphase, nodes)
+if tr is not None and 'phases' in tr.changes:
+phasetracking = tr.changes['phases']
+torev = repo.changelog.rev
+phase = self.phase
+for n in nodes:
+rev = torev(n)
+revphase = phase(repo, rev)
+_trackphasechange(phasetracking, rev, None, revphase)
+repo.invalidatevolatilesets()
+
 def advanceboundary(self, repo, tr, targetphase, nodes):
 """Set all 'nodes' to phase 'targetphase'
 
@@ -417,6 +430,16 @@
 phcache.retractboundary(repo, tr, targetphase, nodes)
 repo._phasecache.replace(phcache)
 
+def registernew(repo, tr, targetphase, nodes):
+"""register a new revision and its phase
+
+Code adding revisions to the repository should use this function to
+set new changeset in their target phase (or higher).
+"""
+phcache = repo._phasecache.copy()
+phcache.registernew(repo, tr, targetphase, nodes)
+repo._phasecache.replace(phcache)
+
 def listphases(repo):
 """List phases root for serialization over pushkey"""
 # Use ordered dictionary so behavior is deterministic.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 11] phases: rework phase movement code in 'cg.apply' to use 'registernew'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499728656 -7200
#  Tue Jul 11 01:17:36 2017 +0200
# Node ID c60ee8233517c9e84d5907ea2822f16667d31ca8
# Parent  d331c624636b7c88f54170c7d600e6d4480aa23b
# EXP-Topic tr.changes.phases
phases: rework phase movement code in 'cg.apply' to use 'registernew'

We rework the code to call 'registernew' before any other phase advancement.
This make 'changegroup.apply' register correct phase movement for the added
and bundled nodes.

diff -r d331c624636b -r c60ee8233517 mercurial/changegroup.py
--- a/mercurial/changegroup.py  Tue Jul 11 00:59:23 2017 +0200
+++ b/mercurial/changegroup.py  Tue Jul 11 01:17:36 2017 +0200
@@ -356,6 +356,7 @@
 repo.hook('pretxnchangegroup', throw=True, **hookargs)
 
 added = [cl.node(r) for r in xrange(clstart, clend)]
+phaseall = None
 if srctype in ('push', 'serve'):
 # Old servers can not push the boundary themselves.
 # New servers won't push the boundary if changeset already
@@ -364,16 +365,19 @@
 # We should not use added here but the list of all change in
 # the bundle
 if repo.publishing():
-phases.advanceboundary(repo, tr, phases.public, cgnodes)
+targetphase = phaseall = phases.public
 else:
+# closer target phase computation
+
 # Those changesets have been pushed from the
 # outside, their phases are going to be pushed
 # alongside. Therefor `targetphase` is
 # ignored.
-phases.advanceboundary(repo, tr, phases.draft, cgnodes)
-phases.retractboundary(repo, tr, phases.draft, added)
-else:
-phases.retractboundary(repo, tr, targetphase, added)
+targetphase = phaseall = phases.draft
+if added:
+phases.registernew(repo, tr, targetphase, added)
+if phaseall is not None:
+phases.advanceboundary(repo, tr, phaseall, cgnodes)
 
 if changesets > 0:
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 11 of 11] phases: test phases tracking at the transaction level

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499891988 -7200
#  Wed Jul 12 22:39:48 2017 +0200
# Node ID 0ccb45f63c27d373c02a87e6544e684db27659fe
# Parent  14007d8eba4dd21240bb243e45394fa0dc70545b
# EXP-Topic tr.changes.phases
phases: test phases tracking at the transaction level

Now that we have all tracking in place, the data in `tr.changes['phases']`
dictionary should be correct and we should test it.

It is a bit late in the cycle to discuss to add any public API (eg: hooks)
that expose the data to the user, so we just add a small test extension
displaying the data. It is enabled for the phases tests.

New output have been manually checked for consistency.

diff -r 14007d8eba4d -r 0ccb45f63c27 tests/test-phases-exchange.t
--- a/tests/test-phases-exchange.t  Wed Jul 12 20:11:00 2017 +0200
+++ b/tests/test-phases-exchange.t  Wed Jul 12 22:39:48 2017 +0200
@@ -1,5 +1,10 @@
 #require killdaemons
 
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > phasereport=$TESTDIR/testlib/ext-phase-report.py
+  > EOF
+
   $ hgph() { hg log -G --template "{rev} {phase} {desc} - {node|short}\n" $*; }
 
   $ mkcommit() {
@@ -13,9 +18,13 @@
   $ hg init alpha
   $ cd alpha
   $ mkcommit a-A
+  test-debug-phase: new rev 0:  x -> 1
   $ mkcommit a-B
+  test-debug-phase: new rev 1:  x -> 1
   $ mkcommit a-C
+  test-debug-phase: new rev 2:  x -> 1
   $ mkcommit a-D
+  test-debug-phase: new rev 3:  x -> 1
   $ hgph
   @  3 draft a-D - b555f63b6063
   |
@@ -34,6 +43,10 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 2 files
+  test-debug-phase: new rev 0:  x -> 0
+  test-debug-phase: new rev 1:  x -> 0
+  test-debug-phase: move rev 0: 1 -> 0
+  test-debug-phase: move rev 1: 1 -> 0
   $ hgph
   @  3 draft a-D - b555f63b6063
   |
@@ -52,6 +65,7 @@
   
   $ hg up -q
   $ mkcommit b-A
+  test-debug-phase: new rev 2:  x -> 1
   $ hgph
   @  2 draft b-A - f54f1bb90ff3
   |
@@ -66,6 +80,8 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 2 files (+1 heads)
+  test-debug-phase: new rev 3:  x -> 0
+  test-debug-phase: new rev 4:  x -> 0
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hgph
   o  4 public a-D - b555f63b6063
@@ -96,6 +112,7 @@
   pushing to ../beta
   searching for changes
   no changes found
+  test-debug-phase: move rev 2: 1 -> 0
   [1]
   $ hgph
   @  3 draft a-D - b555f63b6063
@@ -110,6 +127,7 @@
   pushing to ../beta
   searching for changes
   no changes found
+  test-debug-phase: move rev 3: 1 -> 0
   [1]
   $ hgph
   @  3 public a-D - b555f63b6063
@@ -130,6 +148,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
+  test-debug-phase: new rev 4:  x -> 0
   (run 'hg heads' to see heads, 'hg merge' to merge)
 
   $ cd ../beta
@@ -148,6 +167,7 @@
   pulling from ../alpha
   searching for changes
   no changes found
+  test-debug-phase: move rev 2: 1 -> 0
   $ hgph
   o  4 public a-D - b555f63b6063
   |
@@ -182,6 +202,11 @@
   adding manifests
   adding file changes
   added 5 changesets with 5 changes to 5 files (+1 heads)
+  test-debug-phase: new rev 0:  x -> 1
+  test-debug-phase: new rev 1:  x -> 1
+  test-debug-phase: new rev 2:  x -> 1
+  test-debug-phase: new rev 3:  x -> 1
+  test-debug-phase: new rev 4:  x -> 1
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hgph
   o  4 draft a-D - b555f63b6063
@@ -210,6 +235,9 @@
   adding manifests
   adding file changes
   added 3 changesets with 3 changes to 3 files
+  test-debug-phase: new rev 0:  x -> 1
+  test-debug-phase: new rev 1:  x -> 1
+  test-debug-phase: new rev 2:  x -> 1
   (run 'hg update' to get a working copy)
   $ hgph
   o  2 draft a-C - 54acac6f23ab
@@ -228,6 +256,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
+  test-debug-phase: new rev 3:  x -> 1
   (run 'hg heads' to see heads, 'hg merge' to merge)
   $ hgph
   o  3 draft b-A - f54f1bb90ff3
@@ -250,6 +279,10 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+  test-debug-phase: move rev 0: 1 -> 0
+  test-debug-phase: move rev 1: 1 -> 0
+  test-debug-phase: move rev 2: 1 -> 0
+  test-debug-phase: new rev 4:  x -> 0
   (run 'hg update' to get a working copy)
   $ hgph # f54f1bb90ff3 stay draft, not ancestor of -r
   o  4 public a-D - b555f63b6063
@@ -267,7 +300,9 @@
 
   $ hg up -q f54f1bb90ff3
   $ mkcommit n-A
+  test-debug-phase: new rev 5:  x -> 1
   $ mkcommit n-B
+  test-debug-phase: new rev 6:  x -> 1
   $ hgph
   @  6 draft n-B - 145e75495359
   |
@@ -291,6 +326,12 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 2 files
+  test-debug-phase: move rev 0: 1 -&

[PATCH 09 of 11] phases: detect when boundaries has been actually retracted

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499894109 -7200
#  Wed Jul 12 23:15:09 2017 +0200
# Node ID d90b8e445f0f48ebcac362fb1df6f5498f814f90
# Parent  c60ee8233517c9e84d5907ea2822f16667d31ca8
# EXP-Topic tr.changes.phases
phases: detect when boundaries has been actually retracted

It is useful to detect noop and avoid expensive operations in this case.

We return the information to inform the caller of a possible update. Top level
function might need to react to the phase update (eg: invalidating some
caches, tracking phase change).

diff -r c60ee8233517 -r d90b8e445f0f mercurial/phases.py
--- a/mercurial/phases.py   Tue Jul 11 01:17:36 2017 +0200
+++ b/mercurial/phases.py   Wed Jul 12 23:15:09 2017 +0200
@@ -357,6 +357,7 @@
 
 repo = repo.unfiltered()
 currentroots = self.phaseroots[targetphase]
+finalroots = oldroots = set(currentroots)
 newroots = [n for n in nodes
 if self.phase(repo, repo[n].rev()) < targetphase]
 if newroots:
@@ -376,8 +377,10 @@
 finalroots = set(n for n in currentroots if repo[n].rev() <
  minnewroot)
 finalroots.update(ctx.node() for ctx in updatedroots)
-
+if finalroots != oldroots:
 self._updateroots(targetphase, finalroots, tr)
+return True
+return False
 
 def filterunknown(self, repo):
 """remove unknown nodes from the phase boundary
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 11] convert: use the new 'phase.registernew' function

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499727563 -7200
#  Tue Jul 11 00:59:23 2017 +0200
# Node ID d331c624636b7c88f54170c7d600e6d4480aa23b
# Parent  210688a668f0ff9f8395b2789b29fdb2a1de2c64
# EXP-Topic tr.changes.phases
convert: use the new 'phase.registernew' function

diff -r 210688a668f0 -r d331c624636b hgext/convert/hg.py
--- a/hgext/convert/hg.py   Tue Jul 11 01:05:27 2017 +0200
+++ b/hgext/convert/hg.py   Tue Jul 11 00:59:23 2017 +0200
@@ -345,8 +345,8 @@
 if commit.rev != node:
 ctx = self.repo[node]
 if ctx.phase() < phases.draft:
-phases.retractboundary(self.repo, tr, phases.draft,
-   [ctx.node()])
+phases.registernew(self.repo, tr, phases.draft,
+   [ctx.node()])
 
 text = "(octopus merge fixup)\n"
 p2 = node
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] phases: remove trace of addednodes in the 'phase-heads' handling

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499973055 -7200
#  Thu Jul 13 21:10:55 2017 +0200
# Node ID 23a2483541d50b8dce47a061a92a2b2089a42202
# Parent  50243c975fc2ee605ebac493f4ab18d37117e46a
# EXP-Topic cleanup.changegroup
phases: remove trace of addednodes in the 'phase-heads' handling

updatephases have no use of the 'addednodes' parameter since 50243c975fc2.
However caller are still passing it for nothing, remove the parameter and
remove computing of the added nodes in caller.

diff -r 50243c975fc2 -r 23a2483541d5 mercurial/bundle2.py
--- a/mercurial/bundle2.py  Tue Jul 11 05:06:01 2017 +0200
+++ b/mercurial/bundle2.py  Thu Jul 13 21:10:55 2017 +0200
@@ -1788,11 +1788,7 @@
 def handlephases(op, inpart):
 """apply phases from bundle part to repo"""
 headsbyphase = _readphaseheads(inpart)
-addednodes = []
-for entry in op.records['changegroup']:
-addednodes.extend(entry['addednodes'])
-phases.updatephases(op.repo.unfiltered(), op.gettransaction(), 
headsbyphase,
-addednodes)
+phases.updatephases(op.repo.unfiltered(), op.gettransaction(), 
headsbyphase)
 
 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
 def handlepushkeyreply(op, inpart):
diff -r 50243c975fc2 -r 23a2483541d5 mercurial/phases.py
--- a/mercurial/phases.py   Tue Jul 11 05:06:01 2017 +0200
+++ b/mercurial/phases.py   Thu Jul 13 21:10:55 2017 +0200
@@ -446,7 +446,7 @@
 headsbyphase[phase] = [cl.node(r) for r in repo.revs(revset, subset)]
 return headsbyphase
 
-def updatephases(repo, tr, headsbyphase, addednodes):
+def updatephases(repo, tr, headsbyphase):
 """Updates the repo with the given phase heads"""
 # Now advance phase boundaries of all but secret phase
 for phase in allphases[:-1]:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] changegroup: stop returning and recording added nodes in 'cg.apply'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499972886 -7200
#  Thu Jul 13 21:08:06 2017 +0200
# Node ID ddf2ab3e3add92ed5cddbeb9a33679891d74094d
# Parent  23a2483541d50b8dce47a061a92a2b2089a42202
# EXP-Topic cleanup.changegroup
changegroup: stop returning and recording added nodes in 'cg.apply'

cg.apply used to returns the added nodes. Callers doesn't have a use for it
anymore, remove the added node and stops recording it in the current
operation.

This information was added in the current release cycle so no extensions
breakage should happens.

diff -r 23a2483541d5 -r ddf2ab3e3add mercurial/bundle2.py
--- a/mercurial/bundle2.py  Thu Jul 13 21:10:55 2017 +0200
+++ b/mercurial/bundle2.py  Thu Jul 13 21:08:06 2017 +0200
@@ -403,10 +403,9 @@
 return op
 
 def _processchangegroup(op, cg, tr, source, url, **kwargs):
-ret, addednodes = cg.apply(op.repo, tr, source, url, **kwargs)
+ret = cg.apply(op.repo, tr, source, url, **kwargs)
 op.records.add('changegroup', {
 'return': ret,
-'addednodes': addednodes,
 })
 return ret
 
diff -r 23a2483541d5 -r ddf2ab3e3add mercurial/changegroup.py
--- a/mercurial/changegroup.py  Thu Jul 13 21:10:55 2017 +0200
+++ b/mercurial/changegroup.py  Thu Jul 13 21:08:06 2017 +0200
@@ -408,7 +408,7 @@
 ret = deltaheads - 1
 else:
 ret = deltaheads + 1
-return ret, added
+return ret
 
 class cg2unpacker(cg1unpacker):
 """Unpacker for cg2 streams.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 3 V4] vfs: allow to pass more argument to audit

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499768878 -7200
#  Tue Jul 11 12:27:58 2017 +0200
# Node ID 201d9cbd64a276db278552a8924206afb67b1a4c
# Parent  4672db164c986da4442bd864cd044512d975c3f2
# EXP-Topic vfs.ward
vfs: allow to pass more argument to audit

We want to be able to do more precise check when auditing a path depending of
the intend of the file access (eg read versus write). So we now pass the 'mode'
 value to 'audit' and update the audit function to accept them.

This will be put to use in the next changeset.

diff -r 4672db164c98 -r 201d9cbd64a2 mercurial/pathutil.py
--- a/mercurial/pathutil.py Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/pathutil.py Tue Jul 11 12:27:58 2017 +0200
@@ -46,7 +46,7 @@
 else:
 self.normcase = lambda x: x
 
-def __call__(self, path):
+def __call__(self, path, mode=None):
 '''Check the relative path.
 path may contain a pattern (e.g. foodir/**.txt)'''
 
diff -r 4672db164c98 -r 201d9cbd64a2 mercurial/vfs.py
--- a/mercurial/vfs.py  Sat Jun 24 15:29:42 2017 -0700
+++ b/mercurial/vfs.py  Tue Jul 11 12:27:58 2017 +0200
@@ -306,7 +306,7 @@
 if audit:
 self.audit = pathutil.pathauditor(self.base)
 else:
-self.audit = util.always
+self.audit =  (lambda path, mode=None: True)
 self.createmode = None
 self._trustnlink = None
 
@@ -360,7 +360,7 @@
 r = util.checkosfilename(path)
 if r:
 raise error.Abort("%s: %r" % (r, path))
-self.audit(path)
+self.audit(path, mode=mode)
 f = self.join(path)
 
 if not text and "b" not in mode:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3 V4] repovfs: add a ward to check if locks are properly taken

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499769497 -7200
#  Tue Jul 11 12:38:17 2017 +0200
# Node ID cea0a88164c6d003b43fe542ec12def2662c1273
# Parent  201d9cbd64a276db278552a8924206afb67b1a4c
# EXP-Topic vfs.ward
repovfs: add a ward to check if locks are properly taken


When the appropriate developer warning are enabled, We wrap 'repo.vfs.audit' to
check for locks when accessing file in '.hg' for writing. Another changeset will
add a 'ward' for the store vfs (svfs).

This check system have caught a handful of locking issues that  has been fixed
in previous series (mostly in 4.0). I expect another batch to be caught in third
party extensions.

We introduces two real exceptions from extensions 'blackbox.log' (because a lot 
of
read-only operations add entry to it), and 'last-email.txt' (because 'hg email'
is currently a read only operation and there is value to keep it this way).

In addition we are currently allowing bisect to operate outside of the lock
because the current code is a bit hard to get properly locked for now. Multiple
clean up have been made but there is still a couple of them to do and the freeze
is coming.

diff -r 201d9cbd64a2 -r cea0a88164c6 hgext/blackbox.py
--- a/hgext/blackbox.py Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/blackbox.py Tue Jul 11 12:38:17 2017 +0200
@@ -236,6 +236,7 @@
 
 if util.safehasattr(ui, 'setrepo'):
 ui.setrepo(repo)
+repo._wlockfreeprefix.add('blackbox.log')
 
 @command('^blackbox',
 [('l', 'limit', 10, _('the number of events to show')),
diff -r 201d9cbd64a2 -r cea0a88164c6 hgext/journal.py
--- a/hgext/journal.py  Tue Jul 11 12:27:58 2017 +0200
+++ b/hgext/journal.py  Tue Jul 11 12:38:17 2017 +0200
@@ -69,6 +69,7 @@
 def reposetup(ui, repo):
 if repo.local():
 repo.journal = journalstorage(repo)
+repo._wlockfreeprefix.add('namejournal')
 
 def runcommand(orig, lui, repo, cmd, fullargs, *args):
 """Track the command line options for recording in the journal"""
diff -r 201d9cbd64a2 -r cea0a88164c6 hgext/patchbomb.py
--- a/hgext/patchbomb.pyTue Jul 11 12:27:58 2017 +0200
+++ b/hgext/patchbomb.pyTue Jul 11 12:38:17 2017 +0200
@@ -122,6 +122,10 @@
 cmdutil.extraexport.append('pullurl')
 cmdutil.extraexportmap['pullurl'] = _addpullheader
 
+def reposetup(ui, repo):
+if not repo.local():
+return
+repo._wlockfreeprefix.add('last-email.txt')
 
 def prompt(ui, prompt, default=None, rest=':'):
 if default:
diff -r 201d9cbd64a2 -r cea0a88164c6 mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:27:58 2017 +0200
+++ b/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
@@ -289,6 +289,25 @@
 # only functions defined in module of enabled extensions are invoked
 featuresetupfuncs = set()
 
+# list of prefix for file which can be written without 'wlock'
+# Extensions should extend this list when needed
+_wlockfreeprefix = set([# We migh consider requiring 'wlock' for the next
+# two, but pretty much all the existing code assume
+# wlock is not needed so we keep them excluded for
+# now.
+'hgrc',
+'requires',
+# XXX cache is a complicatged business someone
+# should investigate this in depth at some point
+'cache/',
+# XXX shouldn't be dirstate covered by the wlock?
+'dirstate',
+# XXX bisect was still a bit too messy at the time
+# this changeset was introduced. Someone should fix
+# the remainig bit and drop this line
+'bisect.state',
+])
+
 def __init__(self, baseui, path, create=False):
 self.requirements = set()
 self.filtername = None
@@ -308,10 +327,13 @@
 self.auditor = pathutil.pathauditor(self.root, self._checknested)
 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
 realfs=False)
-self.vfs = vfsmod.vfs(self.path)
 self.baseui = baseui
 self.ui = baseui.copy()
 self.ui.copy = baseui.copy # prevent copying repo configuration
+self.vfs = vfsmod.vfs(self.path)
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+self.vfs.audit = self._getvfsward(self.vfs.audit)
 # A list o

[PATCH 3 of 3 V4] reposvfs: add a ward to check if locks are properly taken

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1470672882 -7200
#  Mon Aug 08 18:14:42 2016 +0200
# Node ID e132c6e95c50c6f23bd0084e5247032bb8f155ea
# Parent  cea0a88164c6d003b43fe542ec12def2662c1273
# EXP-Topic vfs.ward
reposvfs: add a ward to check if locks are properly taken

we wrap 'repo.svfs.audit' to check for the store lock when accessing file in
'.hg/store' for writing. This caught a couple of instance where the transaction
was released after the lock, we should probably have a dedicated checker for
that case.

diff -r cea0a88164c6 -r e132c6e95c50 mercurial/localrepo.py
--- a/mercurial/localrepo.pyTue Jul 11 12:38:17 2017 +0200
+++ b/mercurial/localrepo.pyMon Aug 08 18:14:42 2016 +0200
@@ -411,6 +411,12 @@
 self.svfs = self.store.vfs
 self.sjoin = self.store.join
 self.vfs.createmode = self.store.createmode
+if (self.ui.configbool('devel', 'all-warnings') or
+self.ui.configbool('devel', 'check-locks')):
+if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
+self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
+else: # standard vfs
+self.svfs.audit = self._getsvfsward(self.svfs.audit)
 self._applyopenerreqs()
 if create:
 self._writerequirements()
@@ -481,6 +487,25 @@
 return ret
 return checkvfs
 
+def _getsvfsward(self, origfunc):
+"""build a ward for self.svfs"""
+rref = weakref.ref(self)
+def checksvfs(path, mode=None):
+ret = origfunc(path, mode=mode)
+repo = rref()
+if repo is None or not util.safehasattr(repo, '_lockref'):
+return
+if mode in (None, 'r', 'rb'):
+return
+if path.startswith(repo.sharedpath):
+# truncate name relative to the repository (.hg)
+path = path[len(repo.sharedpath) + 1:]
+if repo._currentlock(repo._lockref) is None:
+repo.ui.develwarn('write with no lock: "%s"' % path,
+  stacklevel=3)
+return ret
+return checksvfs
+
 def close(self):
 self._writecaches()
 
diff -r cea0a88164c6 -r e132c6e95c50 tests/test-devel-warnings.t
--- a/tests/test-devel-warnings.t   Tue Jul 11 12:38:17 2017 +0200
+++ b/tests/test-devel-warnings.t   Mon Aug 08 18:14:42 2016 +0200
@@ -49,6 +49,11 @@
   > with repo.vfs(b'branch', 'a'):
   > pass
   > 
+  > @command(b'no-lock-write', [], '')
+  > def nolockwrite(ui, repo):
+  > with repo.svfs(b'fncache', 'a'):
+  > pass
+  > 
   > @command(b'stripintr', [], '')
   > def stripintr(ui, repo):
   > lo = repo.lock()
@@ -114,6 +119,9 @@
   $ hg no-wlock-write
   devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* 
(nowlockwrite) (glob)
 
+  $ hg no-lock-write
+  devel-warn: write with no lock: "fncache" at: $TESTTMP/buggylocking.py:* 
(nolockwrite) (glob)
+
 Stripping from a transaction
 
   $ echo a > a
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 9 V2] configitems: register the 'bugzilla.strip' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414649 -7200
#  Fri Jul 07 10:04:09 2017 +0200
# Node ID 57dd90ce60747fa07e60f6924b8337aa1ea11620
# Parent  0a8570d6f449291b4c64733d67d4702f30d9e6a8
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.strip' config

diff -r 0a8570d6f449 -r 57dd90ce6074 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:07 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:09 2017 +0200
@@ -357,6 +357,9 @@
  r'(?P(?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
  r'\.?\s*(?:h(?:ours?)?\s*(?P\d*(?:\.\d+)?))?')
 )
+configitem('bugzilla', 'strip',
+default=0,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -1055,7 +1058,7 @@
 def webroot(root):
 '''strip leading prefix of repo root and turn into
 url-safe path.'''
-count = int(self.ui.config('bugzilla', 'strip', 0))
+count = int(self.ui.config('bugzilla', 'strip'))
 root = util.pconvert(root)
 while count > 0:
 c = root.find('/')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 9 V2] configitems: register the 'bugzilla.template' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414653 -7200
#  Fri Jul 07 10:04:13 2017 +0200
# Node ID 4bd1ace2b13873052c6376f0656e55b3b11910e3
# Parent  b6f7fa0605d77198e6459b1634e023cfa984a4f1
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.template' config

diff -r b6f7fa0605d7 -r 4bd1ace2b138 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:11 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:13 2017 +0200
@@ -363,6 +363,9 @@
 configitem('bugzilla', 'style',
 default=None,
 )
+configitem('bugzilla', 'template',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 9 V2] configitems: register the 'bugzilla.timeout' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414655 -7200
#  Fri Jul 07 10:04:15 2017 +0200
# Node ID 65e197186ba97e77bb9db6f28cd8a967ff46b98d
# Parent  4bd1ace2b13873052c6376f0656e55b3b11910e3
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.timeout' config

diff -r 4bd1ace2b138 -r 65e197186ba9 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:13 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:15 2017 +0200
@@ -366,6 +366,9 @@
 configitem('bugzilla', 'template',
 default=None,
 )
+configitem('bugzilla', 'timeout',
+default=5,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -445,7 +448,7 @@
 user = self.ui.config('bugzilla', 'user', 'bugs')
 passwd = self.ui.config('bugzilla', 'password')
 db = self.ui.config('bugzilla', 'db')
-timeout = int(self.ui.config('bugzilla', 'timeout', 5))
+timeout = int(self.ui.config('bugzilla', 'timeout'))
 self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
  (host, db, user, '*' * len(passwd)))
 self.conn = bzmysql._MySQLdb.connect(host=host,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9 V2] configitems: register the 'bugzilla.style' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414651 -7200
#  Fri Jul 07 10:04:11 2017 +0200
# Node ID b6f7fa0605d77198e6459b1634e023cfa984a4f1
# Parent  57dd90ce60747fa07e60f6924b8337aa1ea11620
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.style' config

diff -r 57dd90ce6074 -r b6f7fa0605d7 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:09 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:11 2017 +0200
@@ -360,6 +360,9 @@
 configitem('bugzilla', 'strip',
 default=0,
 )
+configitem('bugzilla', 'style',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 9 V2] configitems: register the 'bugzilla.user' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414657 -7200
#  Fri Jul 07 10:04:17 2017 +0200
# Node ID 5e7b59b762cc7f2e3006abda288be95abf747967
# Parent  65e197186ba97e77bb9db6f28cd8a967ff46b98d
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.user' config

diff -r 65e197186ba9 -r 5e7b59b762cc hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:15 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:17 2017 +0200
@@ -369,6 +369,9 @@
 configitem('bugzilla', 'timeout',
 default=5,
 )
+configitem('bugzilla', 'user',
+default='bugs',
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -445,7 +448,7 @@
 bzaccess.__init__(self, ui)
 
 host = self.ui.config('bugzilla', 'host')
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 passwd = self.ui.config('bugzilla', 'password')
 db = self.ui.config('bugzilla', 'db')
 timeout = int(self.ui.config('bugzilla', 'timeout'))
@@ -693,7 +696,7 @@
 bzweb = self.ui.config('bugzilla', 'bzurl')
 bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi"
 
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 passwd = self.ui.config('bugzilla', 'password')
 
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
@@ -810,7 +813,7 @@
 matches = self.bzproxy.User.get({'match': [user],
  'token': self.bztoken})
 if not matches['users']:
-user = self.ui.config('bugzilla', 'user', 'bugs')
+user = self.ui.config('bugzilla', 'user')
 matches = self.bzproxy.User.get({'match': [user],
  'token': self.bztoken})
 if not matches['users']:
@@ -852,7 +855,7 @@
 bz = self.ui.config('bugzilla', 'bzurl')
 self.bzroot = '/'.join([bz, 'rest'])
 self.apikey = self.ui.config('bugzilla', 'apikey')
-self.user = self.ui.config('bugzilla', 'user', 'bugs')
+self.user = self.ui.config('bugzilla', 'user')
 self.passwd = self.ui.config('bugzilla', 'password')
 self.fixstatus = self.ui.config('bugzilla', 'fixstatus')
 self.fixresolution = self.ui.config('bugzilla', 'fixresolution')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 9 V2] configitems: register the 'bugzilla.version' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414661 -7200
#  Fri Jul 07 10:04:21 2017 +0200
# Node ID 7a9c79633732fd90db14a33d13803cf34eb35028
# Parent  802831b0828c7c4910b8707d04a3678e9abaa523
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.version' config

diff -r 802831b0828c -r 7a9c79633732 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:19 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:21 2017 +0200
@@ -375,6 +375,9 @@
 configitem('bugzilla', 'usermap',
 default=None,
 )
+configitem('bugzilla', 'version',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9 V2] configitems: register the 'bugzilla.usermap' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414659 -7200
#  Fri Jul 07 10:04:19 2017 +0200
# Node ID 802831b0828c7c4910b8707d04a3678e9abaa523
# Parent  5e7b59b762cc7f2e3006abda288be95abf747967
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.usermap' config

diff -r 5e7b59b762cc -r 802831b0828c hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:17 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:19 2017 +0200
@@ -372,6 +372,9 @@
 configitem('bugzilla', 'user',
 default='bugs',
 )
+configitem('bugzilla', 'usermap',
+default=None,
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 9 of 9 V2] bugzilla: move the default regexp for fix in the config declaration

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1500041857 -7200
#  Fri Jul 14 16:17:37 2017 +0200
# Node ID 9da870e7c1057d9067da0eebea81d6adcc170664
# Parent  7a9c79633732fd90db14a33d13803cf34eb35028
# EXP-Topic config.register.bugzilla
bugzilla: move the default regexp for fix in the config declaration

This mimic the change requested by Yuya for '_default_bug_re'.

diff -r 7a9c79633732 -r 9da870e7c105 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:21 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 14 16:17:37 2017 +0200
@@ -338,7 +338,10 @@
 default='bugs',
 )
 configitem('bugzilla', 'fixregexp',
-default=lambda: bugzilla._default_fix_re,
+default=(r'fix(?:es)?\s*(?:bugs?\s*)?,?\s*'
+ r'(?:nos?\.?|num(?:ber)?s?)?\s*'
+ r'(?P(?:#?\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
+ r'\.?\s*(?:h(?:ours?)?\s*(?P\d*(?:\.\d+)?))?')
 )
 configitem('bugzilla', 'fixresolution',
 default='FIXED',
@@ -989,11 +992,6 @@
 'restapi': bzrestapi,
 }
 
-_default_fix_re = (r'fix(?:es)?\s*(?:bugs?\s*)?,?\s*'
-   r'(?:nos?\.?|num(?:ber)?s?)?\s*'
-   r'(?P(?:#?\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
-   r'\.?\s*(?:h(?:ours?)?\s*(?P\d*(?:\.\d+)?))?')
-
 def __init__(self, ui, repo):
 self.ui = ui
 self.repo = repo
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9 V2] configitems: register the 'bugzilla.regexp' config

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499414647 -7200
#  Fri Jul 07 10:04:07 2017 +0200
# Node ID 0a8570d6f449291b4c64733d67d4702f30d9e6a8
# Parent  f793e535b4b9ee6e6eaa19b0a5028e6d6c154ce2
# EXP-Topic config.register.bugzilla
configitems: register the 'bugzilla.regexp' config

The default value is moved from the class to the config registration.

diff -r f793e535b4b9 -r 0a8570d6f449 hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jul 07 10:04:05 2017 +0200
+++ b/hgext/bugzilla.py Fri Jul 07 10:04:07 2017 +0200
@@ -352,6 +352,11 @@
 configitem('bugzilla', 'password',
 default=None,
 )
+configitem('bugzilla', 'regexp',
+default=(r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
+ r'(?P(?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
+ r'\.?\s*(?:h(?:ours?)?\s*(?P\d*(?:\.\d+)?))?')
+)
 
 class bzaccess(object):
 '''Base class for access to Bugzilla.'''
@@ -963,10 +968,6 @@
 'restapi': bzrestapi,
 }
 
-_default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
-   r'(?P(?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
-   r'\.?\s*(?:h(?:ours?)?\s*(?P\d*(?:\.\d+)?))?')
-
 _default_fix_re = (r'fix(?:es)?\s*(?:bugs?\s*)?,?\s*'
r'(?:nos?\.?|num(?:ber)?s?)?\s*'
r'(?P(?:#?\d+\s*(?:,?\s*(?:and)?)?\s*)+)'
@@ -985,8 +986,7 @@
 self.bzdriver = bzclass(self.ui)
 
 self.bug_re = re.compile(
-self.ui.config('bugzilla', 'regexp',
-   bugzilla._default_bug_re), re.IGNORECASE)
+self.ui.config('bugzilla', 'regexp'), re.IGNORECASE)
 self.fix_re = re.compile(
 self.ui.config('bugzilla', 'fixregexp'), re.IGNORECASE)
 self.split_re = re.compile(r'\D+')
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 11 of 11] phases: test phases tracking at the transaction level

2017-07-14 Thread Boris Feld
On Fri, 2017-07-14 at 12:39 -0400, Augie Fackler wrote:
> On Fri, Jul 14, 2017 at 03:25:45PM +0200, Boris Feld wrote:
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1499891988 -7200
> > #  Wed Jul 12 22:39:48 2017 +0200
> > # Node ID 0ccb45f63c27d373c02a87e6544e684db27659fe
> > # Parent  14007d8eba4dd21240bb243e45394fa0dc70545b
> > # EXP-Topic tr.changes.phases
> > phases: test phases tracking at the transaction level
> 
> queued, thanks
> 
> Does this open the door to printing when changes advance from draft
> to
> public as a result of a pull?

Yes!

We planned to work on push/pull report for the next release. Since it's
so close to the freeze, we could try adding a simple message for phases
this weekend if there is no backward-compatibility constraint.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 12] bookmark: use 'applychanges' for bookmark deletion

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499699056 -7200
#  Mon Jul 10 17:04:16 2017 +0200
# Node ID e94048e3d4a0422207fce8c146c6be62fd701f85
# Parent  e94441a7d9e334c5b9e604b9f6cabe4182cd5550
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' for bookmark deletion

diff -r e94441a7d9e3 -r e94048e3d4a0 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:01:34 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 17:04:16 2017 +0200
@@ -715,13 +715,14 @@
 Raises an abort error if mark does not exist.
 """
 marks = repo._bookmarks
+changes = []
 for mark in names:
 if mark not in marks:
 raise error.Abort(_("bookmark '%s' does not exist") % mark)
 if mark == repo._activebookmark:
 deactivate(repo)
-del marks[mark]
-marks.recordchange(tr)
+changes.append((mark, None))
+marks.applychanges(repo, tr, changes)
 
 def rename(repo, tr, old, new, force=False, inactive=False):
 """rename a bookmark from old to new
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 12] bookmark: use 'applychanges' for bookmark renaming

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499699300 -7200
#  Mon Jul 10 17:08:20 2017 +0200
# Node ID 9f589c0e64901c5a15add541d5213574664fa218
# Parent  e94048e3d4a0422207fce8c146c6be62fd701f85
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' for bookmark renaming

diff -r e94048e3d4a0 -r 9f589c0e6490 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:04:16 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 17:08:20 2017 +0200
@@ -739,11 +739,10 @@
 if old not in marks:
 raise error.Abort(_("bookmark '%s' does not exist") % old)
 marks.checkconflict(mark, force)
-marks[mark] = marks[old]
+changes = [(mark, marks[old]), (old, None)]
+marks.applychanges(repo, tr, changes)
 if repo._activebookmark == old and not inactive:
 activate(repo, mark)
-del marks[old]
-marks.recordchange(tr)
 
 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
 """add a list of bookmarks
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 12] bookmark: use 'applychanges' when updating from a remote

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499700137 -7200
#  Mon Jul 10 17:22:17 2017 +0200
# Node ID 76dde98a2c0bc24ab110ba3ecc06698c735adf57
# Parent  34170eeaa6fbfb43b1ceac331ae50678afe10610
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' when updating from a remote

diff -r 34170eeaa6fb -r 76dde98a2c0b mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:10:56 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 17:22:17 2017 +0200
@@ -579,10 +579,11 @@
 
 if changed:
 tr = trfunc()
+changes = []
 for b, node, writer, msg in sorted(changed):
-localmarks[b] = node
+changes.append((b, node))
 writer(msg)
-localmarks.recordchange(tr)
+localmarks.applychanges(repo, tr, changes)
 
 def incoming(ui, repo, other):
 '''Show bookmarks incoming from other to repo
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 12] bookmark: introduce a 'applychanges' function to gather bookmark movement

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499698894 -7200
#  Mon Jul 10 17:01:34 2017 +0200
# Node ID e94441a7d9e334c5b9e604b9f6cabe4182cd5550
# Parent  7c33adc823e008019f0f06ff5f357ca628f3ab34
# EXP-Topic tr.changes.bookmarks
bookmark: introduce a 'applychanges' function to gather bookmark movement

We want to track bookmark movement within a transaction. For this we need a
more centralized way to update bookmarks.

For this purpose we introduce a new 'applychanges' method that apply a list of
changes encoded as '(name, node)'. We'll cover all bookmark updating code to
this new method in later changesets and add bookmark move in the transaction
when all will be migrated.

diff -r 7c33adc823e0 -r e94441a7d9e3 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyThu Mar 30 00:33:00 2017 -0400
+++ b/mercurial/bookmarks.pyMon Jul 10 17:01:34 2017 +0200
@@ -109,6 +109,16 @@
 self._clean = False
 return dict.__delitem__(self, key)
 
+def applychanges(self, repo, tr, changes):
+"""Apply a list of changes to bookmarks
+"""
+for name, node in changes:
+if node is None:
+del self[name]
+else:
+self[name] = node
+self.recordchange(tr)
+
 def recordchange(self, tr):
 """record that bookmarks have been changed in a transaction
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 12] bookmark: use 'applychanges' when updating a bookmark through pushkey

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499700268 -7200
#  Mon Jul 10 17:24:28 2017 +0200
# Node ID 1fc04ebe411862e9648382fa2a0790d8bdaf3862
# Parent  76dde98a2c0bc24ab110ba3ecc06698c735adf57
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' when updating a bookmark through pushkey

diff -r 76dde98a2c0b -r 1fc04ebe4118 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:22:17 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 17:24:28 2017 +0200
@@ -402,12 +402,12 @@
 if existing != old and existing != new:
 return False
 if new == '':
-del marks[key]
+changes = [(key, None)]
 else:
 if new not in repo:
 return False
-marks[key] = repo[new].node()
-marks.recordchange(tr)
+changes = [(key, repo[new].node())]
+marks.applychanges(repo, tr, changes)
 tr.close()
 return True
 finally:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 12] bookmark: use 'applychanges' for adding new bookmark

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499699456 -7200
#  Mon Jul 10 17:10:56 2017 +0200
# Node ID 34170eeaa6fbfb43b1ceac331ae50678afe10610
# Parent  9f589c0e64901c5a15add541d5213574664fa218
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' for adding new bookmark

diff -r 9f589c0e6490 -r 34170eeaa6fb mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:08:20 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 17:10:56 2017 +0200
@@ -758,6 +758,7 @@
 marks = repo._bookmarks
 cur = repo.changectx('.').node()
 newact = None
+changes = []
 for mark in names:
 mark = checkformat(repo, mark)
 if newact is None:
@@ -769,12 +770,12 @@
 if rev:
 tgt = scmutil.revsingle(repo, rev).node()
 marks.checkconflict(mark, force, tgt)
-marks[mark] = tgt
+changes.append((mark, tgt))
+marks.applychanges(repo, tr, changes)
 if not inactive and cur == marks[newact] and not rev:
 activate(repo, newact)
 elif cur != tgt and newact == repo._activebookmark:
 deactivate(repo)
-marks.recordchange(tr)
 
 def _printbookmarks(ui, repo, bmarks, **opts):
 """private method to print bookmarks
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 12] bookmark: use 'applychanges' when updating bookmark in histedit

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499700533 -7200
#  Mon Jul 10 17:28:53 2017 +0200
# Node ID 85ce60fb04bbbf060d7657209802b6a0e0cc030a
# Parent  1fc04ebe411862e9648382fa2a0790d8bdaf3862
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' when updating bookmark in histedit

diff -r 1fc04ebe4118 -r 85ce60fb04bb hgext/histedit.py
--- a/hgext/histedit.py Mon Jul 10 17:24:28 2017 +0200
+++ b/hgext/histedit.py Mon Jul 10 17:28:53 2017 +0200
@@ -1561,9 +1561,10 @@
 if oldbmarks:
 with repo.lock(), repo.transaction('histedit') as tr:
 marks = repo._bookmarks
+changes = []
 for name in oldbmarks:
-marks[name] = newtopmost
-marks.recordchange(tr)
+changes.append((name, newtopmost))
+marks.applychanges(repo, tr, changes)
 
 def cleanupnode(ui, repo, nodes):
 """strip a group of nodes from the repository
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 12] bookmark: use 'applychanges' in the convert extension

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499700620 -7200
#  Mon Jul 10 17:30:20 2017 +0200
# Node ID 0d37c4628a9cc6491e35ad69e8c780ccaf3d26bc
# Parent  85ce60fb04bbbf060d7657209802b6a0e0cc030a
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' in the convert extension

diff -r 85ce60fb04bb -r 0d37c4628a9c hgext/convert/hg.py
--- a/hgext/convert/hg.py   Mon Jul 10 17:28:53 2017 +0200
+++ b/hgext/convert/hg.py   Mon Jul 10 17:30:20 2017 +0200
@@ -425,9 +425,9 @@
 tr = self.repo.transaction('bookmark')
 self.ui.status(_("updating bookmarks\n"))
 destmarks = self.repo._bookmarks
-for bookmark in updatedbookmark:
-destmarks[bookmark] = nodemod.bin(updatedbookmark[bookmark])
-destmarks.recordchange(tr)
+changes = [(bookmark, nodemod.bin(updatedbookmark[bookmark]))
+   for bookmark in updatedbookmark]
+destmarks.applychanges(self.repo, tr, changes)
 tr.close()
 finally:
 lockmod.release(lock, wlock, tr)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 12 of 12] bookmarks: use 'applychanges' for bookmark update

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499708423 -7200
#  Mon Jul 10 19:40:23 2017 +0200
# Node ID c8af08d67851fae61c1cf459f0f0bf20f61b9298
# Parent  bbebf6b3d2514134fc750903de90ec515cf4c4d3
# EXP-Topic tr.changes.bookmarks
bookmarks: use 'applychanges' for bookmark update

There is still some use of 'deletedivergent' bookmark here. They will be taken
care of later. The 'deletedivergent' code needs some rework before fitting in
the new world.

diff -r bbebf6b3d251 -r c8af08d67851 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:46:47 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 19:40:23 2017 +0200
@@ -350,6 +350,7 @@
 if not active:
 return False
 
+bmchanges = []
 if marks[active] in parents:
 new = repo[node]
 divs = [repo[b] for b in marks
@@ -357,7 +358,7 @@
 anc = repo.changelog.ancestors([new.rev()])
 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
 if validdest(repo, repo[marks[active]], new):
-marks[active] = new.node()
+bmchanges.append((active, new.node()))
 update = True
 
 if deletedivergent(repo, deletefrom, active):
@@ -368,7 +369,7 @@
 try:
 lock = repo.lock()
 tr = repo.transaction('bookmark')
-marks.recordchange(tr)
+marks.applychanges(repo, tr, bmchanges)
 tr.close()
 finally:
 lockmod.release(tr, lock)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 12] bookmark: use 'applychanges' when stripping

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499701068 -7200
#  Mon Jul 10 17:37:48 2017 +0200
# Node ID 32399e89b8ed9662b07d6a656a447e6ef5bafc1b
# Parent  0d37c4628a9cc6491e35ad69e8c780ccaf3d26bc
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' when stripping

diff -r 0d37c4628a9c -r 32399e89b8ed hgext/strip.py
--- a/hgext/strip.pyMon Jul 10 17:30:20 2017 +0200
+++ b/hgext/strip.pyMon Jul 10 17:37:48 2017 +0200
@@ -78,9 +78,7 @@
 with repo.transaction('strip') as tr:
 if repo._activebookmark in bookmarks:
 bookmarksmod.deactivate(repo)
-for bookmark in bookmarks:
-del repomarks[bookmark]
-repomarks.recordchange(tr)
+repomarks.applychanges(repo, tr, [(b, None) for b in 
bookmarks])
 for bookmark in sorted(bookmarks):
 ui.write(_("bookmark '%s' deleted\n") % bookmark)
 
@@ -157,9 +155,8 @@
 revs.update(set(rsrevs))
 if not revs:
 with repo.lock(), repo.transaction('bookmark') as tr:
-for bookmark in bookmarks:
-del repomarks[bookmark]
-repomarks.recordchange(tr)
+bmchanges = [(b, None) for b in bookmarks]
+repomarks.applychanges(repo, tr, bmchanges)
 for bookmark in sorted(bookmarks):
 ui.write(_("bookmark '%s' deleted\n") % bookmark)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 12] bookmark: use 'applychanges' in the mq extension

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499701465 -7200
#  Mon Jul 10 17:44:25 2017 +0200
# Node ID e8d6ea8639cdbdd8af729fbad09f508210e02723
# Parent  32399e89b8ed9662b07d6a656a447e6ef5bafc1b
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' in the mq extension

diff -r 32399e89b8ed -r e8d6ea8639cd hgext/mq.py
--- a/hgext/mq.py   Mon Jul 10 17:37:48 2017 +0200
+++ b/hgext/mq.py   Mon Jul 10 17:44:25 2017 +0200
@@ -1834,9 +1834,7 @@
 patchf.close()
 
 marks = repo._bookmarks
-for bm in bmlist:
-marks[bm] = n
-marks.recordchange(tr)
+marks.applychanges(repo, tr, [(bm, n) for bm in bmlist])
 tr.close()
 
 self.applied.append(statusentry(n, patchfn))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 11 of 12] bookmark: use 'applychanges' in 'repair.strip'

2017-07-14 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499701607 -7200
#  Mon Jul 10 17:46:47 2017 +0200
# Node ID bbebf6b3d2514134fc750903de90ec515cf4c4d3
# Parent  e8d6ea8639cdbdd8af729fbad09f508210e02723
# EXP-Topic tr.changes.bookmarks
bookmark: use 'applychanges' in 'repair.strip'

diff -r e8d6ea8639cd -r bbebf6b3d251 mercurial/repair.py
--- a/mercurial/repair.py   Mon Jul 10 17:44:25 2017 +0200
+++ b/mercurial/repair.py   Mon Jul 10 17:46:47 2017 +0200
@@ -219,11 +219,10 @@
 f.close()
 repo._phasecache.invalidate()
 
-for m in updatebm:
-bm[m] = repo[newbmtarget].node()
 
 with repo.transaction('repair') as tr:
-bm.recordchange(tr)
+bmchanges = [(m, repo[newbmtarget].node()) for m in updatebm]
+bm.applychanges(repo, tr, bmchanges)
 
 # remove undo files
 for undovfs, undofile in repo.undofiles():
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 10 of 14] obsstore: pass a repository object for initialisation

2017-07-14 Thread Boris Feld
On Fri, 2017-07-14 at 14:11 -0400, Augie Fackler wrote:
> On Sun, Jul 09, 2017 at 07:55:22PM +0200, Boris Feld wrote:
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1495197862 -7200
> > #  Fri May 19 14:44:22 2017 +0200
> > # Node ID 985d753d4f5799f2a332140adedb06efd465d62b
> > # Parent  63214f4d9a766761259b650539eede424413e6a2
> > # EXP-Topic obs-cache
> > obsstore: pass a repository object for initialisation
> > 
> > The cache will needs a repository object (to grab a 'vfs'), so we
> > pass a repo object instead of just the 'svfs' and we grab the
> > 'svfs'
> > from there.
> 
> I suspect I'll get to it, but why does this cache want to know about
> anything outside of svfs?
> 
> I'm pretty uncomfortable (architecturally) with passing all of `self`
> into the cache layer.

The obscache need the vfs and not the svfs because caches lives in .hg
and not in .hg/store.

Passing the whole repo and grabbing what we need seemed simpler.

> 
> > 
> > diff -r 63214f4d9a76 -r 985d753d4f57 contrib/perf.py
> > --- a/contrib/perf.py   Fri May 19 14:46:26 2017 +0200
> > +++ b/contrib/perf.py   Fri May 19 14:44:22 2017 +0200
> > @@ -1391,8 +1391,7 @@
> > 
> >  Result is the number of markers in the repo."""
> >  timer, fm = gettimer(ui)
> > -svfs = getsvfs(repo)
> > -timer(lambda: len(obsolete.obsstore(svfs)))
> > +timer(lambda: len(obsolete.obsstore(repo)))
> >  fm.end()
> > 
> >  @command('perflrucachedict', formatteropts +
> > diff -r 63214f4d9a76 -r 985d753d4f57 mercurial/obsolete.py
> > --- a/mercurial/obsolete.py Fri May 19 14:46:26 2017 +0200
> > +++ b/mercurial/obsolete.py Fri May 19 14:44:22 2017 +0200
> > @@ -519,10 +519,10 @@
> >  # 1024 byte should be about 10 markers in average
> >  _obskeyspan = 1024
> > 
> > -def __init__(self, svfs, defaultformat=_fm1version,
> > readonly=False):
> > +def __init__(self, repo, defaultformat=_fm1version,
> > readonly=False):
> >  # caches for various obsolescence related cache
> >  self.caches = {}
> > -self.svfs = svfs
> > +self.svfs = repo.svfs
> >  self._defaultformat = defaultformat
> >  self._readonly = readonly
> > 
> > @@ -799,7 +799,7 @@
> >  if defaultformat is not None:
> >  kwargs['defaultformat'] = defaultformat
> >  readonly = not isenabled(repo, createmarkersopt)
> > -store = obsstore(repo.svfs, readonly=readonly, **kwargs)
> > +store = obsstore(repo, readonly=readonly, **kwargs)
> >  if store and readonly:
> >  ui.warn(_('obsolete feature not enabled but %i markers
> > found!\n')
> >  % len(list(store)))
> > ___
> > Mercurial-devel mailing list
> > Mercurial-devel@mercurial-scm.org
> > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 10 of 14] obsstore: pass a repository object for initialisation

2017-07-14 Thread Boris Feld
On Fri, 2017-07-14 at 14:16 -0400, Augie Fackler wrote:
> > On Jul 14, 2017, at 14:15, Boris Feld 
> > wrote:
> > 
> > On Fri, 2017-07-14 at 14:11 -0400, Augie Fackler wrote:
> > > On Sun, Jul 09, 2017 at 07:55:22PM +0200, Boris Feld wrote:
> > > > # HG changeset patch
> > > > # User Boris Feld 
> > > > # Date 1495197862 -7200
> > > > #  Fri May 19 14:44:22 2017 +0200
> > > > # Node ID 985d753d4f5799f2a332140adedb06efd465d62b
> > > > # Parent  63214f4d9a766761259b650539eede424413e6a2
> > > > # EXP-Topic obs-cache
> > > > obsstore: pass a repository object for initialisation
> > > > 
> > > > The cache will needs a repository object (to grab a 'vfs'), so
> > > > we
> > > > pass a repo object instead of just the 'svfs' and we grab the
> > > > 'svfs'
> > > > from there.
> > > 
> > > I suspect I'll get to it, but why does this cache want to know
> > > about
> > > anything outside of svfs?
> > > 
> > > I'm pretty uncomfortable (architecturally) with passing all of
> > > `self`
> > > into the cache layer.
> > 
> > The obscache need the vfs and not the svfs because caches lives in
> > .hg
> > and not in .hg/store.
> > 
> > Passing the whole repo and grabbing what we need seemed simpler.
> 
> It's simpler today, but more of a potential headache later if someone
> decides to just retain the whole repo in the cache. I'd rather not do
> it.

I understand the danger.

Should we pass vfs and svfs explicitly in the V2 then?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 12 of 14] obscache: use the obscache to compute the obsolete set

2017-07-14 Thread Boris Feld
On Fri, 2017-07-14 at 14:16 -0400, Augie Fackler wrote:
> On Sun, Jul 09, 2017 at 07:55:24PM +0200, Boris Feld wrote:
> > # HG changeset patch
> > # User Boris Feld 
> > # Date 1495198021 -7200
> > #  Fri May 19 14:47:01 2017 +0200
> > # Node ID 3a93e99b0e718befd57a32615a14fd0d3c194456
> > # Parent  f8953ed43f8d1b146dcff688030133f0d6123a49
> > # EXP-Topic obs-cache
> > obscache: use the obscache to compute the obsolete set
> > 
> > Now that we have a cache and that the cache is kept up to date, we
> > can use it to
> > speeds up the obsolete set computation. This way, we no longer need
> > to load the
> > obsstore for most operation.
> > 
> > On the mercurial-core repository, this provides a significant speed
> > up for
> > operation that do not need further obsolescence information:
> > 
> > > command  | before | after |
> > > id -r @  |  0.670 | 0.093 |
> > > log -r @ |  0.951 | 0.916 |
> > > diff |  0.070 | 0.069 |
> > > diff -r .~1  |  0.705 | 0.120 |
> > > export @ |  0.672 | 0.103 |
> > > log -G -r draft()|  1.117 | 1.084 |
> > > log -G -r draft()|  1.063 | 1.064 |
> > >   -T "{node} {troubles}" ||   |
> > > log -G -r tip|  0.658 | 0.086 |
> > >   -T "{node} {desc}" ||   |
> 
> These timings look pretty good, though I find some of the numbers
> underwhelming (eg 'hg log -r @' seems like it shouldn't be anywhere
> *near* that slow).
> 
> I think given the history here, and that I know Jun has something
> related coming in a few weeks, I'm going to put this series on hold
> until after 4.3 is done so we can get some comparisons between
> approaches, as I believe his solution requires a little less in the
> way of creative caching layers.
> 
> In more detail: the radixlink approach to speeding up obsmarkers
> interests me a lot because it speeds up more than this does, and is
> close on the things where they're similar. If I can have one caching
> layer instead of two, I'd like that, and given how late in the cycle
> it is and the timetable I've heard from Jun I'm happy to let hg 4.3
> not get perf wins today and just make 4.4 the release where we get
> this sorted out.

The obsmarkers exchange will need the proposed two layers cache. Radix
link is a great improvement for obsolescence access of individual
changesets, but discovery needs to compute and exposes repository wide
properties that needs to be cached in order to be efficient.

Pushing these new caches layers in core would help us experimenting
caches on useful things. For example, with these classes in core, we
could trivially add a cache for the current obsmarkers discovery (not
obshashrange). This will probably save 15s from the current obsmarkers
discovery.

Implementing these abstract caches outside of core is cumbersome,
queuing patch 4 would helps us a lot.

Using the new abstract caches with branchmap will take some times
because branchmap has multiple specific quirks. We won't have time to
do that properly before the freeze.

> 
> > 
> > The obsstore loading operation usually disappear from execution
> > profile.
> > 
> > The speeds up rely on a couple of different mechanism:
> > 
> > * First, not having to parse the obsstore provides a massive
> > speedup:
> > 
> >   Time spent computing 'obsolete', no obsstore pre-loaded.
> > 
> > before: wall 0.449502 comb 0.46 user 0.42 sys 0.04
> > (best of 17)
> > after:  wall 0.005752 comb 0.01 user 0.01 sys 0.00
> > (best of 340)
> > 
> > * Second keeping the computation fully in the revision space (no
> > usage of node),
> >   raise and extra 4x speedup.
> > 
> >   Time spent computing 'obsolete', obsstore preloaded:
> > 
> > before: wall 0.007684 comb 0.00 user 0.00 sys 0.00
> > (best of 305)
> > after:  wall 0.001928 comb 0.00 user 0.00 sys 0.00
> > (best of 1250)
> > 
> > To keep the changeset simple, we assume the cache is up to date
> > (from the last
> > transaction). This won't be true when both old and new clients
> > access the
> > repository. (with the special case of no new transactions since
> > last upgrade).
> > We'll address this issue in the next couple of changesets.
> > 
> > This changesets is a first step to install the basic. There are a
> > couple of easy
> > impr

Re: Community video chats?

2017-07-15 Thread Boris Feld
I've put a reminder in my calendar for 19pm paris time.
On Fri, 2017-07-14 at 20:00 -0400, Augie Fackler wrote:
> Yes, that's right. 
> On Jul 14, 2017 7:40 PM, "Sean Farley"  wrote:
> > Augie Fackler  writes:
> > 
> > 
> > 
> > >> On Jul 13, 2017, at 04:17, Boris Feld 
> > wrote:
> > 
> > >>
> > 
> > >> On Tue, 2017-07-11 at 16:08 -0400, Augie Fackler wrote:
> > 
> > >>>> On Jul 11, 2017, at 15:47, Phillip Cohen 
> > 
> > >>>> wrote:
> > 
> > >>>>
> > 
> > >>>> Great, glad there's interest.
> > 
> > >>>>
> > 
> > >>>> How would Thursday at 10am PST / 1pm EST  / 6pm UTC work? This
> > is
> > 
> > >>>> early enough for London to join, but not too early that
> > California
> > 
> > >>>> won't. Friday mornings are less desirable (because that's
> > Friday
> > 
> > >>>> evening in London) but Monday and Tuesday morning could work
> > as
> > 
> > >>>> well.
> > 
> > >>>
> > 
> > >>> I can't do 1300-1500 America/New_York on Thursdays. Pretty much
> > any
> > 
> > >>> other time in the week would work. Maybe shoot for Tuesdays?
> > 
> > >>>
> > 
> > >>
> > 
> > >> I'm also interested, 6pm UTC (5pm or 7pm could works too) on
> > every day
> > 
> > >> except Tuesdays would works for me with a preference for
> > Thursday.
> > 
> > >
> > 
> > > I've blocked off 1300-1430 America/New_York on the 19th for a
> > test run of this.
> > 
> > 
> > 
> > That's 10am-11:30am for us in San Francisco, right? If so, then
> > I've
> > 
> > also put this in my calendar.
> > 
> > ___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 05 of 10] bookmark: use 'divergent2delete' in checkconflict

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499709752 -7200
#  Mon Jul 10 20:02:32 2017 +0200
# Node ID 3c70ad3b3daaeb8b2386b9d8760ac69e6dce0ecc
# Parent  08c2a3d309e8619e0cc3ec16c4ae02722b9a1118
# EXP-Topic tr.changes.bookmarks
bookmark: use 'divergent2delete' in checkconflict

checkconflict used to also do some bookmark deletion in case of divergence. It
is a bit suspicious given the function name, but it's not the goal of this
series.

In order to unify bookmarks changing, checkconflict now return the list of
divergent bookmarks to clean up and the callers must clean them by calling
applyphases.

diff -r 08c2a3d309e8 -r 3c70ad3b3daa mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 19:12:25 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 20:02:32 2017 +0200
@@ -183,13 +183,15 @@
 
 If force is supplied, then forcibly move the bookmark to a new commit
 regardless if it is a move forward.
+
+If divergent bookmark are to be deleted, they will be returned as list.
 """
 cur = self._repo.changectx('.').node()
 if mark in self and not force:
 if target:
 if self[mark] == target and target == cur:
 # re-activating a bookmark
-return
+return []
 rev = self._repo[target].rev()
 anc = self._repo.changelog.ancestors([rev])
 bmctx = self._repo[self[mark]]
@@ -200,17 +202,16 @@
 # the bookmark across branches when a revision is specified
 # that contains a divergent bookmark
 if bmctx.rev() not in anc and target in divs:
-deletedivergent(self._repo, [target], mark)
-return
+return divergent2delete(self._repo, [target], mark)
 
 deletefrom = [b for b in divs
   if self._repo[b].rev() in anc or b == target]
-deletedivergent(self._repo, deletefrom, mark)
+delbms = divergent2delete(self._repo, deletefrom, mark)
 if validdest(self._repo, bmctx, self._repo[target]):
 self._repo.ui.status(
 _("moving bookmark '%s' forward from %s\n") %
 (mark, short(bmctx.node(
-return
+return delbms
 raise error.Abort(_("bookmark '%s' already exists "
 "(use -f to force)") % mark)
 if ((mark in self._repo.branchmap() or
@@ -228,6 +229,7 @@
   "(did you leave a -r out of an 'hg bookmark' "
   "command?)\n")
 % mark)
+return []
 
 def _readactive(repo, marks):
 """
@@ -747,8 +749,10 @@
 mark = checkformat(repo, new)
 if old not in marks:
 raise error.Abort(_("bookmark '%s' does not exist") % old)
-marks.checkconflict(mark, force)
-changes = [(mark, marks[old]), (old, None)]
+changes = []
+for bm in marks.checkconflict(mark, force):
+changes.append((bm, None))
+changes.extend([(mark, marks[old]), (old, None)])
 marks.applychanges(repo, tr, changes)
 if repo._activebookmark == old and not inactive:
 activate(repo, mark)
@@ -778,7 +782,8 @@
 tgt = cur
 if rev:
 tgt = scmutil.revsingle(repo, rev).node()
-marks.checkconflict(mark, force, tgt)
+for bm in marks.checkconflict(mark, force, tgt):
+changes.append((bm, None))
 changes.append((mark, tgt))
 marks.applychanges(repo, tr, changes)
 if not inactive and cur == marks[newact] and not rev:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 07 of 10] bookmark: deprecate 'recordchange' in favor of 'applychanges'

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499710203 -7200
#  Mon Jul 10 20:10:03 2017 +0200
# Node ID 94da61e581672f5c9616f1ad1336cfaadbdc96a9
# Parent  d8f4f481d22c4fd4b606c2635c9b2f0fada67e8c
# EXP-Topic tr.changes.bookmarks
bookmark: deprecate 'recordchange' in favor of 'applychanges'

Now that we have migrated all in-core caller of 'recordchange' to
'applychanges', deprecate 'recordchange' so external callers will move to the
new unified method.

diff -r d8f4f481d22c -r 94da61e58167 hgext/share.py
--- a/hgext/share.pyMon Jul 10 20:06:15 2017 +0200
+++ b/hgext/share.pyMon Jul 10 20:10:03 2017 +0200
@@ -141,7 +141,7 @@
 
 def extsetup(ui):
 extensions.wrapfunction(bookmarks, '_getbkfile', getbkfile)
-extensions.wrapfunction(bookmarks.bmstore, 'recordchange', recordchange)
+extensions.wrapfunction(bookmarks.bmstore, '_recordchange', recordchange)
 extensions.wrapfunction(bookmarks.bmstore, '_writerepo', writerepo)
 extensions.wrapcommand(commands.table, 'clone', clone)
 
diff -r d8f4f481d22c -r 94da61e58167 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 20:06:15 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 20:10:03 2017 +0200
@@ -117,9 +117,15 @@
 del self[name]
 else:
 self[name] = node
-self.recordchange(tr)
+self._recordchange(tr)
 
 def recordchange(self, tr):
+msg = ("'bookmarks.recorchange' is deprecated, "
+   "use 'bookmarks.applychanges'")
+self._repo.ui.deprecwarn(msg, '4.3')
+return self._recordchange(tr)
+
+def _recordchange(self, tr):
 """record that bookmarks have been changed in a transaction
 
 The transaction is then responsible for updating the file content."""
diff -r d8f4f481d22c -r 94da61e58167 tests/test-obsolete.t
--- a/tests/test-obsolete.t Mon Jul 10 20:06:15 2017 +0200
+++ b/tests/test-obsolete.t Mon Jul 10 20:10:03 2017 +0200
@@ -1149,7 +1149,7 @@
   >  bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', 
trhook)
   >  orig(bkmstoreinst, *args, **kwargs)
   > def extsetup(ui):
-  >   extensions.wrapfunction(bookmarks.bmstore, 'recordchange',
+  >   extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
   >   _bookmarkchanged)
   > EOF
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 03 of 10] bookmark: use 'divergent2delete' in 'scmutil.cleanupnode'

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499706613 -7200
#  Mon Jul 10 19:10:13 2017 +0200
# Node ID 2cb988ee601bd857ed1fe29d1cc36acf1617ac5f
# Parent  95035db0c9c8e55bf75165d098e38286784e4a6c
# EXP-Topic tr.changes.bookmarks
bookmark: use 'divergent2delete' in 'scmutil.cleanupnode'

diff -r 95035db0c9c8 -r 2cb988ee601b mercurial/scmutil.py
--- a/mercurial/scmutil.py  Mon Jul 10 19:08:17 2017 +0200
+++ b/mercurial/scmutil.py  Mon Jul 10 19:10:13 2017 +0200
@@ -592,14 +592,13 @@
 with repo.transaction('cleanup') as tr:
 # Move bookmarks
 bmarks = repo._bookmarks
-bmarkchanged = False
+bmarkchanges = []
 allnewnodes = [n for ns in mapping.values() for n in ns]
 for oldnode, newnodes in mapping.items():
 oldbmarks = repo.nodebookmarks(oldnode)
 if not oldbmarks:
 continue
 from . import bookmarks # avoid import cycle
-bmarkchanged = True
 if len(newnodes) > 1:
 # usually a split, take the one with biggest rev number
 newnode = next(repo.set('max(%ln)', newnodes)).node()
@@ -620,10 +619,12 @@
allnewnodes, newnode, oldnode)
 deletenodes = _containsnode(repo, deleterevs)
 for name in oldbmarks:
-bmarks[name] = newnode
-bookmarks.deletedivergent(repo, deletenodes, name)
-if bmarkchanged:
-bmarks.recordchange(tr)
+bmarkchanges.append((name, newnode))
+for b in bookmarks.divergent2delete(repo, deletenodes, name):
+bmarkchanges.append((b, None))
+
+if bmarkchanges:
+bmarks.applychanges(repo, tr, bmarkchanges)
 
 # Obsolete or strip nodes
 if obsolete.isenabled(repo, obsolete.createmarkersopt):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 02 of 10] bookmark: split out target computation from 'deletedivergent'

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499706497 -7200
#  Mon Jul 10 19:08:17 2017 +0200
# Node ID 95035db0c9c8e55bf75165d098e38286784e4a6c
# Parent  982526b815da34df7d0335b246afcbe48df3d112
# EXP-Topic tr.changes.bookmarks
bookmark: split out target computation from 'deletedivergent'

We want to use applychanges in order to unify bookmark movement. We need a way
to compute divergence deletion without actually removing them.

We split the function in two in this patch while we migrate the existing users
of this code on next patches.

diff -r 982526b815da -r 95035db0c9c8 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 17:48:33 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 19:08:17 2017 +0200
@@ -294,7 +294,17 @@
 '''Delete divergent versions of bm on nodes in deletefrom.
 
 Return True if at least one bookmark was deleted, False otherwise.'''
-deleted = False
+bms = divergent2delete(repo, deletefrom, bm)
+marks = repo._bookmarks
+for b in bms:
+del marks[b]
+return bool(bms)
+
+def divergent2delete(repo, deletefrom, bm):
+"""find divergent versions of bm on nodes in deletefrom.
+
+the list of bookmark to delete."""
+todelete = []
 marks = repo._bookmarks
 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
 for mark in divergent:
@@ -303,9 +313,8 @@
 continue
 if mark and marks[mark] in deletefrom:
 if mark != bm:
-del marks[mark]
-deleted = True
-return deleted
+todelete.append(mark)
+return todelete
 
 def headsforactive(repo):
 """Given a repo with an active bookmark, return divergent bookmark nodes.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 10 of 10] bookmark: deprecate direct del of a bookmark value

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499716177 -7200
#  Mon Jul 10 21:49:37 2017 +0200
# Node ID 0175d9abed800cfc4efc7831f7db8c22b68ef1af
# Parent  381e25bcfa028238ac3c27c30b7cc36f90ef2b60
# EXP-Topic tr.changes.bookmarks
bookmark: deprecate direct del of a bookmark value

We want all bookmark deletion to go through 'applychanges', so lets deprecate
legacy ways of doing bookmark deletion.

diff -r 381e25bcfa02 -r 0175d9abed80 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 21:47:34 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 21:49:37 2017 +0200
@@ -112,6 +112,12 @@
 return dict.__setitem__(self, key, value)
 
 def __delitem__(self, key):
+msg = ("'del bookmarks[name]' is deprecated, "
+   "use 'bookmarks.applychanges'")
+self._repo.ui.deprecwarn(msg, '4.3')
+self._del(key)
+
+def _del(self, key):
 self._clean = False
 return dict.__delitem__(self, key)
 
@@ -122,7 +128,7 @@
 for name, node in changes:
 old = self.get(name)
 if node is None:
-del self[name]
+self._del(name)
 else:
 self._set(name, node)
 if bmchanges is not None:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 06 of 10] bookmark: drop deletedivergent

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499709975 -7200
#  Mon Jul 10 20:06:15 2017 +0200
# Node ID d8f4f481d22c4fd4b606c2635c9b2f0fada67e8c
# Parent  3c70ad3b3daaeb8b2386b9d8760ac69e6dce0ecc
# EXP-Topic tr.changes.bookmarks
bookmark: drop deletedivergent

It has no caller anymore.

diff -r 3c70ad3b3daa -r d8f4f481d22c mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 20:02:32 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 20:06:15 2017 +0200
@@ -292,16 +292,6 @@
 parents = [p.node() for p in repo[None].parents()]
 return (mark in marks and marks[mark] in parents)
 
-def deletedivergent(repo, deletefrom, bm):
-'''Delete divergent versions of bm on nodes in deletefrom.
-
-Return True if at least one bookmark was deleted, False otherwise.'''
-bms = divergent2delete(repo, deletefrom, bm)
-marks = repo._bookmarks
-for b in bms:
-del marks[b]
-return bool(bms)
-
 def divergent2delete(repo, deletefrom, bm):
 """find divergent versions of bm on nodes in deletefrom.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 09 of 10] bookmark: deprecate direct set of a bookmark value

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499716054 -7200
#  Mon Jul 10 21:47:34 2017 +0200
# Node ID 381e25bcfa028238ac3c27c30b7cc36f90ef2b60
# Parent  a041b7fd158ab0a5dda7ef970aa0a238103e896b
# EXP-Topic tr.changes.bookmarks
bookmark: deprecate direct set of a bookmark value

We want all bookmark update to go through 'applychanges', so lets deprecate
legacy ways of doing bookmark update.

diff -r a041b7fd158a -r 381e25bcfa02 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 20:26:53 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 21:47:34 2017 +0200
@@ -102,8 +102,14 @@
 self._aclean = False
 
 def __setitem__(self, *args, **kwargs):
+msg = ("'bookmarks[name] = node' is deprecated, "
+   "use 'bookmarks.applychanges'")
+self._repo.ui.deprecwarn(msg, '4.3')
+self._set(*args, **kwargs)
+
+def _set(self, key, value):
 self._clean = False
-return dict.__setitem__(self, *args, **kwargs)
+return dict.__setitem__(self, key, value)
 
 def __delitem__(self, key):
 self._clean = False
@@ -118,7 +124,7 @@
 if node is None:
 del self[name]
 else:
-self[name] = node
+self._set(name, node)
 if bmchanges is not None:
 # if a previous value exist preserve the "initial" value
 previous = bmchanges.get(name)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 01 of 10] bookmark: remove a useless 'recordchange' in the amend code

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499701713 -7200
#  Mon Jul 10 17:48:33 2017 +0200
# Node ID 982526b815da34df7d0335b246afcbe48df3d112
# Parent  1adcb594eb6b075a9f3b676a1da5b56ed9e2a2ae
# EXP-Topic tr.changes.bookmarks
bookmark: remove a useless 'recordchange' in the amend code

We do not touch the bookmarks store in this code, just the active bookmark, not
covered by the transaction. So it seems we can safely drop this call and the
tests agree with us.

diff -r 1adcb594eb6b -r 982526b815da mercurial/cmdutil.py
--- a/mercurial/cmdutil.py  Mon Jul 10 19:40:23 2017 +0200
+++ b/mercurial/cmdutil.py  Mon Jul 10 17:48:33 2017 +0200
@@ -2750,7 +2750,7 @@
 base = old.p1()
 
 newid = None
-with repo.wlock(), repo.lock(), repo.transaction('amend') as tr:
+with repo.wlock(), repo.lock(), repo.transaction('amend'):
 # See if we got a message from -m or -l, if not, open the editor
 # with the message of the changeset to amend
 message = logmessage(ui, opts)
@@ -2768,7 +2768,6 @@
 node = commit(ui, repo, commitfunc, pats, opts)
 finally:
 repo._bookmarks.active = activebookmark
-repo._bookmarks.recordchange(tr)
 ui.callhooks = True
 ctx = repo[node]
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 04 of 10] bookmark: use 'divergent2delete' when updating a bookmark

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499706745 -7200
#  Mon Jul 10 19:12:25 2017 +0200
# Node ID 08c2a3d309e8619e0cc3ec16c4ae02722b9a1118
# Parent  2cb988ee601bd857ed1fe29d1cc36acf1617ac5f
# EXP-Topic tr.changes.bookmarks
bookmark: use 'divergent2delete' when updating a bookmark

diff -r 2cb988ee601b -r 08c2a3d309e8 mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 19:10:13 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 19:12:25 2017 +0200
@@ -354,7 +354,6 @@
 def update(repo, parents, node):
 deletefrom = parents
 marks = repo._bookmarks
-update = False
 active = marks.active
 if not active:
 return False
@@ -368,12 +367,11 @@
 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
 if validdest(repo, repo[marks[active]], new):
 bmchanges.append((active, new.node()))
-update = True
 
-if deletedivergent(repo, deletefrom, active):
-update = True
+for bm in divergent2delete(repo, deletefrom, active):
+bmchanges.append((bm, None))
 
-if update:
+if bmchanges:
 lock = tr = None
 try:
 lock = repo.lock()
@@ -382,7 +380,7 @@
 tr.close()
 finally:
 lockmod.release(tr, lock)
-return update
+return bool(bmchanges)
 
 def listbinbookmarks(repo):
 # We may try to list bookmarks on a repo type that does not
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 08 of 10] bookmark: track bookmark changes at the transaction level

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1499711213 -7200
#  Mon Jul 10 20:26:53 2017 +0200
# Node ID a041b7fd158ab0a5dda7ef970aa0a238103e896b
# Parent  94da61e581672f5c9616f1ad1336cfaadbdc96a9
# EXP-Topic tr.changes.bookmarks
bookmark: track bookmark changes at the transaction level

The transaction has now a 'bookmarks' dictionary in tr.changes. The structure
of the dictionary is {BOOKMARK_NAME: (OLD_NODE, NEW_NODE)}. If a bookmark is
deleted NEW_NODE will be None. If a bookmark is created OLD_NODE will be None.

If the bookmark is updated multiple time, the initial value is preserved.

diff -r 94da61e58167 -r a041b7fd158a mercurial/bookmarks.py
--- a/mercurial/bookmarks.pyMon Jul 10 20:10:03 2017 +0200
+++ b/mercurial/bookmarks.pyMon Jul 10 20:26:53 2017 +0200
@@ -112,11 +112,19 @@
 def applychanges(self, repo, tr, changes):
 """Apply a list of changes to bookmarks
 """
+bmchanges = tr.changes.get('bookmarks')
 for name, node in changes:
+old = self.get(name)
 if node is None:
 del self[name]
 else:
 self[name] = node
+if bmchanges is not None:
+# if a previous value exist preserve the "initial" value
+previous = bmchanges.get(name)
+if previous is not None:
+old = previous[0]
+bmchanges[name] = (old, node)
 self._recordchange(tr)
 
 def recordchange(self, tr):
diff -r 94da61e58167 -r a041b7fd158a mercurial/localrepo.py
--- a/mercurial/localrepo.pyMon Jul 10 20:10:03 2017 +0200
+++ b/mercurial/localrepo.pyMon Jul 10 20:26:53 2017 +0200
@@ -1217,6 +1217,7 @@
 tr.changes['revs'] = set()
 tr.changes['obsmarkers'] = set()
 tr.changes['phases'] = {}
+tr.changes['bookmarks'] = {}
 
 tr.hookargs['txnid'] = txnid
 # note: writing the fncache only during finalize mean that the file is
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 9] configitems: register the 'ui.forcecwd' config

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498787085 -7200
#  Fri Jun 30 03:44:45 2017 +0200
# Node ID 16b7d5ec9fb0e85e2f4a1f018f031439bc4500ab
# Parent  ffbd58343a63d0ddf02ba8d79ae52d216dc3fe83
# EXP-Topic config.register.ui
configitems: register the 'ui.forcecwd' config

diff -r ffbd58343a63 -r 16b7d5ec9fb0 mercurial/configitems.py
--- a/mercurial/configitems.py  Fri Jun 30 03:44:43 2017 +0200
+++ b/mercurial/configitems.py  Fri Jun 30 03:44:45 2017 +0200
@@ -442,6 +442,9 @@
 coreconfigitem('ui', 'fallbackencoding',
 default=None,
 )
+coreconfigitem('ui', 'forcecwd',
+default=None,
+)
 coreconfigitem('ui', 'forcemerge',
 default=None,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 9] color: drop the _enabledbydefault module variable

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1500120886 -7200
#  Sat Jul 15 14:14:46 2017 +0200
# Node ID 151a6237b3445206b8547da91545bdc21a023bb9
# Parent  16b7d5ec9fb0e85e2f4a1f018f031439bc4500ab
# EXP-Topic config.register.special-case
color: drop the _enabledbydefault module variable

Since color is on by default, cleanup the now useless variable in both core
and color extension.

diff -r 16b7d5ec9fb0 -r 151a6237b344 hgext/color.py
--- a/hgext/color.pyFri Jun 30 03:44:45 2017 +0200
+++ b/hgext/color.pySat Jul 15 14:14:46 2017 +0200
@@ -18,14 +18,8 @@
 
 from __future__ import absolute_import
 
-from mercurial import color
-
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
 # be specifying the version(s) of Mercurial they are tested with, or
 # leave the attribute unspecified.
 testedwith = 'ships-with-hg-core'
-
-def extsetup(ui):
-# change default color config
-color._enabledbydefault = True
diff -r 16b7d5ec9fb0 -r 151a6237b344 mercurial/color.py
--- a/mercurial/color.pyFri Jun 30 03:44:45 2017 +0200
+++ b/mercurial/color.pySat Jul 15 14:14:46 2017 +0200
@@ -45,8 +45,6 @@
 curses = None
 _baseterminfoparams = {}
 
-_enabledbydefault = True
-
 # start and stop parameters for effects
 _effects = {
 'none': 0,
@@ -185,10 +183,7 @@
 def _modesetup(ui):
 if ui.plain():
 return None
-default = 'never'
-if _enabledbydefault:
-default = 'auto'
-config = ui.config('ui', 'color', default)
+config = ui.config('ui', 'color', 'auto')
 if config == 'debug':
 return 'debug'
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 9] configitems: register the 'ui.color' config

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1500120893 -7200
#  Sat Jul 15 14:14:53 2017 +0200
# Node ID 789783a6db854e810b3381d2e0b9e4252238851c
# Parent  151a6237b3445206b8547da91545bdc21a023bb9
# EXP-Topic config.register.special-case
configitems: register the 'ui.color' config

diff -r 151a6237b344 -r 789783a6db85 mercurial/color.py
--- a/mercurial/color.pySat Jul 15 14:14:46 2017 +0200
+++ b/mercurial/color.pySat Jul 15 14:14:53 2017 +0200
@@ -183,7 +183,7 @@
 def _modesetup(ui):
 if ui.plain():
 return None
-config = ui.config('ui', 'color', 'auto')
+config = ui.config('ui', 'color')
 if config == 'debug':
 return 'debug'
 
diff -r 151a6237b344 -r 789783a6db85 mercurial/configitems.py
--- a/mercurial/configitems.py  Sat Jul 15 14:14:46 2017 +0200
+++ b/mercurial/configitems.py  Sat Jul 15 14:14:53 2017 +0200
@@ -430,6 +430,9 @@
 coreconfigitem('ui', 'clonebundles',
 default=True,
 )
+coreconfigitem('ui', 'color',
+default='auto',
+)
 coreconfigitem('ui', 'commitsubrepos',
 default=False,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 9] configitems: register the 'ui.fallbackencoding' config

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498787083 -7200
#  Fri Jun 30 03:44:43 2017 +0200
# Node ID ffbd58343a63d0ddf02ba8d79ae52d216dc3fe83
# Parent  7008f6819002bc01bcc8626f2ff41af0949096c4
# EXP-Topic config.register.ui
configitems: register the 'ui.fallbackencoding' config

diff -r 7008f6819002 -r ffbd58343a63 mercurial/configitems.py
--- a/mercurial/configitems.py  Tue Jul 11 00:40:29 2017 -0400
+++ b/mercurial/configitems.py  Fri Jun 30 03:44:43 2017 +0200
@@ -439,6 +439,9 @@
 coreconfigitem('ui', 'debugger',
 default=None,
 )
+coreconfigitem('ui', 'fallbackencoding',
+default=None,
+)
 coreconfigitem('ui', 'forcemerge',
 default=None,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 9] configitems: register the 'ui.mergemarkertemplate' config

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498787096 -7200
#  Fri Jun 30 03:44:56 2017 +0200
# Node ID 6a5f9dfdcb30a627d914d4b9fdbe767231253288
# Parent  789783a6db854e810b3381d2e0b9e4252238851c
# EXP-Topic config.register.special-case
configitems: register the 'ui.mergemarkertemplate' config

diff -r 789783a6db85 -r 6a5f9dfdcb30 mercurial/configitems.py
--- a/mercurial/configitems.py  Sat Jul 15 14:14:53 2017 +0200
+++ b/mercurial/configitems.py  Fri Jun 30 03:44:56 2017 +0200
@@ -484,6 +484,14 @@
 coreconfigitem('ui', 'mergemarkers',
 default='basic',
 )
+coreconfigitem('ui', 'mergemarkertemplate',
+default=('{node|short} '
+'{ifeq(tags, "tip", "", '
+'ifeq(tags, "", "", "{tags} "))}'
+'{if(bookmarks, "{bookmarks} ")}'
+'{ifeq(branch, "default", "", "{branch} ")}'
+'- {author|user}: {desc|firstline}')
+)
 coreconfigitem('ui', 'nontty',
 default=False,
 )
diff -r 789783a6db85 -r 6a5f9dfdcb30 mercurial/filemerge.py
--- a/mercurial/filemerge.pySat Jul 15 14:14:53 2017 +0200
+++ b/mercurial/filemerge.pyFri Jun 30 03:44:56 2017 +0200
@@ -555,13 +555,6 @@
 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
 return util.ellipsis(mark, 80 - 8)
 
-_defaultconflictmarker = ('{node|short} '
-  '{ifeq(tags, "tip", "", '
-   'ifeq(tags, "", "", "{tags} "))}'
-  '{if(bookmarks, "{bookmarks} ")}'
-  '{ifeq(branch, "default", "", "{branch} ")}'
-  '- {author|user}: {desc|firstline}')
-
 _defaultconflictlabels = ['local', 'other']
 
 def _formatlabels(repo, fcd, fco, fca, labels):
@@ -574,7 +567,7 @@
 ca = fca.changectx()
 
 ui = repo.ui
-template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
+template = ui.config('ui', 'mergemarkertemplate')
 template = templater.unquotestring(template)
 tmpl = formatter.maketemplater(ui, template)
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 9] configitems: register the 'bugzilla.notify' config

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498786213 -7200
#  Fri Jun 30 03:30:13 2017 +0200
# Node ID 0320a1820f8fcea0709ded92b788ffdb438f1e20
# Parent  6a5f9dfdcb30a627d914d4b9fdbe767231253288
# EXP-Topic config.register.special-case
configitems: register the 'bugzilla.notify' config

diff -r 6a5f9dfdcb30 -r 0320a1820f8f hgext/bugzilla.py
--- a/hgext/bugzilla.py Fri Jun 30 03:44:56 2017 +0200
+++ b/hgext/bugzilla.py Fri Jun 30 03:30:13 2017 +0200
@@ -301,6 +301,7 @@
 from mercurial.node import short
 from mercurial import (
 cmdutil,
+configitems,
 error,
 mail,
 registrar,
@@ -352,6 +353,9 @@
 configitem('bugzilla', 'host',
 default='localhost',
 )
+configitem('bugzilla', 'notify',
+default=configitems.dynamicdefault,
+)
 configitem('bugzilla', 'password',
 default=None,
 )
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 9] extensions: expand the builtins extensions declaration

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1500121014 -7200
#  Sat Jul 15 14:16:54 2017 +0200
# Node ID f170c4ba9c21f40248b83b511e064474080a0060
# Parent  07c4317cc5f9e3ae8d357c7013743a07227eb89f
# EXP-Topic cleanup.color
extensions: expand the builtins extensions declaration

This will future updates of the set cleaner and more readable.

diff -r 07c4317cc5f9 -r f170c4ba9c21 mercurial/extensions.py
--- a/mercurial/extensions.py   Sat Jul 15 20:31:52 2017 +0200
+++ b/mercurial/extensions.py   Sat Jul 15 14:16:54 2017 +0200
@@ -29,8 +29,15 @@
 _disabledextensions = {}
 _aftercallbacks = {}
 _order = []
-_builtin = {'hbisect', 'bookmarks', 'parentrevspec', 'progress', 'interhg',
-'inotify', 'hgcia'}
+_builtin = {
+'hbisect',
+'bookmarks',
+'parentrevspec',
+'progress',
+'interhg',
+'inotify',
+'hgcia'
+}
 
 def extensions(ui=None):
 if ui:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 9] debugextensions: drop the color from the test

2017-07-15 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1500143512 -7200
#  Sat Jul 15 20:31:52 2017 +0200
# Node ID 07c4317cc5f9e3ae8d357c7013743a07227eb89f
# Parent  0320a1820f8fcea0709ded92b788ffdb438f1e20
# EXP-Topic cleanup.color
debugextensions: drop the color from the test

We are about to remove the extension so we remove trace of it in this specific
test to prevent it to be confused.

diff -r 0320a1820f8f -r 07c4317cc5f9 tests/test-debugextensions.t
--- a/tests/test-debugextensions.t  Fri Jun 30 03:30:13 2017 +0200
+++ b/tests/test-debugextensions.t  Sat Jul 15 20:31:52 2017 +0200
@@ -11,7 +11,6 @@
 
   $ cat >> $HGRCPATH < [extensions]
-  > color=
   > histedit=
   > patchbomb=
   > rebase=
@@ -21,7 +20,6 @@
   > EOF
 
   $ hg debugextensions
-  color
   ext1 (untested!)
   ext2 (3.2.1!)
   histedit
@@ -30,9 +28,6 @@
   rebase
 
   $ hg debugextensions -v
-  color
-location: */hgext/color.py* (glob)
-bundled: yes
   ext1
 location: */extwithoutinfos.py* (glob)
 bundled: no
@@ -58,13 +53,6 @@
   [
{
 "buglink": "",
-"bundled": true,
-"name": "color",
-"source": "*/hgext/color.py*", (glob)
-"testedwith": []
-   },
-   {
-"buglink": "",
 "bundled": false,
 "name": "ext1",
 "source": "*/extwithoutinfos.py*", (glob)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


  1   2   3   4   5   6   7   8   9   10   >