[PATCH 3 of 3] lfs: remove the verification option when writing to the local store
# HG changeset patch # User Matt Harbison# Date 1515305692 18000 # Sun Jan 07 01:14:52 2018 -0500 # Node ID b58ace49e2be02d475772dda828398fa15a518c9 # Parent 5da1b3ea5aef5e4541f00b5dd75a97d471d39dd5 lfs: remove the verification option when writing to the local store This partially reverts 417e8e040102 and bb6a80fc969a. But since there's now a dedicated download function, there's no functional change. The last sentence in the commit message of the latter is wrong- write() didn't need the one time hash check if verification wasn't requested. I suspect I missed 'read()' in there ("... but _read()_ also needs to do a one time check..."), because that did fail without the hash check before linking to the usercache. The write() method simply took the same check for consistency. While here, clarify that the write() method is *only* for storing content directly from filelog, which has already checked the hash. If someone can come up with a way to bridge the differences between writing to a file and sending a urlreq.request across the wire, we can create an upload() function and cleanup read() in a similar way. About the only common thread I see is an open() that verifies the content before returning a file descriptor. diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -134,20 +134,20 @@ self.ui.note(_('lfs: adding %s to the usercache\n') % oid) lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid)) -def write(self, oid, data, verify=True): -"""Write blob to local blobstore.""" -if verify: -_verify(oid, data) +def write(self, oid, data): +"""Write blob to local blobstore. +This should only be called from the filelog during a commit or similar. +As such, there is no need to verify the data. Imports from a remote +store must use ``download()`` instead.""" with self.vfs(oid, 'wb', atomictemp=True) as fp: fp.write(data) # XXX: should we verify the content of the cache, and hardlink back to # the local store on success, but truncate, write and link on failure? if not self.cachevfs.exists(oid): -if verify or hashlib.sha256(data).hexdigest() == oid: -self.ui.note(_('lfs: adding %s to the usercache\n') % oid) -lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid)) +self.ui.note(_('lfs: adding %s to the usercache\n') % oid) +lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid)) def read(self, oid, verify=True): """Read blob from local blobstore.""" diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py --- a/hgext/lfs/wrapper.py +++ b/hgext/lfs/wrapper.py @@ -86,7 +86,7 @@ # git-lfs only supports sha256 oid = hashlib.sha256(text).hexdigest() -self.opener.lfslocalblobstore.write(oid, text, verify=False) +self.opener.lfslocalblobstore.write(oid, text) # replace contents with metadata longoid = 'sha256:%s' % oid ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 3] lfs: introduce a localstore method for downloading from remote stores
# HG changeset patch # User Matt Harbison# Date 1513900564 18000 # Thu Dec 21 18:56:04 2017 -0500 # Node ID 32b06a5033f350fe73eaac8d27fd153df302257d # Parent 58fda95a0202fc6327d1f5d9df26f7ff16538d57 lfs: introduce a localstore method for downloading from remote stores The current local.write() method requires the full data, which means concatenating file chunks in memory when downloading from a git server. The dedicated method downloads in chunks, verifies the content on the fly, and creates the usercache hardlink if successful. It can also be used for the file system based remotestore. An explicit division of labor between downloading from a remote store (which should be verified) and writing to the store because of a commit or similar (which doesn't need verification), seems clearer. I can't figure out how to make a similar function for upload, because for a file remote store, it's a simple open/read/write operation. For a gitremote store, it's open the file and a urlreq.request(), and process that. diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -114,6 +114,26 @@ return self.vfs(oid, 'rb') +def download(self, oid, src): +"""Read the blob from the remote source in chunks, verify the content, +and write to this local blobstore.""" +sha256 = hashlib.sha256() + +with self.vfs(oid, 'wb', atomictemp=True) as fp: +for chunk in util.filechunkiter(src, size=1048576): +fp.write(chunk) +sha256.update(chunk) + +realoid = sha256.hexdigest() +if realoid != oid: +raise error.Abort(_('corrupt remote lfs object: %s') % oid) + +# XXX: should we verify the content of the cache, and hardlink back to +# the local store on success, but truncate, write and link on failure? +if not self.cachevfs.exists(oid): +self.ui.note(_('lfs: adding %s to the usercache\n') % oid) +lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid)) + def write(self, oid, data, verify=True): """Write blob to local blobstore.""" if verify: ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 2 STABLE] templatefilters: fix doc of basename()
# HG changeset patch # User Yuya Nishihara# Date 1515294449 -32400 # Sun Jan 07 12:07:29 2018 +0900 # Branch stable # Node ID cb1d423650e18fdd4346f951d3fe9f2f47e2a24a # Parent 614e385a5245a43232a10ee383d9894673b03b00 templatefilters: fix doc of basename() os.path.basename() does NOT strip trailing slashes. > Note that the result of this function is different from the Unix basename > program; where basename for '/foo/bar/' returns 'bar', the basename() > function returns an empty string (''). https://docs.python.org/2.7/library/os.path.html#os.path.basename diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -90,9 +90,8 @@ def age(date, abbrev=False): @templatefilter('basename') def basename(path): """Any text. Treats the text as a path, and returns the last -component of the path after splitting by the path separator -(ignoring trailing separators). For example, "foo/bar/baz" becomes -"baz" and "foo/bar//" becomes "bar". +component of the path after splitting by the path separator. +For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "". """ return os.path.basename(path) diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -2218,6 +2218,11 @@ Age filter: $ cd .. $ rm -rf unstable-hash +Filename filters: + + $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n' + bar||foo| + Add a dummy commit to make up for the instability of the above: $ echo a > a ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2 STABLE] identify: document -r. explicitly how to disable wdir scanning (issue5622)
# HG changeset patch # User Yuya Nishihara# Date 1515308218 -32400 # Sun Jan 07 15:56:58 2018 +0900 # Branch stable # Node ID 614e385a5245a43232a10ee383d9894673b03b00 # Parent 058c725925e33d70020f590dc44b94e945205c61 identify: document -r. explicitly how to disable wdir scanning (issue5622) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2690,7 +2690,8 @@ def identify(ui, repo, source=None, rev= a list of tags, and a list of bookmarks. When REV is not given, print a summary of the current state of the -repository. +repository including the working directory. Specify -r. to get information +of the working directory parent without scanning uncommitted changes. Specifying a path to a repository root or Mercurial bundle will cause lookup to operate on that repository/bundle. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] largefiles: modernize how capabilities are added to the wire protocol
On Sun, 07 Jan 2018 01:28:22 -0500, Yuya Nishiharawrote: On Sat, 06 Jan 2018 19:42:35 -0500, Matt Harbison wrote: On Sat, 06 Jan 2018 15:56:43 -0500, Matt Harbison wrote: >> On Jan 6, 2018, at 3:09 PM, Augie Fackler wrote: >>> On Jan 5, 2018, at 1:19 AM, Yuya Nishihara wrote: >>> On Tue, 02 Jan 2018 23:55:08 -0500, Matt Harbison wrote: > On Thu, 28 Dec 2017 08:04:01 -0500, Yuya Nishihara > wrote: >> On Wed, 27 Dec 2017 03:27:58 -0500, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1514349649 18000 >> # Tue Dec 26 23:40:49 2017 -0500 >> # Node ID f2e5631c99e6e2c7e9bac058185c24dd73a04e98 >> # Parent 25ecea2ec3d7844c9146bf878fc5093ab33b6e11 >> largefiles: modernize how capabilities are added to the wire >> protocol > > Looks good to me, so queued, thanks. Any thoughts on how the client can let the server know it has the extension loaded, so I can close off the last hole in this series? >>> >>> CC +indygreg, augie >>> >>> I think there were some discussion about advertising client's >>> capability, >>> but I don't remember. >> >> OOC, why do we want the client to be advertising that it groks >> largefiles to the server? I have a guess, but I’d like that explained >> before I start trying to figure out what we need to support... > > I’m not in front of a computer right now, but see this. I think it is > related to choking on the external flag that it doesn’t understand > without the extension. > > https://www.mercurial-scm.org/repo/hg-all/file/fa865878a849/tests/test-lfs-serve.t#l189 To put a little meat on this: 1) A requirement should always be added when a commit adding lfs files appears in a repo. Otherwise cryptic errors occur. Pulling from a remote server is the last hole I'm aware of. 2) The error referenced above is because client and server can't agree on a common changegroup. LFS forces only changegroup3. See the error log at the bottom of the test. (Aside: you previously mentioned aiming to take the experimental shrink wrap off LFS after the next cycle. But IDK if we want a non-experimental thing depending on something experimental, and IDK how far from being finalize changegroup3 is.) Isn't that a server issue which should fail gracefully if no common changegroup version found? Maybe. The wire protocol stuff is pretty opaque to me. When two sides can't talk to each other, IDK how one tells the other that though. I wasn't too worried about this, because presumably we would enable it by default soon-ish. 3) If changegroup3 is manually enabled, then the server error no longer happens on that clone, but rather the client blows up: $ hg clone -q http://localhost:$HGPORT $TESTTMP/client4_clone --config experimental.changegroup3=True transaction abort! rollback completed abort: missing processor for flag '0x2000'! [255] The error message can be made less cryptic as the core knows 0x2000 means REVIDX_EXTSTORED. I'd be fine with mentioning 'enable lfs' from here if we can sort out the changegroup3 issue. Are there any cache issues to worry about with the rollback? (I keep seeing that strip isn't cache friendly, so I assume rollback isn't either, unless they are part of the transaction. Presumably knowing capabilities up front would fail fast.) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 5] revsetlang: unnest "if True" in formatrevspec()
# HG changeset patch # User Yuya Nishihara# Date 1491033407 -32400 # Sat Apr 01 16:56:47 2017 +0900 # Node ID 11003d3f4751eb00f04c43bbeed25fe044a3db87 # Parent cac1c609a310d403b4d1acefac35aa86d871b608 revsetlang: unnest "if True" in formatrevspec() diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -630,22 +630,20 @@ def formatspec(expr, *args): break ret.append(expr[pos:q]) pos = q + 1 -if True: +d = expr[pos] +if d == '%': +ret.append(d) +elif d in 'dsnbr': +ret.append(argtype(d, args[arg])) +arg += 1 +elif d == 'l': +# a list of some type +pos += 1 d = expr[pos] -if d == '%': -ret.append(d) -elif d in 'dsnbr': -ret.append(argtype(d, args[arg])) -arg += 1 -elif d == 'l': -# a list of some type -pos += 1 -d = expr[pos] -ret.append(listexp(list(args[arg]), d)) -arg += 1 -else: -raise error.Abort(_('unexpected revspec format character %s') - % d) +ret.append(listexp(list(args[arg]), d)) +arg += 1 +else: +raise error.Abort(_('unexpected revspec format character %s') % d) pos += 1 return ''.join(ret) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 5] revsetlang: use iterator to track current argument in formatspec()
# HG changeset patch # User Yuya Nishihara# Date 1491033889 -32400 # Sat Apr 01 17:04:49 2017 +0900 # Node ID 235156e876401ee955e2db5b4cc1bae17f39e3f5 # Parent 11003d3f4751eb00f04c43bbeed25fe044a3db87 revsetlang: use iterator to track current argument in formatspec() diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -620,9 +620,9 @@ def formatspec(expr, *args): return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) expr = pycompat.bytestr(expr) +argiter = iter(args) ret = [] pos = 0 -arg = 0 while pos < len(expr): q = expr.find('%', pos) if q < 0: @@ -634,14 +634,12 @@ def formatspec(expr, *args): if d == '%': ret.append(d) elif d in 'dsnbr': -ret.append(argtype(d, args[arg])) -arg += 1 +ret.append(argtype(d, next(argiter))) elif d == 'l': # a list of some type pos += 1 d = expr[pos] -ret.append(listexp(list(args[arg]), d)) -arg += 1 +ret.append(listexp(list(next(argiter)), d)) else: raise error.Abort(_('unexpected revspec format character %s') % d) pos += 1 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 5] revsetlang: use str.find() to scan expr in formatspec()
# HG changeset patch # User Yuya Nishihara# Date 1491033328 -32400 # Sat Apr 01 16:55:28 2017 +0900 # Node ID cac1c609a310d403b4d1acefac35aa86d871b608 # Parent 48cdc456784aa0e7a39f89f63f1d5142b20637d7 revsetlang: use str.find() to scan expr in formatspec() There should be no need to walk character one by one in Python. diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -624,9 +624,13 @@ def formatspec(expr, *args): pos = 0 arg = 0 while pos < len(expr): -c = expr[pos] -if c == '%': -pos += 1 +q = expr.find('%', pos) +if q < 0: +ret.append(expr[pos:]) +break +ret.append(expr[pos:q]) +pos = q + 1 +if True: d = expr[pos] if d == '%': ret.append(d) @@ -642,8 +646,6 @@ def formatspec(expr, *args): else: raise error.Abort(_('unexpected revspec format character %s') % d) -else: -ret.append(c) pos += 1 return ''.join(ret) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 5] revsetlang: raise ParseError to report invalid format character
# HG changeset patch # User Yuya Nishihara# Date 1491034368 -32400 # Sat Apr 01 17:12:48 2017 +0900 # Node ID 0955ec2eadf2cc4bb3ab63263551a4bd8b5d810e # Parent 235156e876401ee955e2db5b4cc1bae17f39e3f5 revsetlang: raise ParseError to report invalid format character It's more common in revset and templater than raising Abort. I have a couple more patches to address exceptions caused by bad format string passed to revset() template function. diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -641,7 +641,8 @@ def formatspec(expr, *args): d = expr[pos] ret.append(listexp(list(next(argiter)), d)) else: -raise error.Abort(_('unexpected revspec format character %s') % d) +raise error.ParseError(_('unexpected revspec format character %s') + % d) pos += 1 return ''.join(ret) diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -4080,6 +4080,12 @@ default. join() should agree with the de 5:13207e5a10d9fd28ec424934298e176197f2c67f, 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74 +Invalid arguments passed to revset() + + $ hg log -T '{revset("%whatever", 0)}\n' + hg: parse error: unexpected revspec format character w + [255] + Test files function $ hg log -T "{rev}\n{join(files('*'), '\n')}\n" ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 3] test-glog: hook cmdutil.getlogrevs() so -frREV is rewritten accordingly
# HG changeset patch # User Yuya Nishihara# Date 1515036655 -32400 # Thu Jan 04 12:30:55 2018 +0900 # Node ID 9aa28a9a49871922fd48f1ff6811573a191d47f9 # Parent fb998a6d3e5af902012c680aa7b0cd5e1e718be7 test-glog: hook cmdutil.getlogrevs() so -frREV is rewritten accordingly Before, these tests didn't match the real behavior of "log -frREV". diff --git a/tests/test-glog.t b/tests/test-glog.t --- a/tests/test-glog.t +++ b/tests/test-glog.t @@ -98,21 +98,23 @@ o (0) root > return cmdutil._makelogrevset(repo, pats, opts, revs)[0] > > def uisetup(ui): - > def printrevset(orig, ui, repo, *pats, **opts): + > def printrevset(orig, repo, pats, opts): + > revs, filematcher = orig(repo, pats, opts) > if opts.get('print_revset'): - > revs = cmdutil.getlogrevs(repo, pats, opts)[0] > expr = logrevset(repo, pats, opts) > if expr: > tree = revsetlang.parse(expr) > tree = revsetlang.analyze(tree) > else: > tree = [] + > ui = repo.ui > ui.write('%r\n' % (opts.get('rev', []),)) > ui.write(revsetlang.prettyformat(tree) + '\n') > ui.write(smartset.prettyformat(revs) + '\n') - > return 0 - > return orig(ui, repo, *pats, **opts) - > entry = extensions.wrapcommand(commands.table, 'log', printrevset) + > revs = smartset.baseset() # display no revisions + > return revs, filematcher + > extensions.wrapfunction(cmdutil, 'getlogrevs', printrevset) + > aliases, entry = cmdutil.findcmd('log', commands.table) > entry[1].append(('', 'print-revset', False, > 'print generated revset and exit (DEPRECATED)')) > EOF @@ -2304,15 +2306,9 @@ changessincelatesttag with no prior tag -f +g $ testlog --follow -r6 -r8 -r5 -r7 -r4 - ['6', '8', '5', '7', '4'] - (func -(symbol 'descendants') -(func - (symbol 'rev') - (symbol '6'))) - , - > + ['reverse(::(((6) or (8)) or ((5) or ((7) or (4)'] + [] + Test --follow-first and forward --rev @@ -2337,15 +2333,9 @@ Test --follow-first and forward --rev Test --follow and backward --rev $ testlog --follow -r6 -r5 -r7 -r8 -r4 - ['6', '5', '7', '8', '4'] - (func -(symbol 'ancestors') -(func - (symbol 'rev') - (symbol '6'))) - , - > + ['reverse(::(((6) or (5)) or ((7) or ((8) or (4)'] + [] + Test --follow-first and backward --rev ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 3] test-glog: dump computed set
# HG changeset patch # User Yuya Nishihara# Date 1514967150 -32400 # Wed Jan 03 17:12:30 2018 +0900 # Node ID fb998a6d3e5af902012c680aa7b0cd5e1e718be7 # Parent 0b7b23144035c5b8394de3384ee06688b597e2ff test-glog: dump computed set It's more important than the revset expression built from command options. diff --git a/tests/test-glog.t b/tests/test-glog.t --- a/tests/test-glog.t +++ b/tests/test-glog.t @@ -88,6 +88,7 @@ o (0) root > commands, > extensions, > revsetlang, + > smartset, > ) > > def logrevset(repo, pats, opts): @@ -99,6 +100,7 @@ o (0) root > def uisetup(ui): > def printrevset(orig, ui, repo, *pats, **opts): > if opts.get('print_revset'): + > revs = cmdutil.getlogrevs(repo, pats, opts)[0] > expr = logrevset(repo, pats, opts) > if expr: > tree = revsetlang.parse(expr) @@ -107,6 +109,7 @@ o (0) root > tree = [] > ui.write('%r\n' % (opts.get('rev', []),)) > ui.write(revsetlang.prettyformat(tree) + '\n') + > ui.write(smartset.prettyformat(revs) + '\n') > return 0 > return orig(ui, repo, *pats, **opts) > entry = extensions.wrapcommand(commands.table, 'log', printrevset) @@ -1452,6 +1455,7 @@ glog always reorders nodes which explain $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31 ['27', '25', '21', '34', '32', '31'] [] + --- log.nodes* (glob) +++ glog.nodes * (glob) @@ -1,6 +1,6 @@ @@ -1474,6 +1478,15 @@ glog always reorders nodes which explain (func (symbol 'user') (string 'not-a-user' + , +, +>, + , +>>> $ testlog -b not-a-branch abort: unknown revision 'not-a-branch'! abort: unknown revision 'not-a-branch'! @@ -1491,6 +1504,19 @@ glog always reorders nodes which explain (func (symbol 'branch') (string 'branch' + , +, +>, + , + >, +, + $ testlog -k expand -k merge [] (or @@ -1501,22 +1527,43 @@ glog always reorders nodes which explain (func (symbol 'keyword') (string 'merge' + , +, +>, + , +>>> $ testlog --only-merges [] (func (symbol 'merge') None) + , +> $ testlog --no-merges [] (not (func (symbol 'merge') None)) + , +, +>>> $ testlog --date '2 0 to 4 0' [] (func (symbol 'date') (string '2 0 to 4 0')) + , +> $ hg log -G -d 'brace ) in a date' hg: parse error: invalid date: 'brace ) in a date' [255] @@ -1537,6 +1584,21 @@ glog always reorders nodes which explain (func (symbol 'ancestors') (string '32')) + , + , + , + , +, +, + Dedicated repo for --follow and paths filtering. The g is crafted to have 2 filelog topological heads in a linear changeset graph. @@ -1547,9 +1609,11 @@ have 2 filelog topological heads in a li $ testlog --follow [] [] + $ testlog -rnull ['null'] [] + $ echo a > a $ echo aa > aa $ echo f > f @@ -1586,6 +1650,8 @@ have 2 filelog topological heads in a li (func (symbol 'filelog') (string 'a')) + , set([0])> $ testlog a b [] (or @@ -1596,6 +1662,11 @@ have 2 filelog topological heads in a li (func (symbol 'filelog') (string 'b' + , +, + >> Test falling back to slow path for non-existing files @@ -1608,6 +1679,9 @@ Test falling back to slow path for non-e (string 'd:relpath') (string 'p:a') (string 'p:c'))) + , +> Test multiple --include/--exclude/paths @@ -1624,6 +1698,9 @@ Test multiple --include/--exclude/paths (string 'i:e') (string 'x:b') (string 'x:e'))) + , +> Test glob expansion of pats @@ -1638,6 +1715,8 @@ Test glob expansion of pats (func (symbol 'filelog') (string 'aa')) + , set([0])> Test --follow on a non-existent directory @@ -1661,6 +1740,11 @@ Test --follow on a directory (string 'r:') (string 'd:relpath') (string 'p:dir' + , + >, +> $ hg up -q tip Test --follow on file not in parent revision @@ -1684,6 +1768,11 @@ Test --follow and patterns (string 'r:') (string 'd:relpath') (string 'p:glob:*' + , + >, +> Test --follow on a single rename @@ -1693,6 +1782,9 @@ Test --follow on a single rename (func (symbol 'follow') (string 'a')) + , + > Test --follow and multiple renames @@ -1702,6 +1794,9 @@ Test --follow and multiple renames (func (symbol 'follow') (string 'e')) + , + >
[PATCH 1 of 5] revsetlang: avoid string concatenation in formatspec()
# HG changeset patch # User Yuya Nishihara# Date 1491033011 -32400 # Sat Apr 01 16:50:11 2017 +0900 # Node ID 48cdc456784aa0e7a39f89f63f1d5142b20637d7 # Parent 9aa28a9a49871922fd48f1ff6811573a191d47f9 revsetlang: avoid string concatenation in formatspec() diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -620,7 +620,7 @@ def formatspec(expr, *args): return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) expr = pycompat.bytestr(expr) -ret = '' +ret = [] pos = 0 arg = 0 while pos < len(expr): @@ -629,24 +629,24 @@ def formatspec(expr, *args): pos += 1 d = expr[pos] if d == '%': -ret += d +ret.append(d) elif d in 'dsnbr': -ret += argtype(d, args[arg]) +ret.append(argtype(d, args[arg])) arg += 1 elif d == 'l': # a list of some type pos += 1 d = expr[pos] -ret += listexp(list(args[arg]), d) +ret.append(listexp(list(args[arg]), d)) arg += 1 else: raise error.Abort(_('unexpected revspec format character %s') % d) else: -ret += c +ret.append(c) pos += 1 -return ret +return ''.join(ret) def prettyformat(tree): return parser.prettyformat(tree, ('string', 'symbol')) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] largefiles: modernize how capabilities are added to the wire protocol
On Sat, 06 Jan 2018 19:42:35 -0500, Matt Harbison wrote: > On Sat, 06 Jan 2018 15:56:43 -0500, Matt Harbison> wrote: > >> On Jan 6, 2018, at 3:09 PM, Augie Fackler wrote: > >>> On Jan 5, 2018, at 1:19 AM, Yuya Nishihara wrote: > >>> On Tue, 02 Jan 2018 23:55:08 -0500, Matt Harbison wrote: > > On Thu, 28 Dec 2017 08:04:01 -0500, Yuya Nishihara > > wrote: > >> On Wed, 27 Dec 2017 03:27:58 -0500, Matt Harbison wrote: > >> # HG changeset patch > >> # User Matt Harbison > >> # Date 1514349649 18000 > >> # Tue Dec 26 23:40:49 2017 -0500 > >> # Node ID f2e5631c99e6e2c7e9bac058185c24dd73a04e98 > >> # Parent 25ecea2ec3d7844c9146bf878fc5093ab33b6e11 > >> largefiles: modernize how capabilities are added to the wire > >> protocol > > > > Looks good to me, so queued, thanks. > > Any thoughts on how the client can let the server know it has the > extension loaded, so I can close off the last hole in this series? > >>> > >>> CC +indygreg, augie > >>> > >>> I think there were some discussion about advertising client's > >>> capability, > >>> but I don't remember. > >> > >> OOC, why do we want the client to be advertising that it groks > >> largefiles to the server? I have a guess, but I’d like that explained > >> before I start trying to figure out what we need to support... > > > > I’m not in front of a computer right now, but see this. I think it is > > related to choking on the external flag that it doesn’t understand > > without the extension. > > > > https://www.mercurial-scm.org/repo/hg-all/file/fa865878a849/tests/test-lfs-serve.t#l189 > > To put a little meat on this: > > 1) A requirement should always be added when a commit adding lfs files > appears in a repo. Otherwise cryptic errors occur. Pulling from a remote > server is the last hole I'm aware of. > > 2) The error referenced above is because client and server can't agree on > a common changegroup. LFS forces only changegroup3. See the error log at > the bottom of the test. (Aside: you previously mentioned aiming to take > the experimental shrink wrap off LFS after the next cycle. But IDK if we > want a non-experimental thing depending on something experimental, and IDK > how far from being finalize changegroup3 is.) Isn't that a server issue which should fail gracefully if no common changegroup version found? > 3) If changegroup3 is manually enabled, then the server error no longer > happens on that clone, but rather the client blows up: > >$ hg clone -q http://localhost:$HGPORT $TESTTMP/client4_clone --config > experimental.changegroup3=True >transaction abort! >rollback completed >abort: missing processor for flag '0x2000'! >[255] The error message can be made less cryptic as the core knows 0x2000 means REVIDX_EXTSTORED. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] largefiles: modernize how capabilities are added to the wire protocol
On Sat, 06 Jan 2018 15:56:43 -0500, Matt Harbisonwrote: On Jan 6, 2018, at 3:09 PM, Augie Fackler wrote: On Jan 5, 2018, at 1:19 AM, Yuya Nishihara wrote: On Tue, 02 Jan 2018 23:55:08 -0500, Matt Harbison wrote: On Thu, 28 Dec 2017 08:04:01 -0500, Yuya Nishihara wrote: On Wed, 27 Dec 2017 03:27:58 -0500, Matt Harbison wrote: # HG changeset patch # User Matt Harbison # Date 1514349649 18000 # Tue Dec 26 23:40:49 2017 -0500 # Node ID f2e5631c99e6e2c7e9bac058185c24dd73a04e98 # Parent 25ecea2ec3d7844c9146bf878fc5093ab33b6e11 largefiles: modernize how capabilities are added to the wire protocol Looks good to me, so queued, thanks. Any thoughts on how the client can let the server know it has the extension loaded, so I can close off the last hole in this series? CC +indygreg, augie I think there were some discussion about advertising client's capability, but I don't remember. OOC, why do we want the client to be advertising that it groks largefiles to the server? I have a guess, but I’d like that explained before I start trying to figure out what we need to support... I’m not in front of a computer right now, but see this. I think it is related to choking on the external flag that it doesn’t understand without the extension. https://www.mercurial-scm.org/repo/hg-all/file/fa865878a849/tests/test-lfs-serve.t#l189 To put a little meat on this: 1) A requirement should always be added when a commit adding lfs files appears in a repo. Otherwise cryptic errors occur. Pulling from a remote server is the last hole I'm aware of. 2) The error referenced above is because client and server can't agree on a common changegroup. LFS forces only changegroup3. See the error log at the bottom of the test. (Aside: you previously mentioned aiming to take the experimental shrink wrap off LFS after the next cycle. But IDK if we want a non-experimental thing depending on something experimental, and IDK how far from being finalize changegroup3 is.) 3) If changegroup3 is manually enabled, then the server error no longer happens on that clone, but rather the client blows up: $ hg clone -q http://localhost:$HGPORT $TESTTMP/client4_clone --config experimental.changegroup3=True transaction abort! rollback completed abort: missing processor for flag '0x2000'! [255] The check in the other direction is in fa865878a849, along with some comments on how largefiles already does this. (Largefiles doesn't have these flags, so I think it is just to ensure the extension is loaded, so you don't see the standins.) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@35536: 17 new changesets
17 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/711149d8e676 changeset: 35520:711149d8e676 user:Kyle Lippincottdate:Thu Jan 04 16:29:03 2018 -0800 summary: tests: switch test from '--config ui.editor=~/foo' to HGEDITOR=~/foo https://www.mercurial-scm.org/repo/hg/rev/a0fab647a8f1 changeset: 35521:a0fab647a8f1 user:Gregory Szorc date:Mon Dec 25 16:31:14 2017 -0700 summary: revlog: don't use slicing to return parents https://www.mercurial-scm.org/repo/hg/rev/ab9d8d298510 changeset: 35522:ab9d8d298510 user:Anton Shestakov date:Wed Jan 03 09:41:01 2018 +0800 summary: hgweb: make .info a block element by default https://www.mercurial-scm.org/repo/hg/rev/45ed821b5ce4 changeset: 35523:45ed821b5ce4 user:Anton Shestakov date:Wed Jan 03 10:37:49 2018 +0800 summary: monoblue: adjust font size of graph entries https://www.mercurial-scm.org/repo/hg/rev/fcb1ecf2bef7 changeset: 35524:fcb1ecf2bef7 user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Jan 05 17:23:55 2018 +0530 summary: hgdemandimport: use correct hyperlink to python-bug in comments (issue5765) https://www.mercurial-scm.org/repo/hg/rev/83903433c2eb changeset: 35525:83903433c2eb user:Matt Harbison date:Tue Jan 02 21:18:30 2018 -0500 summary: lfs: add a local store method for opening a blob https://www.mercurial-scm.org/repo/hg/rev/e8f80529abeb changeset: 35526:e8f80529abeb user:Matt Harbison date:Tue Jan 02 21:46:57 2018 -0500 summary: lfs: use the local store method for opening a blob https://www.mercurial-scm.org/repo/hg/rev/f43dc62cfe11 changeset: 35527:f43dc62cfe11 user:Elmar Bartel date:Thu Jan 04 12:12:07 2018 +0100 summary: crecord: honor "ui.color = no" config option https://www.mercurial-scm.org/repo/hg/rev/fb2e59e92651 changeset: 35528:fb2e59e92651 user:Elmar Bartel date:Thu Jan 04 12:34:40 2018 +0100 summary: crecord: fallback to color = no when curses.use_default_colors() fails https://www.mercurial-scm.org/repo/hg/rev/5afe0ca59b07 changeset: 35529:5afe0ca59b07 user:Anton Shestakov date:Fri Jan 05 18:46:06 2018 +0800 summary: paper: make actual changeset entries have backgrounds on /graph https://www.mercurial-scm.org/repo/hg/rev/acd8a2454b47 changeset: 35530:acd8a2454b47 user:Anton Shestakov date:Fri Jan 05 19:08:00 2018 +0800 summary: monoblue: make actual changeset entries have backgrounds on /graph https://www.mercurial-scm.org/repo/hg/rev/6c2264732dc5 changeset: 35531:6c2264732dc5 user:Anton Shestakov date:Fri Jan 05 19:16:08 2018 +0800 summary: gitweb: make actual changeset entries have backgrounds on /graph https://www.mercurial-scm.org/repo/hg/rev/bb5a03dfd7ff changeset: 35532:bb5a03dfd7ff user:Anton Shestakov date:Fri Jan 05 19:22:05 2018 +0800 summary: spartan: make actual changeset entries have backgrounds on /graph https://www.mercurial-scm.org/repo/hg/rev/8b958d21b19d changeset: 35533:8b958d21b19d user:Anton Shestakov date:Fri Jan 05 19:30:30 2018 +0800 summary: hgweb: stop adding strings to innerHTML of #graphnodes and #nodebgs (BC) https://www.mercurial-scm.org/repo/hg/rev/b6ce3568771d changeset: 35534:b6ce3568771d user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Jan 05 19:23:30 2018 +0530 summary: annotate: add support to specify hidden revs if directaccess config is set https://www.mercurial-scm.org/repo/hg/rev/ffd7b7cd309b changeset: 35535:ffd7b7cd309b user:Pulkit Goyal <7895pul...@gmail.com> date:Fri Jan 05 19:30:37 2018 +0530 summary: archive: add support to specify hidden revs if directaccess config is set https://www.mercurial-scm.org/repo/hg/rev/f04d16bef2c7 changeset: 35536:f04d16bef2c7 bookmark:@ tag: tip user:Martin von Zweigbergk date:Fri Jan 05 11:53:33 2018 -0800 summary: tests: make #testcase available as env var in test -- 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 6 of 6] largefiles: modernize how capabilities are added to the wire protocol
> On Jan 6, 2018, at 3:09 PM, Augie Facklerwrote: > > >> On Jan 5, 2018, at 1:19 AM, Yuya Nishihara wrote: >> >> On Tue, 02 Jan 2018 23:55:08 -0500, Matt Harbison wrote: On Thu, 28 Dec 2017 08:04:01 -0500, Yuya Nishihara wrote: > On Wed, 27 Dec 2017 03:27:58 -0500, Matt Harbison wrote: > # HG changeset patch > # User Matt Harbison > # Date 1514349649 18000 > # Tue Dec 26 23:40:49 2017 -0500 > # Node ID f2e5631c99e6e2c7e9bac058185c24dd73a04e98 > # Parent 25ecea2ec3d7844c9146bf878fc5093ab33b6e11 > largefiles: modernize how capabilities are added to the wire protocol Looks good to me, so queued, thanks. >>> >>> Any thoughts on how the client can let the server know it has the >>> extension loaded, so I can close off the last hole in this series? >> >> CC +indygreg, augie >> >> I think there were some discussion about advertising client's capability, >> but I don't remember. > > OOC, why do we want the client to be advertising that it groks largefiles to > the server? I have a guess, but I’d like that explained before I start trying > to figure out what we need to support... I’m not in front of a computer right now, but see this. I think it is related to choking on the external flag that it doesn’t understand without the extension. https://www.mercurial-scm.org/repo/hg-all/file/fa865878a849/tests/test-lfs-serve.t#l189 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] win32: do not call GetVolumePathName() with the minimum buffer length
On Tue, Jan 02, 2018 at 08:34:35PM -0500, Matt Harbison wrote: > On Mon, 01 Jan 2018 22:40:44 -0500, Yuya Nishiharawrote: > > > # HG changeset patch > > # User Yuya Nishihara > > # Date 1514862848 -32400 > > # Tue Jan 02 12:14:08 2018 +0900 > > # Node ID c365a5bab6c102b4af74155ec54eae5d01248f50 > > # Parent 99cf3126c685bebbac8e7048f9267494d67ead50 > > win32: do not call GetVolumePathName() with the minimum buffer length > > LGTM, thanks. Queued per this review. Thanks! > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] log: drop unused expr from return value of getlogrevs()
On Thu, Jan 04, 2018 at 05:36:47PM +0900, Yuya Nishihara wrote: > # HG changeset patch > # User Yuya Nishihara> # Date 1508680151 -32400 > # Sun Oct 22 22:49:11 2017 +0900 > # Node ID d944bd7c3801f1fb4fa36f428abe79ab714297a8 > # Parent a7ad7ce089a3d9473c98d094da670834ba40bdb6 > log: drop unused expr from return value of getlogrevs() queued, thanks ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: Pulls Result in 414: Request URI too large
On Fri, Dec 29, 2017 at 12:40:46PM -0700, Chuck Lowery wrote: > I am running into a problem where the Request URI is too large I am unable > to pull. > > Client version is 4.4.2 > Server version is 3.7.3 > > There are only one or two changesets ahead of me. Pulled earlier (within > the hour). > > We have about ten open named branches. > > We use named branches for forking during the creation of new stand-alone > features and so they created and merged in regularly. The merged in and > then closed. That is why we only have 10 currently open. > > Is there a way to mitigate this problem? Pulling one change at a time > specifically doesn't seem ideal. There's always the `[experimental] httppostargs = yes` configuration option. That will help a *lot*, with the caveat that if you're doing access control by treating all POST requests as pushes it'll (probably) break your setup a little. Maybe explore that next? > > > Charles H. Lowery > ___ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 4] debug: add a 'debugdownload' command
On Wed, Jan 03, 2018 at 10:27:13AM +, Gábor STEFANIK wrote: > > -Original Message- > > From: Mercurial-devel [mailto:mercurial-devel-boun...@mercurial-scm.org] > > On Behalf Of Boris Feld > > Sent: Tuesday, January 2, 2018 11:40 AM > > To: mercurial-devel@mercurial-scm.org > > Subject: [PATCH 1 of 4] debug: add a 'debugdownload' command > > > > # HG changeset patch > > # User Boris Feld# Date 1513326616 -3600 > > # Fri Dec 15 09:30:16 2017 +0100 > > # Node ID 2bd6c705949fae0b4477759479e9a0a905788ca4 > > # Parent 2c47986505ff1f9c9c77117eca584347dbd1d89b > > # EXP-Topic largefile-url > > # Available At https://bitbucket.org/octobus/mercurial-devel/ > > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r > > 2bd6c705949f > > debug: add a 'debugdownload' command I like where this is headed, but please send a v2 that addresses Gabor's comments, especially around magic numbers. > > > > This command resolve and fetch and URL through the Mercurial logic. > > Mercurial logic add various headers (including authentication) while > > resolving > > an URL so the commands helps with building the same request Mercurial > > would be doing. > > > > A new test file is created because we'll add more logic regarding Mercurial > > download logic and it will grow to a reasonable size. > > > > diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py > > --- a/mercurial/debugcommands.py > > +++ b/mercurial/debugcommands.py > > @@ -69,6 +69,7 @@ from . import ( > > templater, > > treediscovery, > > upgrade, > > +url as urlmod, > > util, > > vfs as vfsmod, > > ) > > @@ -786,6 +787,25 @@ def debugdiscovery(ui, repo, remoteurl=" > > localrevs = opts['rev'] > > doit(localrevs, remoterevs) > > > > +@command('debugdownload', > > +[ > > +('o', 'output', '', _('URL')), > > +], > > +norepo=True) > > +def debugdownload(ui, url, output=None, **opts): > > +"""Download a ressource using Mercurial logic and config > > typo: resource > > > +""" > > +fh = urlmod.open(ui, url, output) > > + > > +dest = ui > > +if output: > > +dest = open(output, "wb", 4<<10) > > Repeatedly appearing magic number, please name it instead. > > > + > > +data = fh.read(4<<10) > > +while data: > > +dest.write(data) > > +data = fh.read(4<<10) > > + > > @command('debugextensions', cmdutil.formatteropts, [], norepo=True) > > def debugextensions(ui, **opts): > > '''show information about active extensions''' > > diff --git a/tests/test-completion.t b/tests/test-completion.t > > --- a/tests/test-completion.t > > +++ b/tests/test-completion.t > > @@ -85,6 +85,7 @@ Show debug commands if there are no othe > >debugdeltachain > >debugdirstate > >debugdiscovery > > + debugdownload > >debugextensions > >debugfileset > >debugformat > > @@ -263,6 +264,7 @@ Show all commands + options > >debugdeltachain: changelog, manifest, dir, template > >debugdirstate: nodates, datesort > >debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure > > + debugdownload: output > >debugextensions: template > >debugfileset: rev > >debugformat: template > > diff --git a/tests/test-help.t b/tests/test-help.t > > --- a/tests/test-help.t > > +++ b/tests/test-help.t > > @@ -919,6 +919,8 @@ Test list of internal help commands > > show the contents of the current dirstate > > debugdiscovery > > runs the changeset discovery protocol in isolation > > + debugdownload > > + Download a ressource using Mercurial logic and config > > typo: resource > > > debugextensions > > show information about active extensions > > debugfileset parse and apply a fileset specification diff --git > > a/tests/test- > > url-download.t b/tests/test-url-download.t new file mode 100644 > > --- /dev/null > > +++ b/tests/test-url-download.t > > @@ -0,0 +1,36 @@ > > +#require serve > > + > > + $ hg init server > > + $ hg serve -R server -p $HGPORT -d --pid-file=hg1.pid -E ../error.log > > + $ cat hg1.pid >> $DAEMON_PIDS > > + > > +Check basic fetching > > + > > + $ hg debugdownload "http://localhost:$HGPORT/?cmd=lookup=tip; > > + 1 > > + $ hg debugdownload -o null.txt > > "http://localhost:$HGPORT/?cmd=lookup=null; > > + $ cat null.txt > > + 1 > > + > > +Check the request is seens as coming from Mercurial (rev details, give > > typo... what exactly was intended here? "is seen as coming from Mercurial"? > "seems as if coming from Mercurial"? > > > +different content if the request has a Mercurial user agent) > > + > > + $ get-with-headers.py --headeronly "localhost:$HGPORT" "rev/tip" > > + content-type > > + 200 Script output follows > > + content-type: text/html; charset=ascii $ hg debugdownload > > +
Re: [PATCH] revset: parse x^:: as (x^):: (issue5764)
> On Dec 31, 2017, at 7:23 AM, Yuya Nishiharawrote: > > # HG changeset patch > # User Yuya Nishihara > # Date 1514624123 -32400 > # Sat Dec 30 17:55:23 2017 +0900 > # Node ID 4d5be53b4adbc913cfbded05c94307ec3ced1f06 > # Parent e01549a7bf0a6a7adbbb317a5d4bfde36c205b4d > revset: parse x^:: as (x^):: (issue5764) Queued with enormous amounts of delight! This is _by far_ the single most common reason for me to have to use parens (and, by association, to have to quote a revset query in my shell). ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] hgweb: make different kinds of commits look differently on /graph (RFC)
> On Jan 5, 2018, at 1:47 AM, Yuya Nishiharawrote: > > On Tue, 19 Dec 2017 21:52:15 +0800, Anton Shestakov wrote: >> # HG changeset patch >> # User Anton Shestakov >> # Date 1513687285 -28800 >> # Tue Dec 19 20:41:25 2017 +0800 >> # Node ID c7259f4340b50c8b1863ac9a1379ab8412b27b87 >> # Parent e28dedf4ff4368820bbb085c668c3e6ea2088842 >> hgweb: make different kinds of commits look differently on /graph (RFC) >> >> This is RFC for two reasons: >> >> I'm more or less fine with how things look visually (screenshots are in a >> follow-up email), but there's still room for improvement. Feel free to >> criticise or point me to good-looking graphs of this kind for inspiration. > > I have no preference, and this patch is floating more than 2 weeks, so let's > make it happen to get a feedback. Can you send V2? +1: let’s go ahead and land this and we can back it out before the final release if we decide we don’t care for it. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 6] largefiles: modernize how capabilities are added to the wire protocol
> On Jan 5, 2018, at 1:19 AM, Yuya Nishiharawrote: > > On Tue, 02 Jan 2018 23:55:08 -0500, Matt Harbison wrote: >> On Thu, 28 Dec 2017 08:04:01 -0500, Yuya Nishihara wrote: >>> On Wed, 27 Dec 2017 03:27:58 -0500, Matt Harbison wrote: # HG changeset patch # User Matt Harbison # Date 1514349649 18000 # Tue Dec 26 23:40:49 2017 -0500 # Node ID f2e5631c99e6e2c7e9bac058185c24dd73a04e98 # Parent 25ecea2ec3d7844c9146bf878fc5093ab33b6e11 largefiles: modernize how capabilities are added to the wire protocol >>> >>> Looks good to me, so queued, thanks. >> >> Any thoughts on how the client can let the server know it has the >> extension loaded, so I can close off the last hole in this series? > > CC +indygreg, augie > > I think there were some discussion about advertising client's capability, > but I don't remember. OOC, why do we want the client to be advertising that it groks largefiles to the server? I have a guess, but I’d like that explained before I start trying to figure out what we need to support... ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 2 V2] lfs: add a local store method for opening a blob
On Sat, 06 Jan 2018 02:39:08 -0500, Yuya Nishiharawrote: On Fri, 05 Jan 2018 21:15:54 -0500, Matt Harbison wrote: Which parts are confusing? (I've been a little confused by some things too, but I'm wondering how much overlap there is, what can be clarified, and how much is me juggling too many projects at once.) When to verify=True or not, for example. Yeah, that took me a bit to puzzle through as well. There are only a few uses, and I tried describing them in 417e8e040102. Basically, if we are getting data from core (e.g. commit) or giving it back (e.g. cat), there's no need to verify because core does that. Otherwise (e.g. getting stuff from remote stores or writing to remote stores), we do verify. I've been sitting on a series with an explicit local.download() method to help clarify writes from an external source vs commits. But I haven't figured out a way to give upload the same treatment (read -> write to file vs open file and create a urlreq.request() seems too different to pack into one method). I'll clean that up and submit, because it has other benefits. FWIW, I'm reviewing lfs patches without understanding how lfs was designed, so please disregard my pointless comments. All I know about it is from the wiki page[1], and past experience from largefiles. It's good to know what isn't clear to others, so that can be fixed, and make it easier for others to help maintain this in the future. [1] https://www.mercurial-scm.org/wiki/LfsPlan ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5767] New: python3 hg status causes less to emit a "Number is required after -b" waring
https://bz.mercurial-scm.org/show_bug.cgi?id=5767 Bug ID: 5767 Summary: python3 hg status causes less to emit a "Number is required after -b" waring Product: Mercurial Version: unspecified Hardware: PC OS: Linux Status: UNCONFIRMED Severity: bug Priority: normal Component: pager Assignee: bugzi...@mercurial-scm.org Reporter: shlo...@shlomifish.org CC: mercurial-devel@mercurial-scm.org shlomif@telaviv1:~/Download/unpack/file/vcs/hg$ python3.6 hg status Number is required after -b There is no -' option ("less --help" for help) - (press RETURN) it is fine with python2. This tentative change fixes it for both versions: diff -r 31fe397f2bda mercurial/util.py --- a/mercurial/util.py Wed Dec 27 00:24:53 2017 +0530 +++ b/mercurial/util.py Sat Jan 06 16:31:02 2018 +0200 @@ -1153,7 +1153,7 @@ return '0' if val is True: return '1' -return str(val) +return val.decode('utf-8') env = dict(encoding.environ) if environ: env.update((k, py2shell(v)) for k, v in environ.iteritems()) -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1768: cext: obtain reference to index entry type
indygreg updated this revision to Diff 4737. indygreg edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1768?vs=4629=4737 REVISION DETAIL https://phab.mercurial-scm.org/D1768 AFFECTED FILES mercurial/cext/parsers.c mercurial/cext/revlog.c mercurial/policy.py CHANGE DETAILS diff --git a/mercurial/policy.py b/mercurial/policy.py --- a/mercurial/policy.py +++ b/mercurial/policy.py @@ -75,7 +75,7 @@ (r'cext', r'diffhelpers'): 1, (r'cext', r'mpatch'): 1, (r'cext', r'osutil'): 3, -(r'cext', r'parsers'): 4, +(r'cext', r'parsers'): 5, } # map import request to other package or module diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -28,6 +28,20 @@ #define PyInt_AsLong PyLong_AsLong #endif +PyObject *get_index_entry_type(void) { + PyObject *mod, *obj; + + mod = PyImport_ImportModule("mercurial.pure.parsers"); + if (!mod) { + return NULL; + } + + obj = PyObject_GetAttrString(mod, "IndexV1Entry"); + Py_DECREF(mod); + + return obj; +} + /* * A base-16 trie for fast node->rev mapping. * @@ -54,6 +68,7 @@ typedef struct { PyObject_HEAD /* Type-specific fields go here. */ + PyObject *entrytype; /* mercurial.pure.parsers.IndexV1Entry type */ PyObject *nullentry; /* Represents an empty/unknown index value */ PyObject *data;/* raw bytes of index */ Py_buffer buf; /* buffer of data */ @@ -1862,6 +1877,7 @@ Py_ssize_t size; /* Initialize before argument-checking to avoid index_dealloc() crash. */ + self->entrytype = NULL; self->nullentry = NULL; self->raw_length = 0; self->added = NULL; @@ -1874,6 +1890,11 @@ self->nt = NULL; self->offsets = NULL; + self->entrytype = get_index_entry_type(); + if (!self->entrytype) { + return -1; + } + self->nullentry = Py_BuildValue("iiis#", 0, 0, 0, -1, -1, -1, -1, nullid, 20); if (!self->nullentry) { @@ -1937,6 +1958,7 @@ } Py_XDECREF(self->data); Py_XDECREF(self->added); + Py_XDECREF(self->entrytype); Py_XDECREF(self->nullentry); PyObject_Del(self); } @@ -2079,9 +2101,18 @@ void revlog_module_init(PyObject *mod) { + PyObject *index_entry_type; + indexType.tp_new = PyType_GenericNew; if (PyType_Ready() < 0) return; Py_INCREF(); PyModule_AddObject(mod, "index", (PyObject *)); + + index_entry_type = get_index_entry_type(); + if (!index_entry_type) { + return; + } + + PyModule_AddObject(mod, "IndexV1Entry", index_entry_type); } diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c --- a/mercurial/cext/parsers.c +++ b/mercurial/cext/parsers.c @@ -710,7 +710,7 @@ void manifest_module_init(PyObject *mod); void revlog_module_init(PyObject *mod); -static const int version = 4; +static const int version = 5; static void module_init(PyObject *mod) { To: indygreg, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1772: tests: port revlog index code to modern API
indygreg updated this revision to Diff 4739. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1772?vs=4633=4739 REVISION DETAIL https://phab.mercurial-scm.org/D1772 AFFECTED FILES tests/test-parseindex2.py CHANGE DETAILS diff --git a/tests/test-parseindex2.py b/tests/test-parseindex2.py --- a/tests/test-parseindex2.py +++ b/tests/test-parseindex2.py @@ -13,10 +13,6 @@ nullid, nullrev, ) -# no-check-code -from mercurial.pure import ( -parsers as pureparsers, -) from mercurial import ( policy, ) @@ -45,27 +41,32 @@ cache = (0, data) while off <= l: e = struct.unpack(indexformatng, data[off:off + s]) -nodemap[e[7]] = n +e = parsers.IndexV1Entry(*e) +nodemap[e.node] = n append(e) n += 1 -if e[1] < 0: +if e.chunklength < 0: break -off += e[1] + s +off += e.chunklength + s else: while off <= l: e = struct.unpack(indexformatng, data[off:off + s]) -nodemap[e[7]] = n +e = parsers.IndexV1Entry(*e) +nodemap[e.node] = n append(e) n += 1 off += s -e = list(index[0]) -type = gettype(e[0]) -e[0] = offset_type(0, type) -index[0] = tuple(e) +e = index[0] +type = gettype(e.offsetflags) + +index[0] = parsers.IndexV1Entry(offset_type(0, type), +e.chunklength, e.rawlength, +e.baserev, e.linkrev, +e.p1rev, e.p2rev, e.node) # add the magic null revision at -1 -index.append((0, 0, 0, -1, -1, -1, -1, nullid)) +index.append(parsers.IndexV1Entry(0, 0, 0, -1, -1, -1, -1, nullid)) return index, cache @@ -169,21 +170,6 @@ testversionfail(4, makehex(major, minor + 1, micro)) testversionfail(5, "'foo'") -def index_equal(a, b): -"""Determine if 2 index objects are equal.""" -# Normalize all entries to IndexV1Entry instances. -def normvalue(x): -if isinstance(x, pureparsers.IndexV1Entry): -return x - -assert isinstance(x, tuple) -return pureparsers.IndexV1Entry(*x) - -idxa = list(map(normvalue, a[0])) -idxb = list(map(normvalue, b[0])) - -return (idxa, a[1]) == (idxb, b[1]) - def runtest() : # Only test the version-detection logic if it is present. try: @@ -210,15 +196,15 @@ py_res_2 = py_parseindex(data_non_inlined, False) c_res_2 = parse_index2(data_non_inlined, False) -if not index_equal(py_res_1, c_res_1): +if py_res_1 != c_res_1: print("Parse index result (with inlined data) differs!") -if not index_equal(py_res_2, c_res_2): +if py_res_2 != c_res_2: print("Parse index result (no inlined data) differs!") ix = parsers.parse_index2(data_inlined, True)[0] for i, r in enumerate(ix): -if r[7] == nullid: +if r.node == nullid: i = -1 try: if ix[r[7]] != i: To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1778: debugcommands: use named attributes on revlog index entries
indygreg updated this revision to Diff 4741. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1778?vs=4639=4741 REVISION DETAIL https://phab.mercurial-scm.org/D1778 AFFECTED FILES mercurial/debugcommands.py CHANGE DETAILS diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -610,31 +610,31 @@ def revinfo(rev): e = index[rev] -compsize = e[1] -uncompsize = e[2] +compsize = e.chunklength +uncompsize = e.rawlength chainsize = 0 if generaldelta: -if e[3] == e[5]: +if e.baserev == e.p1rev: deltatype = 'p1' -elif e[3] == e[6]: +elif e.baserev == e.p2rev: deltatype = 'p2' -elif e[3] == rev - 1: +elif e.baserev == rev - 1: deltatype = 'prev' -elif e[3] == rev: +elif e.baserev == rev: deltatype = 'base' else: deltatype = 'other' else: -if e[3] == rev: +if e.baserev == rev: deltatype = 'base' else: deltatype = 'prev' chain = r._deltachain(rev)[0] for iterrev in chain: e = index[iterrev] -chainsize += e[1] +chainsize += e.chunklength return compsize, uncompsize, deltatype, chain, chainsize To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1774: repoview: use named attributes on revlog index entries
indygreg updated this revision to Diff 4740. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1774?vs=4635=4740 REVISION DETAIL https://phab.mercurial-scm.org/D1774 AFFECTED FILES mercurial/repoview.py CHANGE DETAILS diff --git a/mercurial/repoview.py b/mercurial/repoview.py --- a/mercurial/repoview.py +++ b/mercurial/repoview.py @@ -217,7 +217,7 @@ # bypass call to changelog.method unfiindex = unfichangelog.index unfilen = len(unfiindex) - 1 -unfinode = unfiindex[unfilen - 1][7] +unfinode = unfiindex[unfilen - 1].node revs = filterrevs(unfi, self.filtername, self._visibilityexceptions) cl = self._clcache To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1767: cext: make nullentry a member of index types
indygreg updated this revision to Diff 4736. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1767?vs=4628=4736 REVISION DETAIL https://phab.mercurial-scm.org/D1767 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 @@ -54,6 +54,7 @@ typedef struct { PyObject_HEAD /* Type-specific fields go here. */ + PyObject *nullentry; /* Represents an empty/unknown index value */ PyObject *data;/* raw bytes of index */ Py_buffer buf; /* buffer of data */ PyObject **cache; /* cached tuples */ @@ -81,7 +82,6 @@ return self->length + PyList_GET_SIZE(self->added); } -static PyObject *nullentry; static const char nullid[20]; static Py_ssize_t inline_scan(indexObject *self, const char **offsets); @@ -167,8 +167,8 @@ } if (pos == length - 1) { - Py_INCREF(nullentry); - return nullentry; + Py_INCREF(self->nullentry); + return self->nullentry; } if (pos >= self->length - 1) { @@ -1862,6 +1862,7 @@ Py_ssize_t size; /* Initialize before argument-checking to avoid index_dealloc() crash. */ + self->nullentry = NULL; self->raw_length = 0; self->added = NULL; self->cache = NULL; @@ -1873,6 +1874,12 @@ self->nt = NULL; self->offsets = NULL; + self->nullentry = Py_BuildValue("iiis#", 0, 0, 0, + -1, -1, -1, -1, nullid, 20); + if (!self->nullentry) { + return -1; + } + if (!PyArg_ParseTuple(args, "OO", _obj, _obj)) return -1; if (!PyObject_CheckBuffer(data_obj)) { @@ -1930,6 +1937,7 @@ } Py_XDECREF(self->data); Py_XDECREF(self->added); + Py_XDECREF(self->nullentry); PyObject_Del(self); } @@ -2076,9 +2084,4 @@ return; Py_INCREF(); PyModule_AddObject(mod, "index", (PyObject *)); - - nullentry = Py_BuildValue("iiis#", 0, 0, 0, - -1, -1, -1, -1, nullid, 20); - if (nullentry) - PyObject_GC_UnTrack(nullentry); } To: indygreg, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1765: parsers: use an attr-derived class for revlog index entries
indygreg updated this revision to Diff 4735. indygreg edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1765?vs=4626=4735 REVISION DETAIL https://phab.mercurial-scm.org/D1765 AFFECTED FILES mercurial/pure/parsers.py tests/test-parseindex2.py CHANGE DETAILS diff --git a/tests/test-parseindex2.py b/tests/test-parseindex2.py --- a/tests/test-parseindex2.py +++ b/tests/test-parseindex2.py @@ -13,6 +13,10 @@ nullid, nullrev, ) +# no-check-code +from mercurial.pure import ( +parsers as pureparsers, +) from mercurial import ( policy, ) @@ -165,6 +169,21 @@ testversionfail(4, makehex(major, minor + 1, micro)) testversionfail(5, "'foo'") +def index_equal(a, b): +"""Determine if 2 index objects are equal.""" +# Normalize all entries to IndexV1Entry instances. +def normvalue(x): +if isinstance(x, pureparsers.IndexV1Entry): +return x + +assert isinstance(x, tuple) +return pureparsers.IndexV1Entry(*x) + +idxa = list(map(normvalue, a[0])) +idxb = list(map(normvalue, b[0])) + +return (idxa, a[1]) == (idxb, b[1]) + def runtest() : # Only test the version-detection logic if it is present. try: @@ -191,10 +210,10 @@ py_res_2 = py_parseindex(data_non_inlined, False) c_res_2 = parse_index2(data_non_inlined, False) -if py_res_1 != c_res_1: +if not index_equal(py_res_1, c_res_1): print("Parse index result (with inlined data) differs!") -if py_res_2 != c_res_2: +if not index_equal(py_res_2, c_res_2): print("Parse index result (no inlined data) differs!") ix = parsers.parse_index2(data_inlined, True)[0] diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -11,6 +11,7 @@ import zlib from ..node import nullid +from ..thirdparty import attr from .. import pycompat stringio = pycompat.stringio @@ -37,13 +38,49 @@ def offset_type(offset, type): return int(int(offset) << 16 | type) +@attr.s +class IndexV1Entry(object): +"""Represents a revlog v1 index entry.""" +offsetflags = attr.ib() +chunklength = attr.ib() +rawlength = attr.ib() +baserev = attr.ib() +linkrev = attr.ib() +p1rev = attr.ib() +p2rev = attr.ib() +node = attr.ib() + +def __getitem__(self, x): +if x == 0: +return self.offsetflags +elif x == 1: +return self.chunklength +elif x == 2: +return self.rawlength +elif x == 3: +return self.baserev +elif x == 4: +return self.linkrev +elif x == 5: +return self.p1rev +elif x == 6: +return self.p2rev +elif x == 7: +return self.node +else: +raise IndexError('index out of range') + class BaseIndexObject(object): def __len__(self): return self._lgt + len(self._extra) + 1 -def insert(self, i, tup): +def insert(self, i, entry): assert i == -1 -self._extra.append(tup) + +if isinstance(entry, tuple): +entry = IndexV1Entry(*entry) + +self._extra.append(entry) def _fix_index(self, i): if not isinstance(i, int): @@ -57,17 +94,17 @@ def __getitem__(self, i): i = self._fix_index(i) if i == len(self) - 1: -return (0, 0, 0, -1, -1, -1, -1, nullid) +return IndexV1Entry(0, 0, 0, -1, -1, -1, -1, nullid) if i >= self._lgt: return self._extra[i - self._lgt] index = self._calculate_index(i) r = struct.unpack(indexformatng, self._data[index:index + indexsize]) if i == 0: e = list(r) type = gettype(e[0]) e[0] = offset_type(0, type) -return tuple(e) -return r +return IndexV1Entry(*e) +return IndexV1Entry(*r) class IndexObject(BaseIndexObject): def __init__(self, data): To: indygreg, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1769: cext: use dedicated type for index entries
indygreg updated this revision to Diff 4738. indygreg edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1769?vs=4630=4738 REVISION DETAIL https://phab.mercurial-scm.org/D1769 AFFECTED FILES mercurial/cext/parsers.c mercurial/cext/revlog.c mercurial/policy.py CHANGE DETAILS diff --git a/mercurial/policy.py b/mercurial/policy.py --- a/mercurial/policy.py +++ b/mercurial/policy.py @@ -75,7 +75,7 @@ (r'cext', r'diffhelpers'): 1, (r'cext', r'mpatch'): 1, (r'cext', r'osutil'): 3, -(r'cext', r'parsers'): 5, +(r'cext', r'parsers'): 6, } # map import request to other package or module diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -133,10 +133,22 @@ int *ps, int maxrev) { if (rev >= self->length - 1) { - PyObject *tuple = PyList_GET_ITEM(self->added, + PyObject *value; + PyObject *entry = PyList_GET_ITEM(self->added, rev - self->length + 1); - ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5)); - ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6)); + value = PyObject_GetAttrString(entry, "p1rev"); + if (!value) { + return -1; + } + ps[0] = (int)PyInt_AS_LONG(value); + Py_DECREF(value); + + value = PyObject_GetAttrString(entry, "p2rev"); + if (!value) { + return -1; + } + ps[1] = (int)PyInt_AS_LONG(value); + Py_DECREF(value); } else { const char *data = index_deref(self, rev); ps[0] = getbe32(data + 24); @@ -224,9 +236,9 @@ parent_2 = getbe32(data + 28); c_node_id = data + 32; - entry = Py_BuildValue(index_entry_format, offset_flags, comp_len, - uncomp_len, base_rev, link_rev, - parent_1, parent_2, c_node_id, 20); + entry = PyObject_CallFunction(self->entrytype, index_entry_format, + offset_flags, comp_len, uncomp_len, base_rev, + link_rev, parent_1, parent_2, c_node_id, 20); if (entry) { PyObject_GC_UnTrack(entry); @@ -253,10 +265,16 @@ return NULL; if (pos >= self->length - 1) { - PyObject *tuple, *str; - tuple = PyList_GET_ITEM(self->added, pos - self->length + 1); - str = PyTuple_GetItem(tuple, 7); - return str ? PyBytes_AS_STRING(str) : NULL; + PyObject *entry, *str; + char *result; + entry = PyList_GET_ITEM(self->added, pos - self->length + 1); + str = PyObject_GetAttrString(entry, "node"); + if (!str) { + return NULL; + } + result = PyBytes_AS_STRING(str); + Py_DECREF(str); + return result; } data = index_deref(self, pos); @@ -277,21 +295,46 @@ static PyObject *index_insert(indexObject *self, PyObject *args) { - PyObject *obj; + PyObject *obj, *nodeobj; + PyObject *result = NULL; + PyObject *tmpobj = NULL; char *node; int index; Py_ssize_t len, nodelen; if (!PyArg_ParseTuple(args, "iO", , )) return NULL; - if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) { - PyErr_SetString(PyExc_TypeError, "8-tuple required"); - return NULL; + /* Legacy callers may pass tuples. Convert to an index entry until +* API compatibility is dropped. */ + if (PyTuple_Check(obj)) { + tmpobj = PyObject_Call(self->entrytype, obj, NULL); + if (!tmpobj) { + return NULL; + } + + /* We own a reference to tmpobj. So any return after here + needs to decrease its refcount. */ + obj = tmpobj; } - if (node_check(PyTuple_GET_ITEM(obj, 7), , ) == -1) - return NULL; + if (!PyObject_TypeCheck(obj, (PyTypeObject *)self->entrytype)) { + PyErr_SetString(PyExc_TypeError, "IndexV1Entry type required"); + goto cleanup; + } + + nodeobj = PyObject_GetAttrString(obj, "node"); + if (!nodeobj) { + PyErr_SetString(PyExc_ValueError, "could not retrieve node"); + goto cleanup; + } + if (node_check(nodeobj, , ) == -1) { + Py_DECREF(nodeobj); + goto cleanup; + } + + Py_DECREF(nodeobj); + nodeobj = NULL; len = index_length(self); @@ -301,23 +344,30 @@ if