D4049: testrunner: allow multiple #testcases
martinvonz added a comment. In https://phab.mercurial-scm.org/D4049#63024, @mharbison72 wrote: > In https://phab.mercurial-scm.org/D4049#63019, @martinvonz wrote: > > > In https://phab.mercurial-scm.org/D4049#63018, @mharbison72 wrote: > > > > > I'm getting an import error, and I'm not sure how to figure out the parent revision from phab. > > > > > > Make sure you're applying it onto @ from https://www.mercurial-scm.org/repo/hg-committed/. If not, you'll probably have to import https://phab.mercurial-scm.org/D4052 before this patch (https://phab.mercurial-scm.org/D4052 is in @ on hg-committed). > > > Maybe needs a push? I'm seeing @ on https://phab.mercurial-scm.org/D4048 on hg-committed. Sorry, I was just misremembering that https://phab.mercurial-scm.org/D4052 had been queued. I don't know why phabricator doesn't understand that this patch is on top of https://phab.mercurial-scm.org/D4052. Anyway, try applying https://phab.mercurial-scm.org/D4052 first, then this one. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4049: testrunner: allow multiple #testcases
mharbison72 added a comment. In https://phab.mercurial-scm.org/D4049#63019, @martinvonz wrote: > In https://phab.mercurial-scm.org/D4049#63018, @mharbison72 wrote: > > > I'm getting an import error, and I'm not sure how to figure out the parent revision from phab. > > > Make sure you're applying it onto @ from https://www.mercurial-scm.org/repo/hg-committed/. If not, you'll probably have to import https://phab.mercurial-scm.org/D4052 before this patch (https://phab.mercurial-scm.org/D4052 is in @ on hg-committed). Maybe needs a push? I'm seeing @ on https://phab.mercurial-scm.org/D4048 on hg-committed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4049: testrunner: allow multiple #testcases
mharbison72 added a comment. I manually fixed it up, and got the following diffs. I see the last parent is listed as https://phab.mercurial-scm.org/D4067, which hasn't been accepted yet, so I'm assuming that's the issue (I'm way behind on the ML). And I guess --stack doesn't pick up parent dependencies, just what was submitted together? --- c:/Users/Matt/projects/hg/tests/test-run-tests.t +++ c:/Users/Matt/projects/hg/tests/test-run-tests.t.err @@ -850,7 +850,7 @@ > EOF --- $TESTTMP/test-cases.t - +++ $TESTTMP/test-cases.t.a.err + +++ $TESTTMP/test-cases.t#a.err @@ -1,6 +1,7 @@ #testcases a b #if a @@ -861,7 +861,7 @@ $ echo 2 Accept this change? [n] . --- $TESTTMP/test-cases.t - +++ $TESTTMP/test-cases.t.b.err + +++ $TESTTMP/test-cases.t#b.err @@ -5,4 +5,5 @@ #endif #if b @@ -1574,7 +1574,7 @@ $ rt . --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1597,7 +1597,7 @@ $ rt --restart --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1619,10 +1619,12 @@ $ mkdir output $ mv test-cases-abc.t.B.err output + mv: cannot stat `test-cases-abc.t.B.err': $ENOENT$ + [1] $ rt --restart --outputdir output - + . --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/output/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/output/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1636,8 +1638,9 @@ ERROR: test-cases-abc.t#B output changed !. Failed test-cases-abc.t#B: output changed - # Ran 2 tests, 0 skipped, 1 failed. - python hash seed: * (glob) + # Ran 3 tests, 0 skipped, 1 failed. + python hash seed: * (glob) + running all tests [1] Test TESTCASE variable @@ -1665,7 +1668,7 @@ $ rt "test-cases-abc.t#B" --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1688,7 +1691,7 @@ $ rt test-cases-abc.t#B test-cases-abc.t#C --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1711,7 +1714,7 @@ $ rt test-cases-abc.t#B test-cases-abc.t#D --- $TESTTMP/anothertests/cases/test-cases-abc.t - +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err + +++ $TESTTMP/anothertests/cases/test-cases-abc.t#B.err @@ -7,7 +7,7 @@ $ V=C #endif @@ -1745,7 +1748,7 @@ $ rt test-cases-advanced-cases.t --- $TESTTMP/anothertests/cases/test-cases-advanced-cases.t - +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t.case-with-dashes.err + +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t#case-with-dashes.err @@ -1,3 +1,3 @@ #testcases simple case-with-dashes casewith_-.chars $ echo $TESTCASE @@ -1755,7 +1758,7 @@ ERROR: test-cases-advanced-cases.t#case-with-dashes output changed ! --- $TESTTMP/anothertests/cases/test-cases-advanced-cases.t - +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t.casewith_-.chars.err + +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t#casewith_-.chars.err @@ -1,3 +1,3 @@ #testcases simple case-with-dashes casewith_-.chars $ echo $TESTCASE @@ -1773,7 +1776,7 @@ $ rt "test-cases-advanced-cases.t#case-with-dashes" --- $TESTTMP/anothertests/cases/test-cases-advanced-cases.t - +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t.case-with-dashes.err + +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t#case-with-dashes.err @@ -1,3 +1,3 @@ #testcases simple case-with-dashes casewith_-.chars $ echo $TESTCASE @@ -1790,7 +1793,7 @@ $ rt "test-cases-advanced-cases.t#casewith_-.chars" --- $TESTTMP/anothertests/cases/test-cases-advanced-cases.t - +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t.casewith_-.chars.err + +++ $TESTTMP/anothertests/cases/test-cases-advanced-cases.t#casewith_-.chars.err @@ -1,3 +1,3 @@ #testcases simple case-with-dashes casewith_-.chars
D4049: testrunner: allow multiple #testcases
martinvonz added a comment. In https://phab.mercurial-scm.org/D4049#63018, @mharbison72 wrote: > I'm getting an import error, and I'm not sure how to figure out the parent revision from phab. Make sure you're applying it onto @ from https://www.mercurial-scm.org/repo/hg-committed/. If not, you'll probably have to import https://phab.mercurial-scm.org/D4052 before this patch (https://phab.mercurial-scm.org/D4052 is in @ on hg-committed). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4049: testrunner: allow multiple #testcases
mharbison72 added a comment. I'm getting an import error, and I'm not sure how to figure out the parent revision from phab. $ hg phabimport D4049 applying patch from stdin patching file tests/run-tests.py Hunk #2 FAILED at 1241 Hunk #7 FAILED at 2724 abort: patch failed to apply $ hg config alias.phabimport !"%HG%" phabread $1 --stack | "%HG%" import --bypass - REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4059: help: add quotes to a few commands we point to
This revision was automatically updated to reflect the committed changes. Closed by commit rHG4fe8d1f077b8: help: add quotes to a few commands we point to (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4059?vs=9798=9812 REVISION DETAIL https://phab.mercurial-scm.org/D4059 AFFECTED FILES mercurial/fileset.py mercurial/minifileset.py mercurial/revset.py tests/test-fileset.t tests/test-revset2.t CHANGE DETAILS diff --git a/tests/test-revset2.t b/tests/test-revset2.t --- a/tests/test-revset2.t +++ b/tests/test-revset2.t @@ -346,15 +346,15 @@ test ',' in `_list` $ log '0,1' hg: parse error: can't use a list in this context - (see hg help "revsets.x or y") + (see 'hg help "revsets.x or y"') [255] $ try '0,1,2' (list (symbol '0') (symbol '1') (symbol '2')) hg: parse error: can't use a list in this context - (see hg help "revsets.x or y") + (see 'hg help "revsets.x or y"') [255] test that chained `or` operations make balanced addsets diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -118,7 +118,7 @@ (symbol 'b') (symbol 'c')) hg: parse error: can't use a list in this context - (see hg help "filesets.x or y") + (see 'hg help "filesets.x or y"') [255] $ fileset '"path":.' @@ -298,7 +298,7 @@ [255] $ fileset '(1k, 2k)' hg: parse error: can't use a list in this context - (see hg help "filesets.x or y") + (see 'hg help "filesets.x or y"') [255] $ fileset 'size(1k)' 1k diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -242,7 +242,7 @@ def listset(repo, subset, *xs, **opts): raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "revsets.x or y"')) + hint=_('see \'hg help "revsets.x or y"\'')) def keyvaluepair(repo, subset, k, v, order): raise error.ParseError(_("can't use a key-value pair in this context")) diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py --- a/mercurial/minifileset.py +++ b/mercurial/minifileset.py @@ -71,7 +71,7 @@ raise error.ParseError(_("can't use negate operator in this context")) elif op == 'list': raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "filesets.x or y"')) + hint=_('see \'hg help "filesets.x or y"\'')) raise error.ProgrammingError('illegal tree: %r' % (tree,)) def compile(text): diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -67,7 +67,7 @@ def listmatch(mctx, *xs): raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "filesets.x or y"')) + hint=_('see \'hg help "filesets.x or y"\'')) def func(mctx, a, b): funcname = getsymbol(a) To: martinvonz, #hg-reviewers, pulkit Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4048: fix: add a monkey-patchable point after all new revisions have been committed
This revision was automatically updated to reflect the committed changes. Closed by commit rHG64535d43c103: fix: add a monkey-patchable point after all new revisions have been committed (authored by hooper, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4048?vs=9769=9813 REVISION DETAIL https://phab.mercurial-scm.org/D4048 AFFECTED FILES hgext/fix.py CHANGE DETAILS diff --git a/hgext/fix.py b/hgext/fix.py --- a/hgext/fix.py +++ b/hgext/fix.py @@ -182,8 +182,23 @@ replacerev(ui, repo, ctx, filedata[rev], replacements) del filedata[rev] -replacements = {prec: [succ] for prec, succ in replacements.iteritems()} -scmutil.cleanupnodes(repo, replacements, 'fix', fixphase=True) +cleanup(repo, replacements, bool(filedata[wdirrev])) + +def cleanup(repo, replacements, wdirwritten): +"""Calls scmutil.cleanupnodes() with the given replacements. + +"replacements" is a dict from nodeid to nodeid, with one key and one value +for every revision that was affected by fixing. This is slightly different +from cleanupnodes(). + +"wdirwritten" is a bool which tells whether the working copy was affected by +fixing, since it has no entry in "replacements". + +Useful as a hook point for extending "hg fix" with output summarizing the +effects of the command, though we choose not to output anything here. +""" +replacements = {prec: [succ] for prec, succ in replacements.iteritems()} +scmutil.cleanupnodes(repo, replacements, 'fix', fixphase=True) def getworkqueue(ui, repo, pats, opts, revstofix, basectxs): Constructs the list of files to be fixed at specific revisions To: hooper, #hg-reviewers, pulkit Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4051: linelog: port to Python 3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG57af5ee15b35: linelog: port to Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4051?vs=9774=9811 REVISION DETAIL https://phab.mercurial-scm.org/D4051 AFFECTED FILES contrib/python3-whitelist mercurial/linelog.py tests/test-linelog.py CHANGE DETAILS diff --git a/tests/test-linelog.py b/tests/test-linelog.py --- a/tests/test-linelog.py +++ b/tests/test-linelog.py @@ -41,12 +41,12 @@ self.assertEqual(linelog.linelog.fromdata(enc), ll) # This encoding matches the encoding used by hg-experimental's # linelog file, or is supposed to if it doesn't. -self.assertEqual(enc, ('\x00\x00\x01\x90\x00\x00\x00\x06' - '\x00\x00\x00\xa4\x00\x00\x00*' - '\x00\x00\x00\x00\x00\x00\x00+' - '\x00\x00\x00\x00\x00\x00\x00\x00' - '\x00\x00\x00\xb1\x00\x00\x00-' - '\x00\x00\x00\xba\x00\x00\x00/')) +self.assertEqual(enc, (b'\x00\x00\x01\x90\x00\x00\x00\x06' + b'\x00\x00\x00\xa4\x00\x00\x00*' + b'\x00\x00\x00\x00\x00\x00\x00+' + b'\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\xb1\x00\x00\x00-' + b'\x00\x00\x00\xba\x00\x00\x00/')) def testsimpleedits(self): ll = linelog.linelog() @@ -94,21 +94,21 @@ def testparseclinelogfile(self): # This data is what the replacements in testsimpleedits # produce when fed to the original linelog.c implementation. -data = ('\x00\x00\x00\x0c\x00\x00\x00\x0f' -'\x00\x00\x00\x00\x00\x00\x00\x02' -'\x00\x00\x00\x05\x00\x00\x00\x06' -'\x00\x00\x00\x06\x00\x00\x00\x00' -'\x00\x00\x00\x00\x00\x00\x00\x07' -'\x00\x00\x00\x06\x00\x00\x00\x02' -'\x00\x00\x00\x00\x00\x00\x00\x00' -'\x00\x00\x00\t\x00\x00\x00\t' -'\x00\x00\x00\x00\x00\x00\x00\x0c' -'\x00\x00\x00\x08\x00\x00\x00\x05' -'\x00\x00\x00\x06\x00\x00\x00\x01' -'\x00\x00\x00\x00\x00\x00\x00\x05' -'\x00\x00\x00\x0c\x00\x00\x00\x05' -'\x00\x00\x00\n\x00\x00\x00\x01' -'\x00\x00\x00\x00\x00\x00\x00\t') +data = (b'\x00\x00\x00\x0c\x00\x00\x00\x0f' +b'\x00\x00\x00\x00\x00\x00\x00\x02' +b'\x00\x00\x00\x05\x00\x00\x00\x06' +b'\x00\x00\x00\x06\x00\x00\x00\x00' +b'\x00\x00\x00\x00\x00\x00\x00\x07' +b'\x00\x00\x00\x06\x00\x00\x00\x02' +b'\x00\x00\x00\x00\x00\x00\x00\x00' +b'\x00\x00\x00\t\x00\x00\x00\t' +b'\x00\x00\x00\x00\x00\x00\x00\x0c' +b'\x00\x00\x00\x08\x00\x00\x00\x05' +b'\x00\x00\x00\x06\x00\x00\x00\x01' +b'\x00\x00\x00\x00\x00\x00\x00\x05' +b'\x00\x00\x00\x0c\x00\x00\x00\x05' +b'\x00\x00\x00\n\x00\x00\x00\x01' +b'\x00\x00\x00\x00\x00\x00\x00\t') llc = linelog.linelog.fromdata(data) self.assertEqual([(l.rev, l.linenum) for l in llc.annotate(1)], [(1, 0), diff --git a/mercurial/linelog.py b/mercurial/linelog.py --- a/mercurial/linelog.py +++ b/mercurial/linelog.py @@ -98,7 +98,7 @@ self._target = op2 def __str__(self): -return 'JGE %d %d' % (self._cmprev, self._target) +return r'JGE %d %d' % (self._cmprev, self._target) def __eq__(self, other): return (type(self) == type(other) @@ -122,7 +122,7 @@ self._target = op2 def __str__(self): -return 'JUMP %d' % (self._target) +return r'JUMP %d' % (self._target) def __eq__(self, other): return (type(self) == type(other) @@ -144,7 +144,7 @@ raise LineLogError("malformed EOF, op2 must be 0, got %d" % op2) def __str__(self): -return 'EOF' +return r'EOF' def __eq__(self, other): return type(self) == type(other) @@ -163,7 +163,7 @@ self._target = op2 def __str__(self): -return 'JL %d %d' % (self._cmprev, self._target) +return r'JL %d %d' % (self._cmprev, self._target) def __eq__(self, other): return (type(self) == type(other) @@ -188,7 +188,7 @@ self._origlineno = op2 def __str__(self): -return 'LINE %d %d' % (self._rev, self._origlineno) +return r'LINE %d %d' % (self._rev, self._origlineno) def __eq__(self, other): return (type(self) == type(other) @@ -245,8 +245,8 @@ hex(id(self)), self._maxrev,
D4048: fix: add a monkey-patchable point after all new revisions have been committed
pulkit accepted this revision. pulkit added inline comments. INLINE COMMENTS > fix.py:197 > + > +Useful as a hook point for extending "hg fix" with output summarizing the > +effects of the command, though we choose not to output anything here. If the output is not Google specific, we can have that here also under `hg fix -v` or a config option. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4048 To: hooper, #hg-reviewers, pulkit Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4055: rebase: move "backup" flag to rbsrt
pulkit added inline comments. INLINE COMMENTS > rebase.py:349 > +nobackup = (not backup) or (not self.backupf) > +backup = not nobackup > + not A or not B = not (A and B) not(not A or not B) = A and B REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4055 To: khanchi97, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3988: resolve: add confirm config option
pulkit added inline comments. INLINE COMMENTS > commands.py:4539 > + b'$$ $$ ')): > +return > + This should be an abort with message 'user quit' instead of just a return. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3988 To: khanchi97, #hg-reviewers, pulkit Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4035: resolve: add option to warn/abort on -m with unresolved conflict markers
pulkit added a comment. In https://phab.mercurial-scm.org/D4035#62661, @spectral wrote: > In https://phab.mercurial-scm.org/D4035#62660, @pulkit wrote: > > > Also, even though this is experimental, can we document it somewhere? > > > Sure, any advice for where would be a good place to do that? I would have thought `mercurial/help/config.txt`, but there's nothing in there about experimental options right now. I think we need 'mercurial/help/experimental.txt' or something. > I'm also fine skipping a prolonged 'experimental' phase and moving out of experimental now/soon. I generally default to starting things in experimental, but maybe I shouldn't be doing that, and just land things like this completely to start with? :) As Augie also mentioned this looks appropriate as non-experimental, lets move this out of experimental and hence document that. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4035 To: spectral, #hg-reviewers Cc: pulkit, khanchi97, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4014: exchange: move simple narrow changegroup generation from extension
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd99083996398: exchange: move simple narrow changegroup generation from extension (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4014?vs=9706=9810 REVISION DETAIL https://phab.mercurial-scm.org/D4014 AFFECTED FILES hgext/narrow/narrowbundle2.py mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -2114,8 +2114,17 @@ if not outgoing.missing: return +if kwargs.get(r'narrow', False): +include = sorted(filter(bool, kwargs.get(r'includepats', []))) +exclude = sorted(filter(bool, kwargs.get(r'excludepats', []))) +filematcher = narrowspec.match(repo.root, include=include, + exclude=exclude) +else: +filematcher = None + cgstream = changegroup.makestream(repo, outgoing, version, source, - bundlecaps=bundlecaps) + bundlecaps=bundlecaps, + filematcher=filematcher) part = bundler.newpart('changegroup', data=cgstream) if cgversions: @@ -2127,6 +2136,15 @@ if 'treemanifest' in repo.requirements: part.addparam('treemanifest', '1') +if kwargs.get(r'narrow', False) and (include or exclude): +narrowspecpart = bundler.newpart('narrow:spec') +if include: +narrowspecpart.addparam( +'include', '\n'.join(include), mandatory=True) +if exclude: +narrowspecpart.addparam( +'exclude', '\n'.join(exclude), mandatory=True) + @getbundle2partsgenerator('bookmarks') def _getbundlebookmarkpart(bundler, repo, source, bundlecaps=None, b2caps=None, **kwargs): diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -87,6 +87,8 @@ def getbundlechangegrouppart_narrow(bundler, repo, source, bundlecaps=None, b2caps=None, heads=None, common=None, **kwargs): +assert repo.ui.configbool('experimental', 'narrowservebrokenellipses') + cgversions = b2caps.get('changegroup') if cgversions: # 3.1 and 3.2 ship with an empty value cgversions = [v for v in cgversions @@ -101,28 +103,6 @@ include = sorted(filter(bool, kwargs.get(r'includepats', []))) exclude = sorted(filter(bool, kwargs.get(r'excludepats', []))) newmatch = narrowspec.match(repo.root, include=include, exclude=exclude) -if not repo.ui.configbool("experimental", "narrowservebrokenellipses"): -outgoing = exchange._computeoutgoing(repo, heads, common) -if not outgoing.missing: -return - -cg = changegroup.makestream(repo, outgoing, version, source, -filematcher=newmatch) -part = bundler.newpart('changegroup', data=cg) -part.addparam('version', version) -if 'treemanifest' in repo.requirements: -part.addparam('treemanifest', '1') - -if include or exclude: -narrowspecpart = bundler.newpart(_SPECPART) -if include: -narrowspecpart.addparam( -_SPECPART_INCLUDE, '\n'.join(include), mandatory=True) -if exclude: -narrowspecpart.addparam( -_SPECPART_EXCLUDE, '\n'.join(exclude), mandatory=True) - -return depth = kwargs.get(r'depth', None) if depth is not None: @@ -311,7 +291,8 @@ if repo.ui.has_section(_NARROWACL_SECTION): kwargs = exchange.applynarrowacl(repo, kwargs) -if kwargs.get(r'narrow', False): +if (kwargs.get(r'narrow', False) and +repo.ui.configbool('experimental', 'narrowservebrokenellipses')): getbundlechangegrouppart_narrow(*args, **kwargs) else: origcgfn(*args, **kwargs) To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4012: changegroup: inline prune() logic from narrow
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5742d0428ed9: changegroup: inline prune() logic from narrow (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4012?vs=9799=9808 REVISION DETAIL https://phab.mercurial-scm.org/D4012 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -21,6 +21,7 @@ from . import ( dagutil, error, +manifest, match as matchmod, mdiff, phases, @@ -589,6 +590,11 @@ # filter any nodes that claim to be part of the known set def prune(self, revlog, missing, commonrevs): +# TODO this violates storage abstraction for manifests. +if isinstance(revlog, manifest.manifestrevlog): +if not self._filematcher.visitdir(revlog._dir[:-1] or '.'): +return [] + rr, rl = revlog.rev, revlog.linkrev return [n for n in missing if rl(rr(n)) not in commonrevs] diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -12,24 +12,14 @@ changegroup, error, extensions, -manifest, mdiff, node, pycompat, revlog, util, ) def setup(): -def prune(orig, self, revlog, missing, commonrevs): -if isinstance(revlog, manifest.manifestrevlog): -if not self._filematcher.visitdir(revlog._dir[:-1] or '.'): -return [] - -return orig(self, revlog, missing, commonrevs) - -extensions.wrapfunction(changegroup.cg1packer, 'prune', prune) - def generatefiles(orig, self, changedfiles, linknodes, commonrevs, source): changedfiles = list(filter(self._filematcher, changedfiles)) To: indygreg, durin42, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4013: exchange: make narrow ACL presence imply narrow=True
This revision was automatically updated to reflect the committed changes. Closed by commit rHG98df52d5042c: exchange: make narrow ACL presence imply narrow=True (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4013?vs=9705=9809 REVISION DETAIL https://phab.mercurial-scm.org/D4013 AFFECTED FILES hgext/narrow/narrowbundle2.py mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1872,9 +1872,11 @@ new_args = {} new_args.update(kwargs) -new_args['includepats'] = req_includes +new_args[r'narrow'] = True +new_args[r'includepats'] = req_includes if req_excludes: -new_args['excludepats'] = req_excludes +new_args[r'excludepats'] = req_excludes + return new_args def _computeellipsis(repo, common, heads, known, match, depth=None): diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -309,9 +309,9 @@ def wrappedcgfn(*args, **kwargs): repo = args[1] if repo.ui.has_section(_NARROWACL_SECTION): -getbundlechangegrouppart_narrow( -*args, **exchange.applynarrowacl(repo, kwargs)) -elif kwargs.get(r'narrow', False): +kwargs = exchange.applynarrowacl(repo, kwargs) + +if kwargs.get(r'narrow', False): getbundlechangegrouppart_narrow(*args, **kwargs) else: origcgfn(*args, **kwargs) To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4064: changegroup: move close() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY More of the same. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4064 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -547,6 +547,13 @@ self._verbosenote = lambda s: None def close(self): +# Ellipses serving mode. +getattr(self, 'clrev_to_localrev', {}).clear() +if getattr(self, 'next_clrev_to_localrev', {}): +self.clrev_to_localrev = self.next_clrev_to_localrev +del self.next_clrev_to_localrev +self.changelog_done = True + return closechunk() def fileheader(self, fname): diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -51,15 +51,6 @@ extensions.wrapfunction( changegroup.cg1packer, 'generatefiles', generatefiles) -def close(orig, self): -getattr(self, 'clrev_to_localrev', {}).clear() -if getattr(self, 'next_clrev_to_localrev', {}): -self.clrev_to_localrev = self.next_clrev_to_localrev -del self.next_clrev_to_localrev -self.changelog_done = True -return orig(self) -extensions.wrapfunction(changegroup.cg1packer, 'close', close) - # In a perfect world, we'd generate better ellipsis-ified graphs # for non-changelog revlogs. In practice, we haven't started doing # that yet, so the resulting DAGs for the manifestlog and filelogs To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4012: changegroup: inline prune() logic from narrow
indygreg updated this revision to Diff 9799. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4012?vs=9704=9799 REVISION DETAIL https://phab.mercurial-scm.org/D4012 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -21,6 +21,7 @@ from . import ( dagutil, error, +manifest, match as matchmod, mdiff, phases, @@ -589,6 +590,11 @@ # filter any nodes that claim to be part of the known set def prune(self, revlog, missing, commonrevs): +# TODO this violates storage abstraction for manifests. +if isinstance(revlog, manifest.manifestrevlog): +if not self._filematcher.visitdir(revlog._dir[:-1] or '.'): +return [] + rr, rl = revlog.rev, revlog.linkrev return [n for n in missing if rl(rr(n)) not in commonrevs] diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -12,24 +12,14 @@ changegroup, error, extensions, -manifest, mdiff, node, pycompat, revlog, util, ) def setup(): -def prune(orig, self, revlog, missing, commonrevs): -if isinstance(revlog, manifest.manifestrevlog): -if not self._filematcher.visitdir(revlog._dir[:-1] or '.'): -return [] - -return orig(self, revlog, missing, commonrevs) - -extensions.wrapfunction(changegroup.cg1packer, 'prune', prune) - def generatefiles(orig, self, changedfiles, linknodes, commonrevs, source): changedfiles = list(filter(self._filematcher, changedfiles)) To: indygreg, durin42, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4061: changegroup: move _packellipsischangegroup() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The behavior here is not ideal, as the function constructs a packer then adds attributes to it. This will be cleaned up in subsequent commits. Moving this code is necessary to move the remainder of the bundle2-level changegroup part generation code into core. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4061 AFFECTED FILES hgext/narrow/narrowbundle2.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -1058,3 +1058,36 @@ (f, hex(n))) return revisions, files + +def _packellipsischangegroup(repo, common, match, relevant_nodes, + ellipsisroots, visitnodes, depth, source, version): +if version in ('01', '02'): +raise error.Abort( +'ellipsis nodes require at least cg3 on client and server, ' +'but negotiated version %s' % version) +# We wrap cg1packer.revchunk, using a side channel to pass +# relevant_nodes into that area. Then if linknode isn't in the +# set, we know we have an ellipsis node and we should defer +# sending that node's data. We override close() to detect +# pending ellipsis nodes and flush them. +packer = getbundler(version, repo, filematcher=match) +# Give the packer the list of nodes which should not be +# ellipsis nodes. We store this rather than the set of nodes +# that should be an ellipsis because for very large histories +# we expect this to be significantly smaller. +packer.full_nodes = relevant_nodes +# Maps ellipsis revs to their roots at the changelog level. +packer.precomputed_ellipsis = ellipsisroots +# Maps CL revs to per-revlog revisions. Cleared in close() at +# the end of each group. +packer.clrev_to_localrev = {} +packer.next_clrev_to_localrev = {} +# Maps changelog nodes to changelog revs. Filled in once +# during changelog stage and then left unmodified. +packer.clnode_to_rev = {} +packer.changelog_done = False +# If true, informs the packer that it is serving shallow content and might +# need to pack file contents not introduced by the changes being packed. +packer.is_shallow = depth is not None + +return packer.generate(common, visitnodes, False, source) diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -49,40 +49,6 @@ caps[NARROWCAP] = ['v0'] return caps -def _packellipsischangegroup(repo, common, match, relevant_nodes, - ellipsisroots, visitnodes, depth, source, version): -if version in ('01', '02'): -raise error.Abort( -'ellipsis nodes require at least cg3 on client and server, ' -'but negotiated version %s' % version) -# We wrap cg1packer.revchunk, using a side channel to pass -# relevant_nodes into that area. Then if linknode isn't in the -# set, we know we have an ellipsis node and we should defer -# sending that node's data. We override close() to detect -# pending ellipsis nodes and flush them. -packer = changegroup.getbundler(version, repo, -filematcher=match) -# Give the packer the list of nodes which should not be -# ellipsis nodes. We store this rather than the set of nodes -# that should be an ellipsis because for very large histories -# we expect this to be significantly smaller. -packer.full_nodes = relevant_nodes -# Maps ellipsis revs to their roots at the changelog level. -packer.precomputed_ellipsis = ellipsisroots -# Maps CL revs to per-revlog revisions. Cleared in close() at -# the end of each group. -packer.clrev_to_localrev = {} -packer.next_clrev_to_localrev = {} -# Maps changelog nodes to changelog revs. Filled in once -# during changelog stage and then left unmodified. -packer.clnode_to_rev = {} -packer.changelog_done = False -# If true, informs the packer that it is serving shallow content and might -# need to pack file contents not introduced by the changes being packed. -packer.is_shallow = depth is not None - -return packer.generate(common, visitnodes, False, source) - # Serve a changegroup for a client with a narrow clone. def getbundlechangegrouppart_narrow(bundler, repo, source, bundlecaps=None, b2caps=None, heads=None, @@ -149,7 +115,7 @@ newvisit, newfull, newellipsis = exchange._computeellipsis( repo, set(), common, known, newmatch) if newvisit: -cg = _packellipsischangegroup( +cg =
D4065: changegroup: move _sortgroup() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4065 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -562,6 +562,26 @@ # Extracted both for clarity and for overriding in extensions. def _sortgroup(self, revlog, nodelist, lookup): """Sort nodes for change group and turn them into revnums.""" +# Ellipses serving mode. +# +# In a perfect world, we'd generate better ellipsis-ified graphs +# for non-changelog revlogs. In practice, we haven't started doing +# that yet, so the resulting DAGs for the manifestlog and filelogs +# are actually full of bogus parentage on all the ellipsis +# nodes. This has the side effect that, while the contents are +# correct, the individual DAGs might be completely out of whack in +# a case like 882681bc3166 and its ancestors (back about 10 +# revisions or so) in the main hg repo. +# +# The one invariant we *know* holds is that the new (potentially +# bogus) DAG shape will be valid if we order the nodes in the +# order that they're introduced in dramatis personae by the +# changelog, so what we do is we sort the non-changelog histories +# by the order in which they are used by the changelog. +if util.safehasattr(self, 'full_nodes') and self.clnode_to_rev: +key = lambda n: self.clnode_to_rev[lookup(n)] +return [revlog.rev(n) for n in sorted(nodelist, key=key)] + # for generaldelta revlogs, we linearize the revs; this will both be # much quicker and generate a much smaller bundle if (revlog._generaldelta and self._reorder is None) or self._reorder: diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -51,28 +51,6 @@ extensions.wrapfunction( changegroup.cg1packer, 'generatefiles', generatefiles) -# In a perfect world, we'd generate better ellipsis-ified graphs -# for non-changelog revlogs. In practice, we haven't started doing -# that yet, so the resulting DAGs for the manifestlog and filelogs -# are actually full of bogus parentage on all the ellipsis -# nodes. This has the side effect that, while the contents are -# correct, the individual DAGs might be completely out of whack in -# a case like 882681bc3166 and its ancestors (back about 10 -# revisions or so) in the main hg repo. -# -# The one invariant we *know* holds is that the new (potentially -# bogus) DAG shape will be valid if we order the nodes in the -# order that they're introduced in dramatis personae by the -# changelog, so what we do is we sort the non-changelog histories -# by the order in which they are used by the changelog. -def _sortgroup(orig, self, revlog, nodelist, lookup): -if not util.safehasattr(self, 'full_nodes') or not self.clnode_to_rev: -return orig(self, revlog, nodelist, lookup) -key = lambda n: self.clnode_to_rev[lookup(n)] -return [revlog.rev(n) for n in sorted(nodelist, key=key)] - -extensions.wrapfunction(changegroup.cg1packer, '_sortgroup', _sortgroup) - def generate(orig, self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' # Note: other than delegating to orig, the only deviation in To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4060: changegroup: move ellipsisdata() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is a pretty straightforward copy of the function. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4060 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -14,6 +14,7 @@ from .i18n import _ from .node import ( hex, +nullid, nullrev, short, ) @@ -26,6 +27,7 @@ mdiff, phases, pycompat, +revlog, util, ) @@ -495,6 +497,21 @@ return d return readexactly(self._fh, n) +def ellipsisdata(packer, rev, revlog_, p1, p2, data, linknode): +n = revlog_.node(rev) +p1n, p2n = revlog_.node(p1), revlog_.node(p2) +flags = revlog_.flags(rev) +flags |= revlog.REVIDX_ELLIPSIS +meta = packer.builddeltaheader( +n, p1n, p2n, nullid, linknode, flags) +# TODO: try and actually send deltas for ellipsis data blocks +diffheader = mdiff.trivialdiffheader(len(data)) +l = len(meta) + len(diffheader) + len(data) +return ''.join((chunkheader(l), +meta, +diffheader, +data)) + class cg1packer(object): deltaheader = _CHANGEGROUPV1_DELTA_HEADER version = '01' diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -12,10 +12,8 @@ changegroup, error, extensions, -mdiff, node, pycompat, -revlog, util, ) @@ -54,21 +52,6 @@ extensions.wrapfunction( changegroup.cg1packer, 'generatefiles', generatefiles) -def ellipsisdata(packer, rev, revlog_, p1, p2, data, linknode): -n = revlog_.node(rev) -p1n, p2n = revlog_.node(p1), revlog_.node(p2) -flags = revlog_.flags(rev) -flags |= revlog.REVIDX_ELLIPSIS -meta = packer.builddeltaheader( -n, p1n, p2n, node.nullid, linknode, flags) -# TODO: try and actually send deltas for ellipsis data blocks -diffheader = mdiff.trivialdiffheader(len(data)) -l = len(meta) + len(diffheader) + len(data) -return ''.join((changegroup.chunkheader(l), -meta, -diffheader, -data)) - def close(orig, self): getattr(self, 'clrev_to_localrev', {}).clear() if getattr(self, 'next_clrev_to_localrev', {}): @@ -330,7 +313,7 @@ else: p1, p2 = sorted(local(p) for p in linkparents) n = revlog.node(rev) -yield ellipsisdata( +yield changegroup.ellipsisdata( self, rev, revlog, p1, p2, revlog.revision(n), linknode) extensions.wrapfunction(changegroup.cg1packer, 'revchunk', revchunk) To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4067: changegroup: move generate() modifications from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Narrow had a custom version of generate() that was essentially a copy of generate() with inline additions to facilitate ellipses serving. This commit inlines those modifications into generate(). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4067 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -660,20 +660,52 @@ clrevorder = {} mfs = {} # needed manifests fnodes = {} # needed file nodes +mfl = repo.manifestlog +# TODO violates storage abstraction. +mfrevlog = mfl._revlog changedfiles = set() -# Callback for the changelog, used to collect changed files and manifest -# nodes. +ellipsesmode = util.safehasattr(self, 'full_nodes') + +# Callback for the changelog, used to collect changed files and +# manifest nodes. # Returns the linkrev node (identity in the changelog case). def lookupcl(x): c = cl.read(x) clrevorder[x] = len(clrevorder) -n = c[0] -# record the first changeset introducing this manifest version -mfs.setdefault(n, x) -# Record a complete list of potentially-changed files in -# this manifest. -changedfiles.update(c[3]) + +if ellipsesmode: +# Only update mfs if x is going to be sent. Otherwise we +# end up with bogus linkrevs specified for manifests and +# we skip some manifest nodes that we should otherwise +# have sent. +if (x in self.full_nodes +or cl.rev(x) in self.precomputed_ellipsis): +n = c[0] +# Record the first changeset introducing this manifest +# version. +mfs.setdefault(n, x) +# Set this narrow-specific dict so we have the lowest +# manifest revnum to look up for this cl revnum. (Part of +# mapping changelog ellipsis parents to manifest ellipsis +# parents) +self.next_clrev_to_localrev.setdefault(cl.rev(x), + mfrevlog.rev(n)) +# We can't trust the changed files list in the changeset if the +# client requested a shallow clone. +if self.is_shallow: +changedfiles.update(mfl[c[0]].read().keys()) +else: +changedfiles.update(c[3]) +else: + +n = c[0] +# record the first changeset introducing this manifest version +mfs.setdefault(n, x) +# Record a complete list of potentially-changed files in +# this manifest. +changedfiles.update(c[3]) + return x self._verbosenote(_('uncompressed size of bundle content:\n')) @@ -708,6 +740,13 @@ for chunk in self.generatemanifests(commonrevs, clrevorder, fastpathlinkrev, mfs, fnodes, source): yield chunk + +if ellipsesmode: +mfdicts = None +if self.is_shallow: +mfdicts = [(self._repo.manifestlog[n].read(), lr) + for (n, lr) in mfs.iteritems()] + mfs.clear() clrevs = set(cl.rev(x) for x in clnodes) @@ -722,6 +761,14 @@ revs = ((r, llr(r)) for r in filerevlog) return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs) +if ellipsesmode: +# We need to pass the mfdicts variable down into +# generatefiles(), but more than one command might have +# wrapped generatefiles so we can't modify the function +# signature. Instead, we pass the data to ourselves using an +# instance attribute. I'm sorry. +self._mfdicts = mfdicts + for chunk in self.generatefiles(changedfiles, linknodes, commonrevs, source): yield chunk diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py deleted file mode 100644 --- a/hgext/narrow/narrowchangegroup.py +++ /dev/null @@ -1,145 +0,0 @@ -# narrowchangegroup.py - narrow clone changegroup creation and consumption -# -# Copyright 2017 Google, Inc. -# -# This software may be used and distributed according to the terms of the -# GNU General Public License version 2 or any later version. - -from __future__
D4063: changegroup: move revchunk() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The monkeypatched revchunk for ellipses serving is a completely independent implementation. We model it as such in the changegroup code. revchunk() is now a simple proxy function. Again, I wish we had better APIs here. Especially since this narrow code is part of cg1packer and cg1packer can't be used with narrow. Class inheritance is wonky. And I will definitely be making changes to changegroup code for delta generation. As part of the code move, `node.nullrev` was replaced by `nullrev`. And a reference to `orig` was replaced to call `self._revchunknormal` directly. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4063 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -805,6 +805,14 @@ return prev def revchunk(self, revlog, rev, prev, linknode): +if util.safehasattr(self, 'full_nodes'): +fn = self._revchunknarrow +else: +fn = self._revchunknormal + +return fn(revlog, rev, prev, linknode) + +def _revchunknormal(self, revlog, rev, prev, linknode): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) base = self.deltaparent(revlog, rev, p1, p2, prev) @@ -834,6 +842,114 @@ yield chunkheader(l) yield meta yield delta + +def _revchunknarrow(self, revlog, rev, prev, linknode): +# build up some mapping information that's useful later. See +# the local() nested function below. +if not self.changelog_done: +self.clnode_to_rev[linknode] = rev +linkrev = rev +self.clrev_to_localrev[linkrev] = rev +else: +linkrev = self.clnode_to_rev[linknode] +self.clrev_to_localrev[linkrev] = rev + +# This is a node to send in full, because the changeset it +# corresponds to was a full changeset. +if linknode in self.full_nodes: +for x in self._revchunknormal(revlog, rev, prev, linknode): +yield x +return + +# At this point, a node can either be one we should skip or an +# ellipsis. If it's not an ellipsis, bail immediately. +if linkrev not in self.precomputed_ellipsis: +return + +linkparents = self.precomputed_ellipsis[linkrev] +def local(clrev): +"""Turn a changelog revnum into a local revnum. + +The ellipsis dag is stored as revnums on the changelog, +but when we're producing ellipsis entries for +non-changelog revlogs, we need to turn those numbers into +something local. This does that for us, and during the +changelog sending phase will also expand the stored +mappings as needed. +""" +if clrev == nullrev: +return nullrev + +if not self.changelog_done: +# If we're doing the changelog, it's possible that we +# have a parent that is already on the client, and we +# need to store some extra mapping information so that +# our contained ellipsis nodes will be able to resolve +# their parents. +if clrev not in self.clrev_to_localrev: +clnode = revlog.node(clrev) +self.clnode_to_rev[clnode] = clrev +return clrev + +# Walk the ellipsis-ized changelog breadth-first looking for a +# change that has been linked from the current revlog. +# +# For a flat manifest revlog only a single step should be necessary +# as all relevant changelog entries are relevant to the flat +# manifest. +# +# For a filelog or tree manifest dirlog however not every changelog +# entry will have been relevant, so we need to skip some changelog +# nodes even after ellipsis-izing. +walk = [clrev] +while walk: +p = walk[0] +walk = walk[1:] +if p in self.clrev_to_localrev: +return self.clrev_to_localrev[p] +elif p in self.full_nodes: +walk.extend([pp for pp in self._repo.changelog.parentrevs(p) +if pp != nullrev]) +elif p in self.precomputed_ellipsis: +walk.extend([pp for pp in self.precomputed_ellipsis[p] +if pp != nullrev]) +else: +# In this case, we've got an ellipsis with
D4062: changegroup: move deltaparent() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I'm not keen on performing the attribute sniff to test for presence of ellipses mode: I'd rather we use a separate packer instance that was ellipses mode specific. But I've tried to formalize a better API without narrow in core and I can't make sense of all the monkeypatching. My goal is to inline as much of the monkeypatching as possible then refactor the changegroup generation API. We add this code to the cg2packer because narrow doesn't work with cg1. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4062 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -854,6 +854,21 @@ self._reorder = False def deltaparent(self, revlog, rev, p1, p2, prev): +# Narrow ellipses mode. +if util.safehasattr(self, 'full_nodes'): +# TODO: send better deltas when in narrow mode. +# +# changegroup.group() loops over revisions to send, +# including revisions we'll skip. What this means is that +# `prev` will be a potentially useless delta base for all +# ellipsis nodes, as the client likely won't have it. In +# the future we should do bookkeeping about which nodes +# have been sent to the client, and try to be +# significantly smarter about delta bases. This is +# slightly tricky because this same code has to work for +# all revlogs, and we don't have the linkrev/linknode here. +return p1 + dp = revlog.deltaparent(rev) if dp == nullrev and revlog.storedeltachains: # Avoid sending full revisions when delta parent is null. Pick prev diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -316,20 +316,3 @@ yield changegroup.ellipsisdata( self, rev, revlog, p1, p2, revlog.revision(n), linknode) extensions.wrapfunction(changegroup.cg1packer, 'revchunk', revchunk) - -def deltaparent(orig, self, revlog, rev, p1, p2, prev): -if util.safehasattr(self, 'full_nodes'): -# TODO: send better deltas when in narrow mode. -# -# changegroup.group() loops over revisions to send, -# including revisions we'll skip. What this means is that -# `prev` will be a potentially useless delta base for all -# ellipsis nodes, as the client likely won't have it. In -# the future we should do bookkeeping about which nodes -# have been sent to the client, and try to be -# significantly smarter about delta bases. This is -# slightly tricky because this same code has to work for -# all revlogs, and we don't have the linkrev/linknode here. -return p1 -return orig(self, revlog, rev, p1, p2, prev) -extensions.wrapfunction(changegroup.cg2packer, 'deltaparent', deltaparent) To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4066: changegroup: move generatefiles() from narrow
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The code is a bit ugly in that it overrides the linknodes function that is passed in as a function. I'd like to think that the caller of generatefiles() would pass in the appropriate function. We can clean this up later. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4066 AFFECTED FILES hgext/narrow/narrowchangegroup.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -799,6 +799,42 @@ # The 'source' parameter is useful for extensions def generatefiles(self, changedfiles, linknodes, commonrevs, source): +changedfiles = list(filter(self._filematcher, changedfiles)) + +if getattr(self, 'is_shallow', False): +# See comment in generate() for why this sadness is a thing. +mfdicts = self._mfdicts +del self._mfdicts +# In a shallow clone, the linknodes callback needs to also include +# those file nodes that are in the manifests we sent but weren't +# introduced by those manifests. +commonctxs = [self._repo[c] for c in commonrevs] +oldlinknodes = linknodes +clrev = self._repo.changelog.rev + +# Defining this function has a side-effect of overriding the +# function of the same name that was passed in as an argument. +# TODO have caller pass in appropriate function. +def linknodes(flog, fname): +for c in commonctxs: +try: +fnode = c.filenode(fname) +self.clrev_to_localrev[c.rev()] = flog.rev(fnode) +except error.ManifestLookupError: +pass +links = oldlinknodes(flog, fname) +if len(links) != len(mfdicts): +for mf, lr in mfdicts: +fnode = mf.get(fname, None) +if fnode in links: +links[fnode] = min(links[fnode], lr, key=clrev) +elif fnode: +links[fnode] = lr +return links + +return self._generatefiles(changedfiles, linknodes, commonrevs, source) + +def _generatefiles(self, changedfiles, linknodes, commonrevs, source): repo = self._repo progress = repo.ui.makeprogress(_('bundling'), unit=_('files'), total=len(changedfiles)) diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py --- a/hgext/narrow/narrowchangegroup.py +++ b/hgext/narrow/narrowchangegroup.py @@ -10,47 +10,12 @@ from mercurial.i18n import _ from mercurial import ( changegroup, -error, extensions, node, util, ) def setup(): -def generatefiles(orig, self, changedfiles, linknodes, commonrevs, - source): -changedfiles = list(filter(self._filematcher, changedfiles)) - -if getattr(self, 'is_shallow', False): -# See comment in generate() for why this sadness is a thing. -mfdicts = self._mfdicts -del self._mfdicts -# In a shallow clone, the linknodes callback needs to also include -# those file nodes that are in the manifests we sent but weren't -# introduced by those manifests. -commonctxs = [self._repo[c] for c in commonrevs] -oldlinknodes = linknodes -clrev = self._repo.changelog.rev -def linknodes(flog, fname): -for c in commonctxs: -try: -fnode = c.filenode(fname) -self.clrev_to_localrev[c.rev()] = flog.rev(fnode) -except error.ManifestLookupError: -pass -links = oldlinknodes(flog, fname) -if len(links) != len(mfdicts): -for mf, lr in mfdicts: -fnode = mf.get(fname, None) -if fnode in links: -links[fnode] = min(links[fnode], lr, key=clrev) -elif fnode: -links[fnode] = lr -return links -return orig(self, changedfiles, linknodes, commonrevs, source) -extensions.wrapfunction( -changegroup.cg1packer, 'generatefiles', generatefiles) - def generate(orig, self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' # Note: other than delegating to orig, the only deviation in To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel
D4057: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
martinvonz added inline comments. INLINE COMMENTS > narrowspec.py:143 > raise > -return _parsestoredpatterns(spec) > +# we should care about the profiles returned too > +includepats, excludepats, __ = sparse.parseconfig(repo.ui, spec, > 'narrow') We should at least abort if they're in there. I think we should add that check already in this patch. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4057 To: pulkit, durin42, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4059: help: add quotes to a few commands we point to
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I didn't know that 'hg help "revsets.x or y"' was valid syntax, so the quoting is extra useful here to make it clear that that is an actual command. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4059 AFFECTED FILES mercurial/fileset.py mercurial/minifileset.py mercurial/revset.py tests/test-fileset.t tests/test-revset2.t CHANGE DETAILS diff --git a/tests/test-revset2.t b/tests/test-revset2.t --- a/tests/test-revset2.t +++ b/tests/test-revset2.t @@ -346,15 +346,15 @@ test ',' in `_list` $ log '0,1' hg: parse error: can't use a list in this context - (see hg help "revsets.x or y") + (see 'hg help "revsets.x or y"') [255] $ try '0,1,2' (list (symbol '0') (symbol '1') (symbol '2')) hg: parse error: can't use a list in this context - (see hg help "revsets.x or y") + (see 'hg help "revsets.x or y"') [255] test that chained `or` operations make balanced addsets diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -118,7 +118,7 @@ (symbol 'b') (symbol 'c')) hg: parse error: can't use a list in this context - (see hg help "filesets.x or y") + (see 'hg help "filesets.x or y"') [255] $ fileset '"path":.' @@ -298,7 +298,7 @@ [255] $ fileset '(1k, 2k)' hg: parse error: can't use a list in this context - (see hg help "filesets.x or y") + (see 'hg help "filesets.x or y"') [255] $ fileset 'size(1k)' 1k diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -242,7 +242,7 @@ def listset(repo, subset, *xs, **opts): raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "revsets.x or y"')) + hint=_('see \'hg help "revsets.x or y"\'')) def keyvaluepair(repo, subset, k, v, order): raise error.ParseError(_("can't use a key-value pair in this context")) diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py --- a/mercurial/minifileset.py +++ b/mercurial/minifileset.py @@ -71,7 +71,7 @@ raise error.ParseError(_("can't use negate operator in this context")) elif op == 'list': raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "filesets.x or y"')) + hint=_('see \'hg help "filesets.x or y"\'')) raise error.ProgrammingError('illegal tree: %r' % (tree,)) def compile(text): diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -67,7 +67,7 @@ def listmatch(mctx, *xs): raise error.ParseError(_("can't use a list in this context"), - hint=_('see hg help "filesets.x or y"')) + hint=_('see \'hg help "filesets.x or y"\'')) def func(mctx, a, b): funcname = getsymbol(a) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] fileset: extract language processing part to new module (API)
On Thu, Aug 2, 2018 at 6:26 AM Yuya Nishihara wrote: > # HG changeset patch > # User Yuya Nishihara > # Date 1532242245 -32400 > # Sun Jul 22 15:50:45 2018 +0900 > # Node ID e6e56b590c20c3a026a304f569e4e1edfd3b1b6a > # Parent 7b744a18768440cdca7662db7dc6179c1abd6613 > fileset: extract language processing part to new module (API) > Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3994: fastannotate: initial import from Facebook's hg-experimental
durin42 added a comment. In https://phab.mercurial-scm.org/D3994#62892, @quark wrote: > I'd also like to see C linelog benchmark data mentioned. The current commit message implies diff algorithm is the bottleneck. That's misleading. Please feel encouraged to contribute your own numbers here. I probably can't be bothered. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3994 To: durin42, #hg-reviewers Cc: quark, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3994: fastannotate: initial import from Facebook's hg-experimental
quark added a comment. I'd also like to see C linelog benchmark data mentioned. The current commit message implies diff algorithm is the bottleneck. That's misleading. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3994 To: durin42, #hg-reviewers Cc: quark, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 v2] utils: create a context manager to handle timing
On Thu, 2 Aug 2018 at 12:04, Yuya Nishihara wrote: > -_timenesting = [0] > > +@attr.s > > +class timedcmstats(object): > > +"""Stats information produced by the timedcm context manager on > entering.""" > > + > > +# the starting value of the timer as a float (meaning and > resulution is > > +# platform dependent, see util.timer) > > +start = attr.ib(default=attr.Factory(lambda: timer())) > > +# the number of seconds as a floating point value; starts at 0, > updated when > > +# the context is exited. > > +elapsed = attr.ib(default=0) > > +# the number of nested timedcm context managers. > > +level = attr.ib(default=1) > > + > > +def __str__(self): > > +return timecount(self.elapsed) if self.elapsed else '' > > Needs s/__str__/__bytes__/ and __str__ = encoding.strmethod(__bytes__) for > py3. > Can you send a follow up? > Patch emailed. > +@contextlib.contextmanager > > +def timedcm(): > > +"""A context manager that produces timing information for a given > context. > > + > > +On entering a timedcmstats instance is produced. > > + > > +This context manager is reentrant. > > + > > +""" > > +# track nested context managers > > +timedcm._nested += 1 > > +timing_stats = timedcmstats(level=timedcm._nested) > > +try: > > +yield timing_stats > > +finally: > > +timing_stats.elapsed = timer() - timing_stats.start > > +timedcm._nested -= 1 > > + > > +timedcm._nested = 0 > > This isn't thread safe, but is no worse than the original code. > If this needs to be threadsafe we can insert a `threading.local()` object here. But yes, the original code had this problem; the context manager only promises to be reentrant, not threadsafe. -- Martijn Pieters ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] util: make new timedcmstats class Python 3 compatible
# HG changeset patch # User Martijn Pieters # Date 1533239583 -3600 # Thu Aug 02 20:53:03 2018 +0100 # Branch stable # Node ID d7c68ee641ff02542680bdaa4bff95a348db688e # Parent 07ca3b8354d59c70db5f10448e53d4bbfd50e72e # EXP-Topic debugextensions util: make new timedcmstats class Python 3 compatible diff -r 07ca3b8354d5 -r d7c68ee641ff mercurial/util.py --- a/mercurial/util.py Wed Aug 01 16:06:53 2018 +0200 +++ b/mercurial/util.py Thu Aug 02 20:53:03 2018 +0100 @@ -2890,9 +2890,11 @@ # the number of nested timedcm context managers. level = attr.ib(default=1) -def __str__(self): +def __bytes__(self): return timecount(self.elapsed) if self.elapsed else '' +__str__ = encoding.strmethod(__bytes__) + @contextlib.contextmanager def timedcm(): """A context manager that produces timing information for a given context. @@ -2929,7 +2931,8 @@ result = func(*args, **kwargs) stderr = procutil.stderr stderr.write('%s%s: %s\n' % ( -' ' * time_stats.level * 2, func.__name__, time_stats)) +' ' * time_stats.level * 2, pycompat.bytestr(func.__name__), +time_stats)) return result return wrapper diff -r 07ca3b8354d5 -r d7c68ee641ff tests/test-util.py --- a/tests/test-util.pyWed Aug 01 16:06:53 2018 +0200 +++ b/tests/test-util.pyThu Aug 02 20:53:03 2018 +0100 @@ -70,8 +70,10 @@ def testtimedcmstatsstr(self): stats = util.timedcmstats() self.assertEqual(str(stats), '') +self.assertEqual(bytes(stats), b'') stats.elapsed = 12.34 -self.assertEqual(str(stats), util.timecount(12.34)) +self.assertEqual(str(stats), pycompat.sysstr(util.timecount(12.34))) +self.assertEqual(bytes(stats), util.timecount(12.34)) def testtimedcmcleanexit(self): # timestamps 1, 4, elapsed time of 4 - 1 = 3 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4056: sparse: add an action argument to parseconfig()
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This will help us in reusing this function to parse narrow config files and unfiying the config file parsing logic. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4056 AFFECTED FILES mercurial/sparse.py CHANGE DETAILS diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -31,9 +31,11 @@ # a per-repo option, possibly a repo requirement. enabled = False -def parseconfig(ui, raw): +def parseconfig(ui, raw, action): """Parse sparse config file content. +action is the command which is trigerring this read, can be narrow, sparse + Returns a tuple of includes, excludes, and profiles. """ includes = set() @@ -54,24 +56,25 @@ elif line == '[include]': if havesection and current != includes: # TODO pass filename into this API so we can report it. -raise error.Abort(_('sparse config cannot have includes ' + -'after excludes')) +raise error.Abort(_('%s config cannot have includes ' + +'after excludes') % action) havesection = True current = includes continue elif line == '[exclude]': havesection = True current = excludes elif line: if current is None: -raise error.Abort(_('sparse config entry outside of ' -'section: %s') % line, +raise error.Abort(_('%s config entry outside of ' +'section: %s') % (action, line), hint=_('add an [include] or [exclude] line ' 'to declare the entry type')) if line.strip().startswith('/'): -ui.warn(_('warning: sparse profile cannot use' + - ' paths starting with /, ignoring %s\n') % line) +ui.warn(_('warning: %s profile cannot use' + + ' paths starting with /, ignoring %s\n') +% (action, line)) continue current.add(line) @@ -102,7 +105,7 @@ raise error.Abort(_('cannot parse sparse patterns from working ' 'directory')) -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') ctx = repo[rev] if profiles: @@ -128,7 +131,7 @@ repo.ui.debug(msg) continue -pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw) +pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw, 'sparse') includes.update(pincludes) excludes.update(pexcludes) profiles.update(subprofs) @@ -516,7 +519,7 @@ force=False, removing=False): """Update the sparse config and working directory state.""" raw = repo.vfs.tryread('sparse') -oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw) +oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, 'sparse') oldstatus = repo.status() oldmatch = matcher(repo) @@ -556,7 +559,7 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') if not includes and not excludes: return @@ -572,7 +575,7 @@ with repo.wlock(): # read current configuration raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') aincludes, aexcludes, aprofiles = activeconfig(repo) # Import rules on top; only take in rules that are not yet @@ -582,7 +585,8 @@ with util.posixfile(util.expandpath(p), mode='rb') as fh: raw = fh.read() -iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw) +iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw, + 'sparse') oldsize = len(includes) + len(excludes) + len(profiles) includes.update(iincludes - aincludes) excludes.update(iexcludes - aexcludes) @@ -615,7 +619,8 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw) +oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw, + 'sparse')
D4058: narrowspec: remove the unused _parsestoredpatterns() function
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previous patch started using sparse.parseconfig() to read narrowspec and now we don't need this function. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4058 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -19,29 +19,6 @@ FILENAME = 'narrowspec' -def _parsestoredpatterns(text): -"""Parses the narrowspec format that's stored on disk.""" -patlist = None -includepats = [] -excludepats = [] -for l in text.splitlines(): -if l == '[includes]': -if patlist is None: -patlist = includepats -else: -raise error.Abort(_('narrowspec includes section must appear ' -'at most once, before excludes')) -elif l == '[excludes]': -if patlist is not excludepats: -patlist = excludepats -else: -raise error.Abort(_('narrowspec excludes section must appear ' -'at most once')) -else: -patlist.append(l) - -return set(includepats), set(excludepats) - def parseserverpatterns(text): """Parses the narrowspec format that's returned by the server.""" includepats = set() To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3968: amend: support "history-editing-backup" config option
khanchi97 updated this revision to Diff 9794. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3968?vs=9640=9794 REVISION DETAIL https://phab.mercurial-scm.org/D3968 AFFECTED FILES mercurial/cmdutil.py tests/test-amend.t CHANGE DETAILS diff --git a/tests/test-amend.t b/tests/test-amend.t --- a/tests/test-amend.t +++ b/tests/test-amend.t @@ -331,3 +331,37 @@ ? missing_content2_content2-untracked ? missing_content2_content3-untracked ? missing_missing_content3-untracked + +== +Test history-editing-backup config option| +== + $ hg init $TESTTMP/repo4 + $ cd $TESTTMP/repo4 + $ echo a>a + $ hg ci -Aqma + $ echo oops>b + $ hg ci -Aqm "b" + $ echo partiallyfixed > b + +#if obsstore-off + $ hg amend + saved backup bundle to $TESTTMP/repo4/.hg/strip-backup/95e899acf2ce-f11cb050-amend.hg +When history-editing-backup config option is set: + $ cat << EOF >> $HGRCPATH + > [ui] + > history-editing-backup = False + > EOF + $ echo fixed > b + $ hg amend + +#else + $ hg amend +When history-editing-backup config option is set: + $ cat << EOF >> $HGRCPATH + > [ui] + > history-editing-backup = False + > EOF + $ echo fixed > b + $ hg amend + +#endif diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2556,8 +2556,10 @@ obsmetadata = None if opts.get('note'): obsmetadata = {'note': encoding.fromlocal(opts['note'])} +backup = ui.configbool('ui', 'history-editing-backup') scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata, - fixphase=True, targetphase=commitphase) + fixphase=True, targetphase=commitphase, + backup=backup) # Fixing the dirstate because localrepo.commitctx does not update # it. This is rather convenient because we did not need to update To: khanchi97, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4055: rebase: move "backup" flag to rbsrt
khanchi97 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY It was getting messy to populate "backup" flag to calls of `_finishrebase()` and `_prepareabortorcontinue`, so made some changes to move "backup" flag to rbsrt. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4055 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -177,6 +177,7 @@ if e: self.extrafns = [e] +self.backupf = ui.configbool('ui', 'history-editing-backup') self.keepf = opts.get('keep', False) self.keepbranchesf = opts.get('keepbranches', False) self.obsoletenotrebased = {} @@ -343,6 +344,10 @@ msg = _('cannot continue inconsistent rebase') hint = _('use "hg rebase --abort" to clear broken state') raise error.Abort(msg, hint=hint) + +nobackup = (not backup) or (not self.backupf) +backup = not nobackup + if isabort: return abort(self.repo, self.originalwd, self.destmap, self.state, activebookmark=self.activebookmark, backup=backup, @@ -585,11 +590,7 @@ # case and realize that the commit was in progress. self.storestatus() -def _finishrebase(self, backup=True): -""" -backup: if False, no backup will be stored when stripping rebased - revisions -""" +def _finishrebase(self): repo, ui, opts = self.repo, self.ui, self.opts fm = ui.formatter('rebase', opts) fm.startitem() @@ -636,7 +637,7 @@ if self.collapsef and not self.keepf: collapsedas = newnode clearrebased(ui, repo, self.destmap, self.state, self.skipped, - collapsedas, self.keepf, fm=fm, backup=backup) + collapsedas, self.keepf, fm=fm, backup=self.backupf) clearstatus(repo) clearcollapsemsg(repo) @@ -833,8 +834,6 @@ userrevs = list(repo.revs(opts.get('auto_orphans'))) opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] opts['dest'] = '_destautoorphanrebase(SRC)' -backup = ui.configbool('ui', 'history-editing-backup') -opts['backup'] = backup if dryrun: return _dryrunrebase(ui, repo, opts) @@ -856,7 +855,6 @@ def _dryrunrebase(ui, repo, opts): rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts) confirm = opts.get('confirm') -backup = opts.get('backup') if confirm: ui.status(_('starting in-memory rebase\n')) else: @@ -878,7 +876,7 @@ if not ui.promptchoice(_(b'apply changes (yn)?' b'$$ $$ ')): # finish unfinished rebase -rbsrt._finishrebase(backup=backup) +rbsrt._finishrebase() else: rbsrt._prepareabortorcontinue(isabort=True, backup=False, suppwarns=True) @@ -909,7 +907,6 @@ destspace = opts.get('_destspace') contf = opts.get('continue') abortf = opts.get('abort') -backup = opts.get('backup') if opts.get('interactive'): try: if extensions.find('histedit'): @@ -940,7 +937,7 @@ ms = mergemod.mergestate.read(repo) mergeutil.checkunresolved(ms) -retcode = rbsrt._prepareabortorcontinue(abortf, backup=backup) +retcode = rbsrt._prepareabortorcontinue(abortf) if retcode is not None: return retcode else: @@ -969,7 +966,7 @@ with util.acceptintervention(dsguard): rbsrt._performrebase(tr) if not leaveunfinished: -rbsrt._finishrebase(backup=backup) +rbsrt._finishrebase() def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None, revf=None, destspace=None): To: khanchi97, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3887: rebase: support "history-editing-backup" config option
khanchi97 added a comment. In https://phab.mercurial-scm.org/D3887#62850, @pulkit wrote: > In https://phab.mercurial-scm.org/D3887#62825, @yuja wrote: > > > Queued, thanks. > > > > > @@ -829,6 +833,8 @@ > > > > > > userrevs = list(repo.revs(opts.get('auto_orphans'))) > > > opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] > > > opts['dest'] = '_destautoorphanrebase(SRC)' > > > > > > +backup = ui.configbool('ui', 'history-editing-backup') > > > +opts['backup'] = backup > > > > This seems getting ugly. Maybe the option can be carried by rbsrt instead? > > > > self.backupf = ui.configbool('ui', 'history-editing-backup') > > > > > I like Yuya's suggestion here. @khanchi97 can you please follow-up? Okay, I will send a follow-up. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3887 To: khanchi97, #hg-reviewers Cc: pulkit, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4053: [RFC]hgweb: garbage collect on every request in hgweb_mod too
av6 added a comment. Are you sure you're not just using hgwebdir_mod? hgweb_mod is for cases when you don't use --web-conf flag, at least that seems to be the logic that `hgweb.createapp()` uses to pick one of the two modules. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4053 To: pulkit, #hg-reviewers Cc: av6, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 4] i18n: omit redundant translatable synopsis text to avoid xgettext warning
# HG changeset patch # User FUJIWARA Katsunori # Date 1528687936 -32400 # Mon Jun 11 12:32:16 2018 +0900 # Node ID ddfbcd8d9351fb699d08482d2ced0e6cc42ea319 # Parent b2d92c607d9af9945a03cd2e5d781021bfc80de1 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r ddfbcd8d9351 # EXP-Topic refactor-update-pot i18n: omit redundant translatable synopsis text to avoid xgettext warning This empty translatable synopsis text causes xgettext warning below: Empty msgid. It is reserved by GNU gettext: gettext("") returns the header entry with meta information, not the empty string. This "synopsis" argument of @command annotation is omitable. diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -921,8 +921,7 @@ def debugfileset(ui, repo, expr, **opts) ui.write("%s\n" % f) @command('debugformat', - [] + cmdutil.formatteropts, -_('')) + [] + cmdutil.formatteropts) def debugformat(ui, repo, **opts): """display format information about the current repository ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4] i18n: avoid substitution of PYFILES at runtime for readability of output
# HG changeset patch # User FUJIWARA Katsunori # Date 1533211650 -32400 # Thu Aug 02 21:07:30 2018 +0900 # Node ID 984894e4ad78ef5799a6974d079d45bcf5a64f05 # Parent 2002c193f2bcb07ea898d6229835e7d61bc48aae # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 984894e4ad78 # EXP-Topic refactor-update-pot i18n: avoid substitution of PYFILES at runtime for readability of output This substitution decreases readability of "make update-pot" output, because PYFILES consists of many files. This patch makes "make update-pot" show "find mercurial hgext doc -name '*.py'" instead of many *.py files at runtime. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ PYTHON=python $(eval HGROOT := $(shell pwd)) HGPYTHONS ?= $(HGROOT)/build/pythons PURE= -PYFILES:=$(shell find mercurial hgext doc -name '*.py') +PYFILESCMD=find mercurial hgext doc -name '*.py' +PYFILES:=$(shell $(PYFILESCMD)) DOCFILES=mercurial/help/*.txt export LANGUAGE=C export LC_ALL=C @@ -145,7 +146,7 @@ i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n # parse them even though they are not marked for translation. # Extracting with an explicit encoding of ISO-8859-1 will make # xgettext "parse" and ignore them. - echo $(PYFILES) | xargs \ + $(PYFILESCMD) | xargs \ xgettext --package-name "Mercurial" \ --msgid-bugs-address "" \ --copyright-holder "Matt Mackall and others" \ ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 4] i18n: omit redundant warnings of GNU xgettext command
# HG changeset patch # User FUJIWARA Katsunori # Date 1533224280 -32400 # Fri Aug 03 00:38:00 2018 +0900 # Node ID b2d92c607d9af9945a03cd2e5d781021bfc80de1 # Parent 984894e4ad78ef5799a6974d079d45bcf5a64f05 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r b2d92c607d9a # EXP-Topic refactor-update-pot i18n: omit redundant warnings of GNU xgettext command At "make update-pot", GNU xgettext command shows many warning messages like below, but these are meaningless, because i18n-ed messages with unnamed arguments are intentional for Mercurial. FILE:LINE: warning: 'msgid' format string with unnamed arguments cannot be properly localized: The translator cannot reorder the arguments. Please consider using a format string with named arguments, and a mapping instead of a tuple for the arguments. This patch introduces i18n/hgxgettext.py, which omits such noisy warnings of xgettext, in order to increase readability of "make update-pot" output. In order to omit multi-lines warning messages of xgettext like above, this patch chooses "implementing specific command" instead of "filtering with POSIX standard command (sed or so)", for maintainability and extensibility. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -147,7 +147,8 @@ i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n # Extracting with an explicit encoding of ISO-8859-1 will make # xgettext "parse" and ignore them. $(PYFILESCMD) | xargs \ - xgettext --package-name "Mercurial" \ + $(PYTHON) i18n/hgxgettext.py \ + --package-name "Mercurial" \ --msgid-bugs-address "" \ --copyright-holder "Matt Mackall and others" \ --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \ diff --git a/i18n/hgxgettext.py b/i18n/hgxgettext.py new file mode 100755 --- /dev/null +++ b/i18n/hgxgettext.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# +# hgxgettxt - spawn GNU xgettext, and omit redundant messages for Mercurial +# +# Copyright 2018 FUJIWARA Katsunori +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from __future__ import absolute_import, print_function + +import os +import re +import sys + +# omittable message patterns: +# +# - 'format string with unnamed arguments': +# this is intentional implementation +# +omittable = re.compile('format string with unnamed arguments').search + +def itermessages(lines): +"""Iterate messages of GNU xgettext command given via lines + +This function assumes that below are part of the multi-lines +message. + +- empty line +- starts with space character +""" +pending = '' +for line in lines: +if not line.strip() or line[0].isspace(): +pending += line +else: +if pending: +yield pending +pending = line +if pending: +yield pending + +def filteroutput(stdout, stderr): +for message in itermessages(iter(stderr.readline, '')): +if not omittable(message): +sys.stderr.write(message) + +for line in iter(stdout.readline, ''): +sys.stdout.write(line) + +if __name__ == "__main__": +# in order to import the Mercurial modules from the source tree +# where hgxgettext.py is executed +sys.path.insert(0, os.getcwd()) + +from mercurial import pycompat +from mercurial.utils import procutil + +# join and shellquote are needed to re-use procutil.popen4(), which +# implies subprocess.Popen() with shell=True +cmd = ' '.join(procutil.shellquote(e) for e in ['xgettext'] + sys.argv[1:]) +stdin, stdout, stderr, proc = procutil.popen4(cmd) + +filteroutput(stdout, stderr) + +proc.wait() +rc = proc.returncode + +# this comes from procutil.system() +if pycompat.sysplatform == 'OpenVMS' and rc & 1: +rc = 0 + +sys.exit(rc) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 4] i18n: format warning of hggettext in standard compiler error style
# HG changeset patch # User FUJIWARA Katsunori # Date 1528689615 -32400 # Mon Jun 11 13:00:15 2018 +0900 # Node ID 7748d224f147c8d8d4990f6e8b2a1ce865283c26 # Parent ddfbcd8d9351fb699d08482d2ced0e6cc42ea319 # Available At https://bitbucket.org/foozy/mercurial-wip # hg pull https://bitbucket.org/foozy/mercurial-wip -r 7748d224f147 # EXP-Topic refactor-update-pot i18n: format warning of hggettext in standard compiler error style Now, hggettext specific warning messages are formatted in: FILENAME:LINENO:MESSAGE This allows editors to jump into corresponded line easily. diff --git a/i18n/hggettext b/i18n/hggettext --- a/i18n/hggettext +++ b/i18n/hggettext @@ -63,7 +63,7 @@ def poentry(path, lineno, s): doctestre = re.compile(r'^ +>>> ', re.MULTILINE) -def offset(src, doc, name, default): +def offset(src, doc, name, lineno, default): """Compute offset or issue a warning on stdout.""" # remove doctest part, in order to avoid backslash mismatching m = doctestre.search(doc) @@ -76,8 +76,9 @@ def offset(src, doc, name, default): # This can happen if the docstring contains unnecessary escape # sequences such as \" in a triple-quoted string. The problem # is that \" is turned into " and so doc wont appear in src. -sys.stderr.write("warning: unknown offset in %s, assuming %d lines\n" - % (name, default)) +sys.stderr.write("%s:%d:warning:" + " unknown docstr offset, assuming %d lines\n" + % (name, lineno, default)) return default else: return src.count('\n', 0, end) @@ -106,7 +107,7 @@ def docstrings(path): if not path.startswith('mercurial/') and mod.__doc__: with open(path) as fobj: src = fobj.read() -lineno = 1 + offset(src, mod.__doc__, path, 7) +lineno = 1 + offset(src, mod.__doc__, path, 1, 7) print(poentry(path, lineno, mod.__doc__)) functions = list(getattr(mod, 'i18nfunctions', [])) @@ -129,7 +130,6 @@ def docstrings(path): actualpath = '%s%s.py' % (funcmod.__name__.replace('.', '/'), extra) src = inspect.getsource(func) -name = "%s.%s" % (actualpath, func.__name__) lineno = inspect.getsourcelines(func)[1] doc = docobj.__doc__ origdoc = getattr(docobj, '_origdoc', '') @@ -137,9 +137,9 @@ def docstrings(path): doc = doc.rstrip() origdoc = origdoc.rstrip() if origdoc: -lineno += offset(src, origdoc, name, 1) +lineno += offset(src, origdoc, actualpath, lineno, 1) else: -lineno += offset(src, doc, name, 1) +lineno += offset(src, doc, actualpath, lineno, 1) print(poentry(actualpath, lineno, doc)) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3990: linelog: add a Python implementation of the linelog datastructure
durin42 added a comment. In https://phab.mercurial-scm.org/D3990#62806, @martinvonz wrote: > I'm still just trying to understand how weaves work. Here are some questions for you for now. We may want to document some of the answers in a follow-up patch (not just here in Phabricator). Tragically, I think you understand linelog.txt better than I do at this point - maybe send me patches as you work things out? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3990 To: durin42, #hg-reviewers, indygreg Cc: martinvonz, indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4012: changegroup: inline prune() logic from narrow
martinvonz added a comment. `hg import` is being annoying again, so can you rebase and update the remainder of the series? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4012 To: indygreg, durin42, #hg-reviewers Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4053: [RFC]hgweb: garbage collect on every request in hgweb_mod too
pulkit updated this revision to Diff 9792. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4053?vs=9787=9792 REVISION DETAIL https://phab.mercurial-scm.org/D4053 AFFECTED FILES mercurial/hgweb/hgweb_mod.py CHANGE DETAILS diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -9,6 +9,7 @@ from __future__ import absolute_import import contextlib +import gc import os from .common import ( @@ -305,8 +306,19 @@ with self._obtainrepo() as repo: profile = repo.ui.configbool('profiling', 'enabled') with profiling.profile(repo.ui, enabled=profile): -for r in self._runwsgi(req, res, repo): -yield r +try: +for r in self._runwsgi(req, res, repo): +yield r +finally: +# There are known cycles in localrepository that prevent +# those objects (and tons of held references) from being +# collected through normal refcounting. We mitigate those +# leaks by performing an explicit GC on every request. +# TODO remove this once leaks are fixed. +# TODO only run this on requests that create localrepository +# instances instead of every request. +gc.collect() + def _runwsgi(self, req, res, repo): rctx = requestcontext(self, repo, req, res) To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3887: rebase: support "history-editing-backup" config option
pulkit added a comment. In https://phab.mercurial-scm.org/D3887#62825, @yuja wrote: > Queued, thanks. > > > @@ -829,6 +833,8 @@ > > > > userrevs = list(repo.revs(opts.get('auto_orphans'))) > > opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] > > opts['dest'] = '_destautoorphanrebase(SRC)' > > > > +backup = ui.configbool('ui', 'history-editing-backup') > > +opts['backup'] = backup > > This seems getting ugly. Maybe the option can be carried by rbsrt instead? > > self.backupf = ui.configbool('ui', 'history-editing-backup') > I like Yuya's suggestion here. @khanchi97 can you please follow-up? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3887 To: khanchi97, #hg-reviewers Cc: pulkit, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4054: hgsubversion: add 4.7 to list of supported mercurial
pulkit added a comment. Sorry about sending this here, my gmail is not allowing me send emails from command line. This is meant for hgsubversion. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4054 To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4054: hgsubversion: add 4.7 to list of supported mercurial
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The tox.ini changes were authored by Augie Fackler. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4054 AFFECTED FILES hgsubversion/__init__.py tox.ini CHANGE DETAILS diff --git a/tox.ini b/tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = hg37,hg38,hg39,hg40,hg41,hg42,hg43,hg44,hg45,hg46 +envlist = hg37,hg38,hg39,hg40,hg41,hg42,hg43,hg44,hg45,hg46,hg47 [testenv] deps= @@ -14,5 +14,6 @@ hg44: Mercurial==4.4.2 hg45: Mercurial==4.5.2 hg46: Mercurial==4.6 +hg47: Mercurial==4.7 subvertpy commands=nosetests {posargs} diff --git a/hgsubversion/__init__.py b/hgsubversion/__init__.py --- a/hgsubversion/__init__.py +++ b/hgsubversion/__init__.py @@ -15,7 +15,7 @@ For more information and instructions, see :hg:`help subversion`. ''' -testedwith = '3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6' +testedwith = '3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7' import os To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4049: testrunner: allow multiple #testcases
martinvonz updated this revision to Diff 9790. martinvonz marked an inline comment as done. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4049?vs=9784=9790 REVISION DETAIL https://phab.mercurial-scm.org/D4049 AFFECTED FILES tests/run-tests.py tests/test-run-tests.t CHANGE DETAILS diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t --- a/tests/test-run-tests.t +++ b/tests/test-run-tests.t @@ -896,6 +896,40 @@ .. # Ran 2 tests, 0 skipped, 0 failed. +When using multiple dimensions of "#testcases" in .t files + + $ cat > test-cases.t <<'EOF' + > #testcases a b + > #testcases c d + > #if a d + > $ echo $TESTCASE + > a#d + > #endif + > #if b c + > $ echo yes + > no + > #endif + > EOF + $ rt test-cases.t + .. + --- $TESTTMP/test-cases.t + +++ $TESTTMP/test-cases.t#b#c.err + @@ -6,5 +6,5 @@ + #endif + #if b c + $ echo yes + - no + + yes + #endif + + ERROR: test-cases.t#b#c output changed + !. + Failed test-cases.t#b#c: output changed + # Ran 4 tests, 0 skipped, 1 failed. + python hash seed: * (glob) + [1] + + $ rm test-cases.t#b#c.err $ rm test-cases.t (reinstall) diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -285,12 +285,12 @@ If path does not exist, return an empty set. """ -cases = set() +cases = [] try: with open(path, 'rb') as f: for l in f: if l.startswith(b'#testcases '): -cases.update(l[11:].split()) +cases.append(sorted(l[11:].split())) except IOError as ex: if ex.errno != errno.ENOENT: raise @@ -1242,14 +1242,15 @@ def __init__(self, path, *args, **kwds): # accept an extra "case" parameter -case = kwds.pop('case', None) +case = kwds.pop('case', []) self._case = case -self._allcases = parsettestcases(path) +self._allcases = {x for y in parsettestcases(path) for x in y} super(TTest, self).__init__(path, *args, **kwds) if case: -self.name = '%s#%s' % (self.name, _strpath(case)) -self.errpath = b'%s#%s.err' % (self.errpath[:-4], case) -self._tmpname += b'-%s' % case +casepath = _strpath('#'.join(case)) +self.name = '%s#%s' % (self.name, casepath) +self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath) +self._tmpname += b'-%s' % casepath self._have = {} @property @@ -1323,10 +1324,10 @@ reqs = [] for arg in args: if arg.startswith(b'no-') and arg[3:] in self._allcases: -if arg[3:] == self._case: +if arg[3:] in self._case: return False elif arg in self._allcases: -if arg != self._case: +if arg not in self._case: return False else: reqs.append(arg) @@ -1370,10 +1371,11 @@ if os.getenv('MSYSTEM'): script.append(b'alias pwd="pwd -W"\n') if self._case: +casestr = '#'.join(self._case) if isinstance(self._case, str): -quoted = shellquote(self._case) +quoted = shellquote(casestr) else: -quoted = shellquote(self._case.decode('utf8')).encode('utf8') +quoted = shellquote(casestr.decode('utf8')).encode('utf8') script.append(b'TESTCASE=%s\n' % quoted) script.append(b'export TESTCASE\n') @@ -2666,31 +2668,42 @@ expanded_args.append(arg) args = expanded_args -testcasepattern = re.compile(br'([\w-]+\.t|py)(#([a-zA-Z0-9_\-\.]+))') +testcasepattern = re.compile(br'([\w-]+\.t|py)(#([a-zA-Z0-9_\-\.#]+))') tests = [] for t in args: -case = None +case = [] if not (os.path.basename(t).startswith(b'test-') and (t.endswith(b'.py') or t.endswith(b'.t'))): m = testcasepattern.match(t) if m is not None: -t, _, case = m.groups() +t, _, casestr = m.groups() +if casestr: +case = casestr.split('#') else: continue if t.endswith(b'.t'): # .t file may contain multiple test cases -cases = sorted(parsettestcases(t)) -if cases: -if case is not None and case in cases: -tests += [{'path': t, 'case': case}] -elif case is not None and case not in cases: +casedimensions = parsettestcases(t) +if casedimensions: +cases = [] +def addcases(case, casedimensions): +
D4049: testrunner: allow multiple #testcases
martinvonz added a comment. Added a failed test REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4005: index: store nullrev as -1 in nodetree
martinvonz updated this revision to Diff 9789. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4005?vs=9697=9789 REVISION DETAIL https://phab.mercurial-scm.org/D4005 AFFECTED FILES mercurial/cext/revlog.c CHANGE DETAILS diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -32,7 +32,7 @@ * A base-16 trie for fast node->rev mapping. * * Positive value is index of the next node in the trie - * Negative value is a leaf: -(rev + 1) + * Negative value is a leaf: -(rev + 2) * Zero is empty */ typedef struct { @@ -231,7 +231,7 @@ Py_ssize_t length = index_length(self); const char *data; - if (pos == length - 1 || pos == INT_MAX) + if (pos == length - 1 || pos == -1) return nullid; if (pos >= length) @@ -1010,7 +1010,7 @@ const char *n; Py_ssize_t i; - v = -(v + 1); + v = -(v + 2); n = index_node(self, v); if (n == NULL) return -2; @@ -1062,17 +1062,17 @@ v = n->children[k]; if (v == 0) { - n->children[k] = -rev - 1; + n->children[k] = -rev - 2; return 0; } if (v < 0) { - const char *oldnode = index_node_existing(self, -(v + 1)); + const char *oldnode = index_node_existing(self, -(v + 2)); int noff; if (oldnode == NULL) return -1; if (!memcmp(oldnode, node, 20)) { - n->children[k] = -rev - 1; + n->children[k] = -rev - 2; return 0; } noff = nt_new(self); @@ -1097,8 +1097,8 @@ static int nt_delete_node(indexObject *self, const char *node) { - /* rev==-1 happens to get encoded as 0, which is interpreted as not set */ - return nt_insert(self, node, -1); + /* rev==-2 happens to get encoded as 0, which is interpreted as not set */ + return nt_insert(self, node, -2); } static int nt_init(indexObject *self) @@ -1120,7 +1120,7 @@ self->ntrev = (int)index_length(self) - 1; self->ntlookups = 1; self->ntmisses = 0; - if (nt_insert(self, nullid, INT_MAX) == -1) + if (nt_insert(self, nullid, -1) == -1) return -1; } return 0; @@ -1290,7 +1290,7 @@ v = n->children[k]; if (v < 0) { const char *n; - v = -(v + 1); + v = -(v + 2); n = index_node_existing(self, v); if (n == NULL) return -3; To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4004: index: create function for deleting node from nodetree
martinvonz updated this revision to Diff 9788. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4004?vs=9696=9788 REVISION DETAIL https://phab.mercurial-scm.org/D4004 AFFECTED FILES mercurial/cext/revlog.c CHANGE DETAILS diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -1095,6 +1095,12 @@ return -1; } +static int nt_delete_node(indexObject *self, const char *node) +{ + /* rev==-1 happens to get encoded as 0, which is interpreted as not set */ + return nt_insert(self, node, -1); +} + static int nt_init(indexObject *self) { if (self->nt == NULL) { @@ -1795,7 +1801,7 @@ PyObject *tuple = PyList_GET_ITEM(self->added, i); PyObject *node = PyTuple_GET_ITEM(tuple, 7); - nt_insert(self, PyBytes_AS_STRING(node), -1); + nt_delete_node(self, PyBytes_AS_STRING(node)); } if (start == 0) @@ -1854,7 +1860,7 @@ if (node == NULL) return -1; - nt_insert(self, node, -1); + nt_delete_node(self, node); } if (self->added) nt_invalidate_added(self, 0); @@ -1907,7 +1913,7 @@ return -1; if (value == NULL) - return self->nt ? nt_insert(self, node, -1) : 0; + return self->nt ? nt_delete_node(self, node) : 0; rev = PyInt_AsLong(value); if (rev > INT_MAX || rev < 0) { if (!PyErr_Occurred()) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4003: index: write expression for encoded revision index consistently
martinvonz added a comment. In https://phab.mercurial-scm.org/D4003#62821, @yuja wrote: > > - n->children[k] = -rev - 1; +n->children[k] = -(rev + 1); > > This is technically less correct since (MAX_INT + 1) overflows, but maybe > we don't care? Good point, I had not noticed before that the encoding was using one form and the decoding was using the other and the reason was almost certainly to avoid integer overflow. It won't be relevant after https://phab.mercurial-scm.org/D4005, but I'll dequeue this patch and update https://phab.mercurial-scm.org/D4004 and https://phab.mercurial-scm.org/D4005. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4003 To: martinvonz, #hg-reviewers, pulkit Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4053: [RFC]hgweb: garbage collect on every request in hgweb_mod too
pulkit created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY We recently updated to mercurial 4.6.2 on our servers and also increased number of requests to be made on server at one time. This made hgweb instance takes up a lot of memory, sometime upto 50GB of memory when requests are made parallely. This patch is motivated from https://www.mercurial-scm.org/repo/hg-committed/rev/ff2370a70fe8 which adds gc.collect() call for the server which serves multiple repositories. I tried profiling this fix, sometimes this shows less memory usage, sometimes more, so I am not sure whether this is right and hence RFC tag. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4053 AFFECTED FILES mercurial/hgweb/hgweb_mod.py CHANGE DETAILS diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -305,8 +305,19 @@ with self._obtainrepo() as repo: profile = repo.ui.configbool('profiling', 'enabled') with profiling.profile(repo.ui, enabled=profile): -for r in self._runwsgi(req, res, repo): -yield r +try: +for r in self._runwsgi(req, res, repo): +yield r +finally: +# There are known cycles in localrepository that prevent +# those objects (and tons of held references) from being +# collected through normal refcounting. We mitigate those +# leaks by performing an explicit GC on every request. +# TODO remove this once leaks are fixed. +# TODO only run this on requests that create localrepository +# instances instead of every request. +gc.collect() + def _runwsgi(self, req, res, repo): rctx = requestcontext(self, repo, req, res) To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3887: rebase: support "history-editing-backup" config option
This revision was automatically updated to reflect the committed changes. Closed by commit rHG7de767e15f52: rebase: support history-editing-backup config option (authored by khanchi97, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3887?vs=9639=9786 REVISION DETAIL https://phab.mercurial-scm.org/D3887 AFFECTED FILES hgext/rebase.py mercurial/repair.py mercurial/scmutil.py tests/test-rebase-backup.t CHANGE DETAILS diff --git a/tests/test-rebase-backup.t b/tests/test-rebase-backup.t new file mode 100644 --- /dev/null +++ b/tests/test-rebase-backup.t @@ -0,0 +1,150 @@ + $ cat << EOF >> $HGRCPATH + > [extensions] + > rebase= + > EOF + +== +Test history-editing-backup config option | +== +Test with Pre-obsmarker rebase: +1) When config option is not set: + $ hg init repo1 + $ cd repo1 + $ echo a>a + $ hg ci -qAma + $ echo b>b + $ hg ci -qAmb + $ echo c>c + $ hg ci -qAmc + $ hg up 0 -q + $ echo d>d + $ hg ci -qAmd + $ echo e>e + $ hg ci -qAme + $ hg log -GT "{rev}: {firstline(desc)}\n" + @ 4: e + | + o 3: d + | + | o 2: c + | | + | o 1: b + |/ + o 0: a + + $ hg rebase -s 1 -d . + rebasing 1:d2ae7f538514 "b" + rebasing 2:177f92b77385 "c" + saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/d2ae7f538514-c7ed7a78-rebase.hg + $ hg log -GT "{rev}: {firstline(desc)}\n" + o 4: c + | + o 3: b + | + @ 2: e + | + o 1: d + | + o 0: a + + +2) When config option is set: + $ cat << EOF >> $HGRCPATH + > [ui] + > history-editing-backup = False + > EOF + + $ echo f>f + $ hg ci -Aqmf + $ echo g>g + $ hg ci -Aqmg + $ hg log -GT "{rev}: {firstline(desc)}\n" + @ 6: g + | + o 5: f + | + | o 4: c + | | + | o 3: b + |/ + o 2: e + | + o 1: d + | + o 0: a + + $ hg rebase -s 3 -d . + rebasing 3:05bff2a95b12 "b" + rebasing 4:1762bde4404d "c" + + $ hg log -GT "{rev}: {firstline(desc)}\n" + o 6: c + | + o 5: b + | + @ 4: g + | + o 3: f + | + o 2: e + | + o 1: d + | + o 0: a + +Test when rebased revisions are stripped during abort: +== + + $ echo conflict > c + $ hg ci -Am "conflict with c" + adding c + created new head + $ hg log -GT "{rev}: {firstline(desc)}\n" + @ 7: conflict with c + | + | o 6: c + | | + | o 5: b + |/ + o 4: g + | + o 3: f + | + o 2: e + | + o 1: d + | + o 0: a + +When history-editing-backup = True: + $ cat << EOF >> $HGRCPATH + > [ui] + > history-editing-backup = True + > EOF + $ hg rebase -s 5 -d . + rebasing 5:1f8148a544ee "b" + rebasing 6:f8bc7d28e573 "c" + merging c + warning: conflicts while merging c! (edit, then use 'hg resolve --mark') + unresolved conflicts (see hg resolve, then hg rebase --continue) + [1] + $ hg rebase --abort + saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/818c1a43c916-2b644d96-backup.hg + rebase aborted + +When history-editing-backup = False: + $ cat << EOF >> $HGRCPATH + > [ui] + > history-editing-backup = False + > EOF + $ hg rebase -s 5 -d . + rebasing 5:1f8148a544ee "b" + rebasing 6:f8bc7d28e573 "c" + merging c + warning: conflicts while merging c! (edit, then use 'hg resolve --mark') + unresolved conflicts (see hg resolve, then hg rebase --continue) + [1] + $ hg rebase --abort + rebase aborted + $ cd .. + diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -780,7 +780,7 @@ return self._revcontains(self._torev(node)) def cleanupnodes(repo, replacements, operation, moves=None, metadata=None, - fixphase=False, targetphase=None): + fixphase=False, targetphase=None, backup=True): """do common cleanups when old nodes are replaced by new nodes That includes writing obsmarkers or stripping nodes, and moving bookmarks. @@ -905,7 +905,8 @@ from . import repair # avoid import cycle tostrip = list(replacements) if tostrip: -repair.delayedstrip(repo.ui, repo, tostrip, operation) +repair.delayedstrip(repo.ui, repo, tostrip, operation, +backup=backup) def addremove(repo, matcher, prefix, opts=None): if opts is None: diff --git a/mercurial/repair.py b/mercurial/repair.py --- a/mercurial/repair.py +++ b/mercurial/repair.py @@ -298,24 +298,24 @@ if roots: strip(self.ui, self.repo, roots, self.backup, self.topic) -def delayedstrip(ui, repo, nodelist, topic=None): +def delayedstrip(ui, repo, nodelist, topic=None, backup=True): """like strip, but works inside transaction and won't strip irreverent revs nodelist must explicitly contain all descendants. Otherwise a warning will be printed that some nodes are not stripped. -Always do a backup. The last
Re: D3887: rebase: support "history-editing-backup" config option
Queued, thanks. > @@ -829,6 +833,8 @@ > userrevs = list(repo.revs(opts.get('auto_orphans'))) > opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] > opts['dest'] = '_destautoorphanrebase(SRC)' > +backup = ui.configbool('ui', 'history-editing-backup') > +opts['backup'] = backup This seems getting ugly. Maybe the option can be carried by rbsrt instead? ``` self.backupf = ui.configbool('ui', 'history-editing-backup') ``` ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3887: rebase: support "history-editing-backup" config option
yuja added a comment. Queued, thanks. > @@ -829,6 +833,8 @@ > > userrevs = list(repo.revs(opts.get('auto_orphans'))) > opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] > opts['dest'] = '_destautoorphanrebase(SRC)' > > +backup = ui.configbool('ui', 'history-editing-backup') > +opts['backup'] = backup This seems getting ugly. Maybe the option can be carried by rbsrt instead? self.backupf = ui.configbool('ui', 'history-editing-backup') REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3887 To: khanchi97, #hg-reviewers Cc: pulkit, yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D3968: amend: support "history-editing-backup" config option
> --- a/mercurial/cmdutil.py > +++ b/mercurial/cmdutil.py > @@ -2556,8 +2556,10 @@ > obsmetadata = None > if opts.get('note'): > obsmetadata = {'note': encoding.fromlocal(opts['note'])} > +backup = opts.get('backup') > scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata, > - fixphase=True, targetphase=commitphase) > + fixphase=True, targetphase=commitphase, > + backup=backup) > > # Fixing the dirstate because localrepo.commitctx does not update > # it. This is rather convenient because we did not need to update > diff --git a/hgext/amend.py b/hgext/amend.py > --- a/hgext/amend.py > +++ b/hgext/amend.py > @@ -54,4 +54,6 @@ > if not opts.get('logfile'): > opts['message'] = opts.get('message') or repo['.'].description() > opts['amend'] = True > +backup = ui.configbool('ui', 'history-editing-backup') > +opts['backup'] = backup > return commands._docommit(ui, repo, *pats, > **pycompat.strkwargs(opts)) No need to pass by opts since cmdutil.amend() can read ui.config. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3968: amend: support "history-editing-backup" config option
yuja added a comment. > - a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2556,8 +2556,10 @@ obsmetadata = None if opts.get('note'): obsmetadata = {'note': encoding.fromlocal(opts['note'])} +backup = opts.get('backup') scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata, > - fixphase=True, targetphase=commitphase) + fixphase=True, targetphase=commitphase, + backup=backup) > 1. Fixing the dirstate because localrepo.commitctx does not update > 2. it. This is rather convenient because we did not need to update diff --git a/hgext/amend.py b/hgext/amend.py > - a/hgext/amend.py +++ b/hgext/amend.py @@ -54,4 +54,6 @@ if not opts.get('logfile'): opts['message'] = opts.get('message') or repo['.'].description() opts['amend'] = True +backup = ui.configbool('ui', 'history-editing-backup') +opts['backup'] = backup return commands._docommit(ui, repo, *pats, **pycompat.strkwargs(opts)) No need to pass by opts since cmdutil.amend() can read ui.config. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3968 To: khanchi97, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 6] fileset: flatten 'or' nodes to unnest unionmatchers
# HG changeset patch # User Yuya Nishihara # Date 1532154236 -32400 # Sat Jul 21 15:23:56 2018 +0900 # Node ID 7b744a18768440cdca7662db7dc6179c1abd6613 # Parent 4391366a156f0a976460deccaa176217e50a3650 fileset: flatten 'or' nodes to unnest unionmatchers This also makes it easier to compile a union of basic patterns into a single regexp pattern. diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -103,7 +103,7 @@ def parse(expr): tree, pos = p.parse(tokenize(expr)) if pos != len(expr): raise error.ParseError(_("invalid token"), pos) -return parser.simplifyinfixops(tree, {'list'}) +return parser.simplifyinfixops(tree, {'list', 'or'}) def getsymbol(x): if x and x[0] == 'symbol': @@ -157,10 +157,9 @@ def andmatch(mctx, x, y): ym = getmatch(mctx, y) return matchmod.intersectmatchers(xm, ym) -def ormatch(mctx, x, y): -xm = getmatch(mctx, x) -ym = getmatch(mctx, y) -return matchmod.unionmatcher([xm, ym]) +def ormatch(mctx, *xs): +ms = [getmatch(mctx, x) for x in xs] +return matchmod.unionmatcher(ms) def notmatch(mctx, x): m = getmatch(mctx, x) diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py --- a/mercurial/minifileset.py +++ b/mercurial/minifileset.py @@ -40,9 +40,8 @@ def _compile(tree): raise error.ParseError(_("unsupported file pattern: %s") % name, hint=_('paths must be prefixed with "path:"')) elif op == 'or': -func1 = _compile(tree[1]) -func2 = _compile(tree[2]) -return lambda n, s: func1(n, s) or func2(n, s) +funcs = [_compile(x) for x in tree[1:]] +return lambda n, s: any(f(n, s) for f in funcs) elif op == 'and': func1 = _compile(tree[1]) func2 = _compile(tree[2]) diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -159,9 +159,8 @@ Show parsed tree at stages: $ fileset -p all -s 'a1 or a2 or (grep("b") & clean())' * parsed: (or -(or - (symbol 'a1') - (symbol 'a2')) +(symbol 'a1') +(symbol 'a2') (group (and (func @@ -172,9 +171,8 @@ Show parsed tree at stages: None * matcher: , - ]>, +, +, , m2=>]> ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 6] fileset: extract language processing part to new module (API)
# HG changeset patch # User Yuya Nishihara # Date 1532242245 -32400 # Sun Jul 22 15:50:45 2018 +0900 # Node ID e6e56b590c20c3a026a304f569e4e1edfd3b1b6a # Parent 7b744a18768440cdca7662db7dc6179c1abd6613 fileset: extract language processing part to new module (API) I'll add a couple more functions that work on parsed tree. % wc -l mercurial/fileset*.py 559 mercurial/fileset.py 135 mercurial/filesetlang.py 694 total diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py --- a/hgext/lfs/__init__.py +++ b/hgext/lfs/__init__.py @@ -136,7 +136,7 @@ from mercurial import ( exchange, extensions, filelog, -fileset, +filesetlang, hg, localrepo, minifileset, @@ -261,7 +261,7 @@ def _trackedmatcher(repo): # deprecated config: lfs.threshold threshold = repo.ui.configbytes('lfs', 'threshold') if threshold: -fileset.parse(trackspec) # make sure syntax errors are confined +filesetlang.parse(trackspec) # make sure syntax errors are confined trackspec = "(%s) | size('>%d')" % (trackspec, threshold) return minifileset.compile(trackspec) @@ -361,7 +361,7 @@ def extsetup(ui): def lfsfileset(mctx, x): """File that uses LFS storage.""" # i18n: "lfs" is a keyword -fileset.getargs(x, 0, 0, _("lfs takes no arguments")) +filesetlang.getargs(x, 0, 0, _("lfs takes no arguments")) ctx = mctx.ctx def lfsfilep(f): return wrapper.pointerfromctx(ctx, f, removed=True) is not None diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -48,7 +48,7 @@ from . import ( exchange, extensions, filemerge, -fileset, +filesetlang, formatter, hg, httppeer, @@ -916,13 +916,13 @@ def debugfileset(ui, repo, expr, **opts) raise error.Abort(_('invalid stage name: %s') % n) showalways.update(opts['show_stage']) -tree = fileset.parse(expr) +tree = filesetlang.parse(expr) for n, f in stages: tree = f(tree) if n in showalways: if opts['show_stage'] or n != 'parsed': ui.write(("* %s:\n") % n) -ui.write(fileset.prettyformat(tree), "\n") +ui.write(filesetlang.prettyformat(tree), "\n") files = set() if opts['all_files']: diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -13,9 +13,9 @@ import re from .i18n import _ from . import ( error, +filesetlang, match as matchmod, merge, -parser, pycompat, registrar, scmutil, @@ -25,120 +25,12 @@ from .utils import ( stringutil, ) -elements = { -# token-type: binding-strength, primary, prefix, infix, suffix -"(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None), -":": (15, None, None, ("kindpat", 15), None), -"-": (5, None, ("negate", 19), ("minus", 5), None), -"not": (10, None, ("not", 10), None, None), -"!": (10, None, ("not", 10), None, None), -"and": (5, None, None, ("and", 5), None), -"&": (5, None, None, ("and", 5), None), -"or": (4, None, None, ("or", 4), None), -"|": (4, None, None, ("or", 4), None), -"+": (4, None, None, ("or", 4), None), -",": (2, None, None, ("list", 2), None), -")": (0, None, None, None, None), -"symbol": (0, "symbol", None, None, None), -"string": (0, "string", None, None, None), -"end": (0, None, None, None, None), -} - -keywords = {'and', 'or', 'not'} - -globchars = ".*{}[]?/\\_" - -def tokenize(program): -pos, l = 0, len(program) -program = pycompat.bytestr(program) -while pos < l: -c = program[pos] -if c.isspace(): # skip inter-token whitespace -pass -elif c in "(),-:|&+!": # handle simple operators -yield (c, None, pos) -elif (c in '"\'' or c == 'r' and - program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings -if c == 'r': -pos += 1 -c = program[pos] -decode = lambda x: x -else: -decode = parser.unescapestr -pos += 1 -s = pos -while pos < l: # find closing quote -d = program[pos] -if d == '\\': # skip over escaped characters -pos += 2 -continue -if d == c: -yield ('string', decode(program[s:pos]), s) -break -pos += 1 -else: -raise error.ParseError(_("unterminated string"), s) -elif c.isalnum() or c in globchars or ord(c) > 127: -# gather up a symbol/keyword -s = pos -pos += 1 -while pos < l: # find end of symbol -d = program[pos] -if not
[PATCH 2 of 6] debugfileset: backport --show-stage option from debugrevspec
# HG changeset patch # User Yuya Nishihara # Date 1532152356 -32400 # Sat Jul 21 14:52:36 2018 +0900 # Node ID 75b419d263b70188d50c80f83704d9207654911a # Parent ad997e7f6cfc576b4178b962afba58de35c36fc1 debugfileset: backport --show-stage option from debugrevspec I'll add some static optimizations to fileset. diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -888,15 +888,39 @@ def debugextensions(ui, repo, **opts): @command('debugfileset', [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')), ('', 'all-files', False, - _('test files from all revisions and working directory'))], -_('[-r REV] [--all-files] FILESPEC')) + _('test files from all revisions and working directory')), + ('p', 'show-stage', [], + _('print parsed tree at the given stage'), _('NAME'))], +_('[-r REV] [--all-files] [OPTION]... FILESPEC')) def debugfileset(ui, repo, expr, **opts): '''parse and apply a fileset specification''' opts = pycompat.byteskwargs(opts) ctx = scmutil.revsingle(repo, opts.get('rev'), None) -if ui.verbose: -tree = fileset.parse(expr) -ui.note(fileset.prettyformat(tree), "\n") + +stages = [ +('parsed', pycompat.identity), +] +stagenames = set(n for n, f in stages) + +showalways = set() +if ui.verbose and not opts['show_stage']: +# show parsed tree by --verbose (deprecated) +showalways.add('parsed') +if opts['show_stage'] == ['all']: +showalways.update(stagenames) +else: +for n in opts['show_stage']: +if n not in stagenames: +raise error.Abort(_('invalid stage name: %s') % n) +showalways.update(opts['show_stage']) + +tree = fileset.parse(expr) +for n, f in stages: +tree = f(tree) +if n in showalways: +if opts['show_stage'] or n != 'parsed': +ui.write(("* %s:\n") % n) +ui.write(fileset.prettyformat(tree), "\n") files = set() if opts['all_files']: diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -274,7 +274,7 @@ Show all commands + options debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure debugdownload: output debugextensions: template - debugfileset: rev, all-files + debugfileset: rev, all-files, show-stage debugformat: template debugfsinfo: debuggetbundle: head, common, type diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -114,6 +114,44 @@ Test invalid syntax hg: parse error: invalid pattern kind: foo [255] +Show parsed tree at stages: + + $ fileset -p unknown a + abort: invalid stage name: unknown + [255] + + $ fileset -p parsed 'path:a1 or glob:b?' + * parsed: + (or +(kindpat + (symbol 'path') + (symbol 'a1')) +(kindpat + (symbol 'glob') + (symbol 'b?'))) + a1 + b1 + b2 + + $ fileset -p all 'a1 or a2 or (grep("b") & clean())' + * parsed: + (or +(or + (symbol 'a1') + (symbol 'a2')) +(group + (and +(func + (symbol 'grep') + (string 'b')) +(func + (symbol 'clean') + None + a1 + a2 + b1 + b2 + Test files status $ rm a1 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 6] lfs: remove callstatus property from 'lfs()' fileset
# HG changeset patch # User Yuya Nishihara # Date 1532243028 -32400 # Sun Jul 22 16:03:48 2018 +0900 # Node ID ad997e7f6cfc576b4178b962afba58de35c36fc1 # Parent 13dcf5d3761d69386e6b4086b5155f4f95533536 lfs: remove callstatus property from 'lfs()' fileset It was added at 91aac8e6604d, but is no longer needed since a fileset expression is now compiled into an "open" matcher. See ff5b6fca1082 for details. diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py --- a/hgext/lfs/__init__.py +++ b/hgext/lfs/__init__.py @@ -357,7 +357,7 @@ def extsetup(ui): # when writing a bundle via "hg bundle" command, upload related LFS blobs wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle) -@filesetpredicate('lfs()', callstatus=True) +@filesetpredicate('lfs()') def lfsfileset(mctx, x): """File that uses LFS storage.""" # i18n: "lfs" is a keyword ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 6] debugfileset: add option to show matcher representation
# HG changeset patch # User Yuya Nishihara # Date 1532153140 -32400 # Sat Jul 21 15:05:40 2018 +0900 # Node ID 75b53fecd632963175bc86d20fd8458774583211 # Parent 75b419d263b70188d50c80f83704d9207654911a debugfileset: add option to show matcher representation diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -889,6 +889,8 @@ def debugextensions(ui, repo, **opts): [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')), ('', 'all-files', False, _('test files from all revisions and working directory')), + ('s', 'show-matcher', None, + _('print internal representation of matcher')), ('p', 'show-stage', [], _('print parsed tree at the given stage'), _('NAME'))], _('[-r REV] [--all-files] [OPTION]... FILESPEC')) @@ -939,6 +941,8 @@ def debugfileset(ui, repo, expr, **opts) files.update(ctx.substate) m = ctx.matchfileset(expr) +if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose): +ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n') for f in sorted(files): if not m(f): continue diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -274,7 +274,7 @@ Show all commands + options debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure debugdownload: output debugextensions: template - debugfileset: rev, all-files, show-stage + debugfileset: rev, all-files, show-matcher, show-stage debugformat: template debugfsinfo: debuggetbundle: head, common, type diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -18,13 +18,19 @@ Test operators and basic patterns $ fileset -v a1 (symbol 'a1') + * matcher: + a1 $ fileset -v 'a*' (symbol 'a*') + * matcher: + a1 a2 $ fileset -v '"re:a\d"' (string 're:a\\d') + * matcher: + a1 a2 $ fileset -v '!re:"a\d"' @@ -32,6 +38,10 @@ Test operators and basic patterns (kindpat (symbol 're') (string 'a\\d'))) + * matcher: + >> b1 b2 $ fileset -v 'path:a1 or glob:b?' @@ -42,10 +52,14 @@ Test operators and basic patterns (kindpat (symbol 'glob') (symbol 'b?'))) + * matcher: + , +]> a1 b1 b2 - $ fileset -v 'a1 or a2' + $ fileset -v --no-show-matcher 'a1 or a2' (or (symbol 'a1') (symbol 'a2')) @@ -133,7 +147,7 @@ Show parsed tree at stages: b1 b2 - $ fileset -p all 'a1 or a2 or (grep("b") & clean())' + $ fileset -p all -s 'a1 or a2 or (grep("b") & clean())' * parsed: (or (or @@ -147,6 +161,14 @@ Show parsed tree at stages: (func (symbol 'clean') None + * matcher: + , + ]>, +, + m2=>]> a1 a2 b1 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 6] fileset: flatten arguments list
# HG changeset patch # User Yuya Nishihara # Date 1532153678 -32400 # Sat Jul 21 15:14:38 2018 +0900 # Node ID 4391366a156f0a976460deccaa176217e50a3650 # Parent 75b53fecd632963175bc86d20fd8458774583211 fileset: flatten arguments list Just prepares for flattening 'or' nodes. This change would have no impact on performance. diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -103,7 +103,7 @@ def parse(expr): tree, pos = p.parse(tokenize(expr)) if pos != len(expr): raise error.ParseError(_("invalid token"), pos) -return tree +return parser.simplifyinfixops(tree, {'list'}) def getsymbol(x): if x and x[0] == 'symbol': @@ -131,7 +131,7 @@ def getlist(x): if not x: return [] if x[0] == 'list': -return getlist(x[1]) + [x[2]] +return list(x[1:]) return [x] def getargs(x, min, max, err): @@ -174,7 +174,7 @@ def minusmatch(mctx, x, y): def negatematch(mctx, x): raise error.ParseError(_("can't use negate operator in this context")) -def listmatch(mctx, x, y): +def listmatch(mctx, *xs): raise error.ParseError(_("can't use a list in this context"), hint=_('see hg help "filesets.x or y"')) diff --git a/tests/test-fileset.t b/tests/test-fileset.t --- a/tests/test-fileset.t +++ b/tests/test-fileset.t @@ -111,6 +111,15 @@ Test invalid syntax None)) hg: parse error: can't use negate operator in this context [255] + $ fileset -p parsed 'a, b, c' + * parsed: + (list +(symbol 'a') +(symbol 'b') +(symbol 'c')) + hg: parse error: can't use a list in this context + (see hg help "filesets.x or y") + [255] $ fileset '"path":.' hg: parse error: not a symbol ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38779: new changeset (1 on stable)
New changeset (1 on stable) in mercurial: https://www.mercurial-scm.org/repo/hg/rev/824636b08400 changeset: 38779:824636b08400 branch: stable tag: tip parent: 38765:cc8657f6fd3e user:Gregory Szorc date:Wed Aug 01 12:24:52 2018 -0700 summary: packaging: always execute builddeb from source root -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4003: index: write expression for encoded revision index consistently
yuja added a comment. > - n->children[k] = -rev - 1; + n->children[k] = -(rev + 1); This is technically less correct since (MAX_INT + 1) overflows, but maybe we don't care? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4003 To: martinvonz, #hg-reviewers, pulkit Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4034: py3: stop rewriting xrange() to pycompat.xrange()
yuja added a comment. Need to bump BYTECODEHEADER. Fixed in flight. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4034 To: indygreg, #hg-reviewers, durin42 Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4003: index: write expression for encoded revision index consistently
> - n->children[k] = -rev - 1; > + n->children[k] = -(rev + 1); This is technically less correct since (MAX_INT + 1) overflows, but maybe we don't care? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4034: py3: stop rewriting xrange() to pycompat.xrange()
Need to bump BYTECODEHEADER. Fixed in flight. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38778: 11 new changesets
11 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/afc4ad706f9c changeset: 38768:afc4ad706f9c user:Rodrigo Damazio Bovendorp date:Thu Jul 19 23:22:05 2018 -0700 summary: dispatch: making all hg abortions be output with a specific label https://www.mercurial-scm.org/repo/hg/rev/e252f136b948 changeset: 38769:e252f136b948 user:Martin von Zweigbergk date:Fri Jul 27 14:49:45 2018 -0700 summary: amend: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/260c17eaf3f7 changeset: 38770:260c17eaf3f7 user:Martin von Zweigbergk date:Fri Jul 27 14:46:59 2018 -0700 summary: fix: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/3bd22c4d3711 changeset: 38771:3bd22c4d3711 user:Martin von Zweigbergk date:Fri Jul 27 14:47:38 2018 -0700 summary: uncommit: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/af5c0c933af8 changeset: 38772:af5c0c933af8 user:Martin von Zweigbergk date:Fri Jul 27 14:48:06 2018 -0700 summary: fileset: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/59af0c7d103f changeset: 38773:59af0c7d103f user:Martin von Zweigbergk date:Fri Jul 27 14:48:34 2018 -0700 summary: patch: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/87a581d1391c changeset: 38774:87a581d1391c user:Martin von Zweigbergk date:Fri Jul 27 14:48:58 2018 -0700 summary: templatekw: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2) https://www.mercurial-scm.org/repo/hg/rev/e971d6eb4770 changeset: 38775:e971d6eb4770 user:Martin von Zweigbergk date:Mon Jul 30 14:37:36 2018 -0700 summary: context: delete an obsolete comment https://www.mercurial-scm.org/repo/hg/rev/65ed2fcb9032 changeset: 38776:65ed2fcb9032 user:Augie Fackler date:Mon Jul 16 14:15:29 2018 -0400 summary: patchbomb: ensure all headers and values given to email mod are native strings https://www.mercurial-scm.org/repo/hg/rev/83a505b5cf85 changeset: 38777:83a505b5cf85 user:Martin von Zweigbergk date:Fri Jul 20 11:17:33 2018 -0700 summary: revlog: don't include trailing nullrev in revlog.revs(stop=len(revlog)) https://www.mercurial-scm.org/repo/hg/rev/a4d847cea6f8 changeset: 38778:a4d847cea6f8 bookmark:@ tag: tip user:Martin von Zweigbergk date:Fri Jul 20 11:37:31 2018 -0700 summary: perfmoonwalk: make work with filtered repo -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 v2] extensions: add detailed loading information
On Wed, 01 Aug 2018 17:29:40 +0200, Martijn Pieters wrote: > # HG changeset patch > # User Martijn Pieters > # Date 1533132413 -7200 > # Wed Aug 01 16:06:53 2018 +0200 > # Branch stable > # Node ID 07ca3b8354d59c70db5f10448e53d4bbfd50e72e > # Parent 2bad2ee57e26f05f99a81715e781f7978515b705 > # EXP-Topic debugextensions > extensions: add detailed loading information > +if ui.configbool('devel', 'debug.extensions'): > +log = lambda msg, *values: ui.debug('debug.extensions: ', > +msg % values, label='debug.extensions') > +else: > +log = lambda *a, **kw: None Seems like we're reinventing ui.log(). Can't this be a blackbox feature? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 v2] utils: create a context manager to handle timing
On Wed, 01 Aug 2018 17:29:39 +0200, Martijn Pieters wrote: > # HG changeset patch > # User Martijn Pieters > # Date 1533132341 -7200 > # Wed Aug 01 16:05:41 2018 +0200 > # Branch stable > # Node ID 2bad2ee57e26f05f99a81715e781f7978515b705 > # Parent 545a3e6650cd8f7e19c0f0256082837a33bea029 > # EXP-Topic debugextensions > utils: create a context manager to handle timing Queued, thanks. > +from .utils import ( > +procutil, > +stringutil, > +) > from . import ( > encoding, > error, > @@ -45,10 +52,6 @@ > pycompat, > urllibcompat, > ) > -from .utils import ( > -procutil, > -stringutil, > -) Dropped this change since ".utils" are generally imported after ".". > -_timenesting = [0] > +@attr.s > +class timedcmstats(object): > +"""Stats information produced by the timedcm context manager on > entering.""" > + > +# the starting value of the timer as a float (meaning and resulution is > +# platform dependent, see util.timer) > +start = attr.ib(default=attr.Factory(lambda: timer())) > +# the number of seconds as a floating point value; starts at 0, updated > when > +# the context is exited. > +elapsed = attr.ib(default=0) > +# the number of nested timedcm context managers. > +level = attr.ib(default=1) > + > +def __str__(self): > +return timecount(self.elapsed) if self.elapsed else '' Needs s/__str__/__bytes__/ and __str__ = encoding.strmethod(__bytes__) for py3. Can you send a follow up? > +@contextlib.contextmanager > +def timedcm(): > +"""A context manager that produces timing information for a given > context. > + > +On entering a timedcmstats instance is produced. > + > +This context manager is reentrant. > + > +""" > +# track nested context managers > +timedcm._nested += 1 > +timing_stats = timedcmstats(level=timedcm._nested) > +try: > +yield timing_stats > +finally: > +timing_stats.elapsed = timer() - timing_stats.start > +timedcm._nested -= 1 > + > +timedcm._nested = 0 This isn't thread safe, but is no worse than the original code. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4049: testrunner: allow multiple #testcases
lothiraldan added inline comments. INLINE COMMENTS > test-run-tests.t:912 > + # Ran 4 tests, 0 skipped, 0 failed. > + >$ rm test-cases.t Could you add a combination that failed so we test the test name of combination cases? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4049 To: martinvonz, #hg-reviewers, mharbison72 Cc: lothiraldan, mharbison72, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3988: resolve: add confirm config option
khanchi97 updated this revision to Diff 9785. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3988?vs=9678=9785 REVISION DETAIL https://phab.mercurial-scm.org/D3988 AFFECTED FILES mercurial/commands.py mercurial/configitems.py mercurial/help/config.txt tests/test-resolve.t CHANGE DETAILS diff --git a/tests/test-resolve.t b/tests/test-resolve.t --- a/tests/test-resolve.t +++ b/tests/test-resolve.t @@ -374,3 +374,90 @@ $ hg resolve -l $ cd .. + +== +Test 'hg resolve' confirm config option functionality | +== + $ cat >> $HGRCPATH << EOF + > [extensions] + > rebase= + > EOF + + $ hg init repo2 + $ cd repo2 + + $ echo boss > boss + $ hg ci -Am "add boss" + adding boss + + $ for emp in emp1 emp2 emp3; do echo work > $emp; done; + $ hg ci -Aqm "added emp1 emp2 emp3" + + $ hg up 0 + 0 files updated, 0 files merged, 3 files removed, 0 files unresolved + + $ for emp in emp1 emp2 emp3; do echo nowork > $emp; done; + $ hg ci -Aqm "added lazy emp1 emp2 emp3" + + $ hg log -GT "{rev} {node|short} {firstline(desc)}\n" + @ 2 0acfd4a49af0 added lazy emp1 emp2 emp3 + | + | o 1 f30f98a8181f added emp1 emp2 emp3 + |/ + o 0 88660038d466 add boss + + $ hg rebase -s 1 -d 2 + rebasing 1:f30f98a8181f "added emp1 emp2 emp3" + merging emp1 + merging emp2 + merging emp3 + warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark') + unresolved conflicts (see hg resolve, then hg rebase --continue) + [1] + +Test when commands.resolve.confirm config option is not set: +=== + $ hg resolve --all + merging emp1 + merging emp2 + merging emp3 + warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark') + [1] + +Test when config option is set: +== + $ cat >> $HGRCPATH << EOF + > [ui] + > interactive = True + > [commands] + > resolve.confirm = True + > EOF + + $ hg resolve + abort: no files or directories specified + (use --all to re-merge all unresolved files) + [255] + $ hg resolve --all << EOF + > n + > EOF + re-merge all unresolved files (yn)? n + + $ hg resolve --all << EOF + > y + > EOF + re-merge all unresolved files (yn)? y + merging emp1 + merging emp2 + merging emp3 + warning: conflicts while merging emp1! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp2! (edit, then use 'hg resolve --mark') + warning: conflicts while merging emp3! (edit, then use 'hg resolve --mark') + [1] + + $ hg rebase --abort + rebase aborted + $ cd .. diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -438,6 +438,11 @@ ``commands`` +``resolve.confirm`` +Confirm before re-merging all unresolved files when running +:hg:`resolve --all`. +(default: False) + ``status.relative`` Make paths in :hg:`status` output relative to the current directory. (default: False) diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -190,6 +190,9 @@ coreconfigitem('commands', 'grep.all-files', default=False, ) +coreconfigitem('commands', 'resolve.confirm', +default=False, +) coreconfigitem('commands', 'show.aliasprefix', default=list, ) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4528,10 +4528,16 @@ """ opts = pycompat.byteskwargs(opts) +confirm = ui.configbool('commands', 'resolve.confirm') flaglist = 'all mark unmark list no_status'.split() all, mark, unmark, show, nostatus = \ [opts.get(o) for o in flaglist] +if all and confirm: +if ui.promptchoice(_(b're-merge all unresolved files (yn)?' + b'$$ $$ ')): +return + if (show and (mark or unmark)) or (mark and unmark): raise error.Abort(_("too many options specified")) if pats and all: To: khanchi97, #hg-reviewers, pulkit Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3990: linelog: add a Python implementation of the linelog datastructure
martinvonz added a comment. I'm still just trying to understand how weaves work. Here are some questions for you for now. We may want to document some of the answers in a follow-up patch (not just here in Phabricator). INLINE COMMENTS > linelog.txt:110 > + > + The following cases are considered malformed in our implementation: > + Does that mean that we don't produce these cases? Or we fail if they happen and we fall back to old annotate? > linelog.txt:115-118 > + ^AI/D x ^AI/D x > + ^AI/D y -> ^AI/D y > + ^AE x ^AE y > + ^AE y ^AE x Could we add content to these examples to make them clearer? I don't follow how the rewrite works without seeing the content in there. I can imagine a rewrite that looks something like the following, but that's not what the example says, so I'm probably missing something. ^AI/D x ^AI/D x foo foo ^AE x ^AD/I y -> ^AI/D x ^AD/I y bar bar ^AE x ^AE y ^AE x ^AD/I y baz baz ^AE y ^AE y > linelog.txt:123-126 > + ^AI x + 1 ^AI x + 1 > + ^AI x -> ^AE x + 1 > + ^AE x ^AI x > + ^AE x + 1 ^AE x Same here, adding content might help. I imagine it means something like this (just the LHS): ^AI x + 1 foo ^AI x bar ^AE x baz ^AE x + 1 But what does that even mean? That bar got added in revision x and then it got added again in revision x+1? I suppose it means it won't be added the second time, but I agree that it makes sense to consider that malformed. > linelog.txt:128 > + > +3. Insertion or deletion inside another deletion, where the outer > deletion > + block has a smaller revision number. Why is insertion inside an earlier deletion considered invalid? That seems like what would happen when you revive a line (as you also say below). How do we model that instead? > linelog.txt:128 > + > +3. Insertion or deletion inside another deletion, where the outer > deletion > + block has a smaller revision number. I agree that deletion inside deletion should be invalid, but why isn't that part of item 2 instead? It seems more similar to that case (i.e. nested deletion seems more like nested insertion to me). > linelog.txt:128 > + > +3. Insertion or deletion inside another deletion, where the outer > deletion > + block has a smaller revision number. How about nested deletion inside insertion? Why is that different? > linelog.txt:134 > + ^AE x + 1 ^AI/D x + 1 > + ^AE x ^AE x > + I assume this should read `^AE x + 1` on the RHS REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3990 To: durin42, #hg-reviewers, indygreg Cc: martinvonz, indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel