Re: [PATCH 9 of 9] template: use template-engine for obsfate
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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
# 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
# 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
# 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?
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
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
# 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
# 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
# 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
# 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
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
# 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'
# 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
# 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
# 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'
# 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'
# 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
# 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'
# 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
# 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
# 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
# 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
# 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'
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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'
# 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
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
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
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?
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
# 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'
# 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'
# 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'
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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